summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am19
-rw-r--r--src/demuxers/Makefile.am48
-rw-r--r--src/demuxers/demux.h125
-rw-r--r--src/demuxers/demux_avi.c982
-rw-r--r--src/demuxers/demux_elem.c284
-rw-r--r--src/demuxers/demux_mpeg.c626
-rw-r--r--src/demuxers/demux_mpeg_block.c519
-rw-r--r--src/demuxers/demux_mpgaudio.c440
-rw-r--r--src/input/Makefile.am72
-rw-r--r--src/input/dvd_udf.c661
-rw-r--r--src/input/dvd_udf.h39
-rw-r--r--src/input/input_dvd.c438
-rw-r--r--src/input/input_file.c191
-rw-r--r--src/input/input_net.c224
-rw-r--r--src/input/input_plugin.h178
-rw-r--r--src/input/input_rtp.c384
-rw-r--r--src/input/input_stdin_fifo.c219
-rw-r--r--src/input/input_vcd.c586
-rw-r--r--src/libac3/Makefile.am47
-rw-r--r--src/libac3/ac3.h54
-rw-r--r--src/libac3/ac3_internal.h359
-rw-r--r--src/libac3/bit_allocate.c509
-rw-r--r--src/libac3/bit_allocate.h24
-rw-r--r--src/libac3/bitstream.c79
-rw-r--r--src/libac3/bitstream.h46
-rw-r--r--src/libac3/bswap.h60
-rw-r--r--src/libac3/cmplx.h9
-rw-r--r--src/libac3/coeff.c437
-rw-r--r--src/libac3/coeff.h24
-rw-r--r--src/libac3/crc.c100
-rw-r--r--src/libac3/crc.h27
-rw-r--r--src/libac3/decode.c314
-rw-r--r--src/libac3/decode.h22
-rw-r--r--src/libac3/dither.c117
-rw-r--r--src/libac3/dither.h37
-rw-r--r--src/libac3/downmix.c158
-rw-r--r--src/libac3/downmix.h43
-rw-r--r--src/libac3/exponent.c138
-rw-r--r--src/libac3/exponent.h28
-rw-r--r--src/libac3/imdct.c661
-rw-r--r--src/libac3/imdct.h36
-rw-r--r--src/libac3/parse.c484
-rw-r--r--src/libac3/parse.h26
-rw-r--r--src/libac3/rematrix.c95
-rw-r--r--src/libac3/rematrix.h25
-rw-r--r--src/libac3/sanity_check.c128
-rw-r--r--src/libac3/sanity_check.h27
-rw-r--r--src/libac3/srfft.c309
-rw-r--r--src/libac3/srfft.h39
-rw-r--r--src/libac3/srfftp.h305
-rw-r--r--src/libmpeg2/Makefile.am23
-rw-r--r--src/libmpeg2/decode.c323
-rw-r--r--src/libmpeg2/header.c235
-rw-r--r--src/libmpeg2/idct.c290
-rw-r--r--src/libmpeg2/idct_mlib.c47
-rw-r--r--src/libmpeg2/idct_mlib.h25
-rw-r--r--src/libmpeg2/idct_mmx.c705
-rw-r--r--src/libmpeg2/motion_comp.c125
-rw-r--r--src/libmpeg2/motion_comp_mlib.c180
-rw-r--r--src/libmpeg2/motion_comp_mmx.c1017
-rw-r--r--src/libmpeg2/mpeg2.h67
-rw-r--r--src/libmpeg2/mpeg2_internal.h194
-rw-r--r--src/libmpeg2/slice.c1799
-rw-r--r--src/libmpeg2/stats.c315
-rw-r--r--src/libmpeg2/vlc.h425
-rw-r--r--src/libmpg123/Makefile.am22
-rw-r--r--src/libmpg123/README39
-rw-r--r--src/libmpg123/TODO2
-rw-r--r--src/libmpg123/common.c181
-rw-r--r--src/libmpg123/dct64_i386.c315
-rw-r--r--src/libmpg123/decode_i386.c151
-rw-r--r--src/libmpg123/huffman.h332
-rw-r--r--src/libmpg123/interface.c157
-rw-r--r--src/libmpg123/l2tables.h160
-rw-r--r--src/libmpg123/layer1.c159
-rw-r--r--src/libmpg123/layer2.c300
-rw-r--r--src/libmpg123/layer3.c1608
-rw-r--r--src/libmpg123/main.c29
-rw-r--r--src/libmpg123/mpg123.h194
-rw-r--r--src/libmpg123/mpglib.h68
-rw-r--r--src/libmpg123/tabinit.c80
-rw-r--r--src/libspudec/Makefile.am20
-rw-r--r--src/libspudec/spudec.c688
-rw-r--r--src/libspudec/spudec.h67
-rw-r--r--src/libw32dll/Makefile.am38
-rw-r--r--src/libw32dll/afl.c765
-rw-r--r--src/libw32dll/driver.c182
-rw-r--r--src/libw32dll/elfdll.c305
-rw-r--r--src/libw32dll/ext.c565
-rw-r--r--src/libw32dll/loader.h286
-rw-r--r--src/libw32dll/module.c618
-rw-r--r--src/libw32dll/pe_image.c936
-rw-r--r--src/libw32dll/pe_resource.c391
-rw-r--r--src/libw32dll/registry.c421
-rw-r--r--src/libw32dll/registry.h24
-rw-r--r--src/libw32dll/resource.c479
-rw-r--r--src/libw32dll/stubs.s36
-rw-r--r--src/libw32dll/vfl.c330
-rw-r--r--src/libw32dll/w32codec.c426
-rw-r--r--src/libw32dll/w32codec.h41
-rw-r--r--src/libw32dll/win32.c1706
-rw-r--r--src/libw32dll/win32.h1
-rw-r--r--src/libw32dll/wine/Makefile.am16
-rw-r--r--src/libw32dll/wine/avifmt.h244
-rw-r--r--src/libw32dll/wine/basetsd.h145
-rw-r--r--src/libw32dll/wine/config.h442
-rw-r--r--src/libw32dll/wine/debugtools.h92
-rw-r--r--src/libw32dll/wine/driver.h112
-rw-r--r--src/libw32dll/wine/elfdll.h14
-rw-r--r--src/libw32dll/wine/heap.h56
-rw-r--r--src/libw32dll/wine/ldt.h98
-rw-r--r--src/libw32dll/wine/mmreg.h104
-rw-r--r--src/libw32dll/wine/module.h198
-rw-r--r--src/libw32dll/wine/msacm.h942
-rw-r--r--src/libw32dll/wine/msacmdrv.h203
-rw-r--r--src/libw32dll/wine/ntdef.h101
-rw-r--r--src/libw32dll/wine/pe_image.h81
-rw-r--r--src/libw32dll/wine/poppack.h15
-rw-r--r--src/libw32dll/wine/pshpack1.h13
-rw-r--r--src/libw32dll/wine/pshpack2.h12
-rw-r--r--src/libw32dll/wine/pshpack4.h15
-rw-r--r--src/libw32dll/wine/pshpack8.h12
-rw-r--r--src/libw32dll/wine/vfw.h654
-rw-r--r--src/libw32dll/wine/winbase.h1792
-rw-r--r--src/libw32dll/wine/windef.h656
-rw-r--r--src/libw32dll/wine/windows.h38
-rw-r--r--src/libw32dll/wine/winerror.h1658
-rw-r--r--src/libw32dll/wine/winestring.h13
-rw-r--r--src/libw32dll/wine/winnt.h2665
-rw-r--r--src/libw32dll/wine/winreg.h57
-rw-r--r--src/libw32dll/wine/winuser.h2929
-rw-r--r--src/libw32dll/wineacm.h55
-rw-r--r--src/xine-engine/Makefile.am82
-rw-r--r--src/xine-engine/attributes.h27
-rw-r--r--src/xine-engine/audio_decoder.c194
-rw-r--r--src/xine-engine/audio_decoder.h66
-rw-r--r--src/xine-engine/buffer.c225
-rw-r--r--src/xine-engine/buffer.h147
-rw-r--r--src/xine-engine/configfile.c293
-rw-r--r--src/xine-engine/configfile.h101
-rw-r--r--src/xine-engine/cpu_accel.c110
-rw-r--r--src/xine-engine/cpu_accel.h514
-rw-r--r--src/xine-engine/load_plugins.c200
-rw-r--r--src/xine-engine/metronom.c298
-rw-r--r--src/xine-engine/metronom.h179
-rw-r--r--src/xine-engine/monitor.c84
-rw-r--r--src/xine-engine/monitor.h89
-rw-r--r--src/xine-engine/utils.c125
-rw-r--r--src/xine-engine/utils.h39
-rw-r--r--src/xine-engine/video_decoder.c180
-rw-r--r--src/xine-engine/video_decoder.h73
-rw-r--r--src/xine-engine/xine.c607
-rw-r--r--src/xine-engine/xine_internal.h76
153 files changed, 45835 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 000000000..822ab3e18
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,19 @@
+
+SUBDIRS = input libmpeg2 libspudec demuxers \
+ libac3 libmpg123 libw32dll xine-engine
+
+debug:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ (cd $$subdir && $(MAKE) $@) \
+ done;
+
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
+
diff --git a/src/demuxers/Makefile.am b/src/demuxers/Makefile.am
new file mode 100644
index 000000000..46e5bc8b6
--- /dev/null
+++ b/src/demuxers/Makefile.am
@@ -0,0 +1,48 @@
+CFLAGS = @BUILD_LIB_STATIC@ @GLOBAL_CFLAGS@
+
+noinst_LTLIBRARIES = libdemux.la
+
+#libdemux_la_SOURCES = demux_avi.c demux_mpeg_block.c demux_mpeg.c \
+# demux_mpgaudio.c demux_elem.c
+libdemux_la_SOURCES = demux_avi.c demux_mpeg_block.c demux_mpeg.c
+#libdemux_la_DEPENDENCIES = libsdeps
+#libdemux_la_LIBADD = $(top_builddir)/libmpg123/libmpg123.la
+
+include_HEADERS = demux.h
+
+#libsdeps:
+# @cd $(top_builddir)/libmpg123 && $(MAKE) libmpg123.la
+
+##
+## Install header files (default=$includedir/xine)
+##
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)/xine
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p; \
+ done
+
+
+##
+## Remove them
+##
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/xine/$$p; \
+ done
+
+debug:
+ $(MAKE) CFLAGS="$(DEBUG_CFLAGS)"
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
+
diff --git a/src/demuxers/demux.h b/src/demuxers/demux.h
new file mode 100644
index 000000000..6fda091fe
--- /dev/null
+++ b/src/demuxers/demux.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2000 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: demux.h,v 1.1 2001/04/18 22:33:54 f1rmb Exp $
+ */
+
+#ifndef HAVE_DEMUX_H
+#define HAVE_DEMUX_H
+
+#include "buffer.h"
+#include "xine.h"
+#if defined(XINE_COMPILE)
+#include "input/input_plugin.h"
+#else
+#include "input_plugin.h"
+#endif
+
+#define DEMUX_OK 0
+#define DEMUX_FINISHED 1
+
+#define DEMUX_CANNOT_HANDLE 0
+#define DEMUX_CAN_HANDLE 1
+
+#define DEMUX_DEFAULT_STRATEGY 0
+#define DEMUX_REVERT_STRATEGY 1
+#define DEMUX_CONTENT_STRATEGY 2
+#define DEMUX_EXTENSION_STRATEGY 3
+
+#define STAGE_BY_CONTENT 1
+#define STAGE_BY_EXTENSION 2
+
+/*
+ * a demux plugin (no matter if it's staically built into xine
+ * or dynamically loaded at run-time) must implement these functions
+ */
+
+typedef struct demux_plugin_s demux_plugin_t;
+
+struct demux_plugin_s
+{
+ /*
+ * ask demuxer to open the given stream (input-plugin)
+ * using the content-detection method specified in <stage>
+ *
+ * return values:
+ * DEMUX_CAN_HANDLE on success
+ * DEMUX_CANNOT_HANDLE on failure
+ */
+
+ int (*open) (demux_plugin_t *this, input_plugin_t *ip,
+ int stage);
+
+ /*
+ * start demux thread
+ * pos : 0..65535
+ */
+
+ void (*start) (demux_plugin_t *this, fifo_buffer_t *video_fifo,
+ fifo_buffer_t *audio_fifo, fifo_buffer_t *spu_fifo,
+ off_t pos) ;
+
+ /*
+ * stop & kill demux thread, free resources associated with current
+ * input stream
+ */
+
+ void (*stop) (demux_plugin_t *this) ;
+
+ /*
+ * close demuxer, free all resources
+ */
+
+ void (*close) (demux_plugin_t *this) ;
+
+ /*
+ * returns DEMUX_OK or DEMUX_FINISHED
+ */
+
+ int (*get_status) (demux_plugin_t *this) ;
+
+ /*
+ * return human readable identifier for this plugin
+ */
+
+ char* (*get_identifier) (demux_plugin_t *this);
+
+} ;
+
+/*
+ * for dynamic demux plugins:
+ *
+ * make sure you provide this (and only this!) function call:
+ *
+ * demux_plugin_t *init_demux_plugin (config_values_t *cfg, uint32_t xd);
+ *
+ */
+
+demux_plugin_t *init_demux_mpeg (config_values_t *cfg, uint32_t xd);
+
+demux_plugin_t *init_demux_mpeg_block (config_values_t *cfg, uint32_t xd);
+
+demux_plugin_t *init_demux_avi (config_values_t *cfg, uint32_t xd);
+
+demux_plugin_t *init_demux_mpeg_audio (config_values_t *cfg, uint32_t xd);
+
+demux_plugin_t *init_demux_mpeg_elem(config_values_t *cfg, uint32_t xd);
+
+#endif
+
diff --git a/src/demuxers/demux_avi.c b/src/demuxers/demux_avi.c
new file mode 100644
index 000000000..badcadc7d
--- /dev/null
+++ b/src/demuxers/demux_avi.c
@@ -0,0 +1,982 @@
+/*
+ * Copyright (C) 2000 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: demux_avi.c,v 1.1 2001/04/18 22:33:55 f1rmb Exp $
+ *
+ * demultiplexer for avi streams
+ *
+ * part of the code is taken from
+ * avilib (C) 1999 Rainer Johanni <Rainer@Johanni.de>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "xine.h"
+#include "monitor.h"
+#include "demux.h"
+#include "utils.h"
+#include "libw32dll/wine/mmreg.h"
+#include "libw32dll/wine/avifmt.h"
+#include "libw32dll/wine/vfw.h"
+
+/* The following variable indicates the kind of error */
+
+static uint32_t xine_debug;
+
+typedef struct
+{
+ long pos;
+ long len;
+} video_index_entry_t;
+
+typedef struct
+{
+ long pos;
+ long len;
+ long tot;
+} audio_index_entry_t;
+
+typedef struct
+{
+ long width; /* Width of a video frame */
+ long height; /* Height of a video frame */
+ long dwScale, dwRate;
+ double fps; /* Frames per second */
+
+ char compressor[8]; /* Type of compressor, 4 bytes + padding for 0 byte */
+ long video_strn; /* Video stream number */
+ long video_frames; /* Number of video frames */
+ char video_tag[4]; /* Tag of video data */
+ long video_posf; /* Number of next frame to be read
+ (if index present) */
+ long video_posb; /* Video position: byte within frame */
+
+ long a_fmt; /* Audio format, see #defines below */
+ long a_chans; /* Audio channels, 0 for no audio */
+ long a_rate; /* Rate in Hz */
+ long a_bits; /* bits per audio sample */
+ long audio_strn; /* Audio stream number */
+ long audio_bytes; /* Total number of bytes of audio data */
+ long audio_chunks; /* Chunks of audio data in the file */
+ char audio_tag[4]; /* Tag of audio data */
+ long audio_posc; /* Audio position: chunk */
+ long audio_posb; /* Audio position: byte within chunk */
+
+ long pos; /* position in file */
+ long n_idx; /* number of index entries actually filled */
+ long max_idx; /* number of index entries actually allocated */
+ unsigned char (*idx)[16]; /* index entries (AVI idx1 tag) */
+ video_index_entry_t *video_index;
+ audio_index_entry_t *audio_index;
+ BITMAPINFOHEADER bih;
+ char wavex[64];
+ off_t movi_start;
+ uint32_t AVI_errno;
+} avi_t;
+
+typedef struct demux_avi_s {
+ demux_plugin_t demux_plugin;
+
+ fifo_buffer_t *audio_fifo;
+ fifo_buffer_t *video_fifo;
+
+ input_plugin_t *input;
+
+ avi_t *avi;
+
+ pthread_t thread;
+
+ int status;
+
+ uint32_t video_step;
+ uint32_t avg_bytes_per_sec;
+} demux_avi_t ;
+
+#define AVI_ERR_SIZELIM 1 /* The write of the data would exceed
+ the maximum size of the AVI file.
+ This is more a warning than an error
+ since the file may be closed safely */
+
+#define AVI_ERR_OPEN 2 /* Error opening the AVI file - wrong path
+ name or file nor readable/writable */
+
+#define AVI_ERR_READ 3 /* Error reading from AVI File */
+
+#define AVI_ERR_WRITE 4 /* Error writing to AVI File,
+ disk full ??? */
+
+#define AVI_ERR_WRITE_INDEX 5 /* Could not write index to AVI file
+ during close, file may still be
+ usable */
+
+#define AVI_ERR_CLOSE 6 /* Could not write header to AVI file
+ or not truncate the file during close,
+ file is most probably corrupted */
+
+#define AVI_ERR_NOT_PERM 7 /* Operation not permitted:
+ trying to read from a file open
+ for writing or vice versa */
+
+#define AVI_ERR_NO_MEM 8 /* malloc failed */
+
+#define AVI_ERR_NO_AVI 9 /* Not an AVI file */
+
+#define AVI_ERR_NO_HDRL 10 /* AVI file has no has no header list,
+ corrupted ??? */
+
+#define AVI_ERR_NO_MOVI 11 /* AVI file has no has no MOVI list,
+ corrupted ??? */
+
+#define AVI_ERR_NO_VIDS 12 /* AVI file contains no video data */
+
+#define AVI_ERR_NO_IDX 13 /* The file has been opened with
+ getIndex==0, but an operation has been
+ performed that needs an index */
+
+static unsigned long str2ulong(unsigned char *str)
+{
+ return ( str[0] | (str[1]<<8) | (str[2]<<16) | (str[3]<<24) );
+}
+
+static unsigned long str2ushort(unsigned char *str)
+{
+ return ( str[0] | (str[1]<<8) );
+}
+
+static void long2str(unsigned char *dst, int n)
+{
+ dst[0] = (n )&0xff;
+ dst[1] = (n>> 8)&0xff;
+ dst[2] = (n>>16)&0xff;
+ dst[3] = (n>>24)&0xff;
+}
+
+static void AVI_close(avi_t *AVI)
+{
+ if(AVI->idx) free(AVI->idx);
+ if(AVI->video_index) free(AVI->video_index);
+ if(AVI->audio_index) free(AVI->audio_index);
+ free(AVI);
+}
+
+#define ERR_EXIT(x) \
+{ \
+ AVI->AVI_errno = x; \
+ return 0; \
+}
+
+#define PAD_EVEN(x) ( ((x)+1) & ~1 )
+
+static int avi_sampsize(avi_t *AVI)
+{
+ int s;
+ s = ((AVI->a_bits+7)/8)*AVI->a_chans;
+ if(s==0) s=1; /* avoid possible zero divisions */
+ return s;
+}
+
+static int avi_add_index_entry(avi_t *AVI, unsigned char *tag,
+ long flags, long pos, long len)
+{
+ void *ptr;
+
+ if(AVI->n_idx>=AVI->max_idx)
+ {
+ ptr = realloc((void *)AVI->idx,(AVI->max_idx+4096)*16);
+ if(ptr == 0)
+ {
+ AVI->AVI_errno = AVI_ERR_NO_MEM;
+ return -1;
+ }
+ AVI->max_idx += 4096;
+ AVI->idx = (unsigned char((*)[16]) ) ptr;
+ }
+
+ /* Add index entry */
+
+ memcpy(AVI->idx[AVI->n_idx],tag,4);
+ long2str(AVI->idx[AVI->n_idx]+ 4,flags);
+ long2str(AVI->idx[AVI->n_idx]+ 8,pos);
+ long2str(AVI->idx[AVI->n_idx]+12,len);
+
+ /* Update counter */
+
+ AVI->n_idx++;
+
+ return 0;
+}
+
+static avi_t *AVI_init(demux_avi_t *this)
+{
+ avi_t *AVI;
+ long i, n, idx_type;
+ unsigned char *hdrl_data;
+ long hdrl_len=0;
+ long nvi, nai, ioff;
+ long tot;
+ int lasttag = 0;
+ int vids_strh_seen = 0;
+ int vids_strf_seen = 0;
+ int auds_strh_seen = 0;
+ int auds_strf_seen = 0;
+ int num_stream = 0;
+ char data[256];
+
+ /* Create avi_t structure */
+
+ AVI = (avi_t *) xmalloc(sizeof(avi_t));
+ if(AVI==NULL)
+ {
+ AVI->AVI_errno = AVI_ERR_NO_MEM;
+ return 0;
+ }
+ memset((void *)AVI,0,sizeof(avi_t));
+
+ /* Read first 12 bytes and check that this is an AVI file */
+
+ if( this->input->read(data,12) != 12 ) ERR_EXIT(AVI_ERR_READ) ;
+
+ if( strncasecmp(data ,"RIFF",4) !=0 ||
+ strncasecmp(data+8,"AVI ",4) !=0 ) ERR_EXIT(AVI_ERR_NO_AVI) ;
+ /* Go through the AVI file and extract the header list,
+ the start position of the 'movi' list and an optionally
+ present idx1 tag */
+
+ hdrl_data = 0;
+
+ while(1) {
+ if (this->input->read(data,8) != 8 ) break; /* We assume it's EOF */
+
+ n = str2ulong(data+4);
+ n = PAD_EVEN(n);
+
+ if(strncasecmp(data,"LIST",4) == 0)
+ {
+ if( this->input->read(data,4) != 4 ) ERR_EXIT(AVI_ERR_READ)
+ n -= 4;
+ if(strncasecmp(data,"hdrl",4) == 0)
+ {
+ hdrl_len = n;
+ hdrl_data = (unsigned char *) xmalloc(n);
+ if(hdrl_data==0) ERR_EXIT(AVI_ERR_NO_MEM)
+ if( this->input->read(hdrl_data,n) != n ) ERR_EXIT(AVI_ERR_READ)
+ }
+ else if(strncasecmp(data,"movi",4) == 0)
+ {
+ AVI->movi_start = this->input->seek(0,SEEK_CUR);
+ this->input->seek(n,SEEK_CUR);
+ }
+ else
+ this->input->seek(n,SEEK_CUR);
+ }
+ else if(strncasecmp(data,"idx1",4) == 0)
+ {
+ /* n must be a multiple of 16, but the reading does not
+ break if this is not the case */
+
+ AVI->n_idx = AVI->max_idx = n/16;
+ AVI->idx = (unsigned char((*)[16]) ) xmalloc(n);
+ if(AVI->idx==0) ERR_EXIT(AVI_ERR_NO_MEM)
+ if( this->input->read((char *)AVI->idx,n) != n ) ERR_EXIT(AVI_ERR_READ)
+ }
+ else
+ this->input->seek(n,SEEK_CUR);
+ }
+
+ if(!hdrl_data) ERR_EXIT(AVI_ERR_NO_HDRL) ;
+ if(!AVI->movi_start) ERR_EXIT(AVI_ERR_NO_MOVI) ;
+
+ /* Interpret the header list */
+
+ for(i=0;i<hdrl_len;)
+ {
+ /* List tags are completly ignored */
+
+ if(strncasecmp(hdrl_data+i,"LIST",4)==0) { i+= 12; continue; }
+
+ n = str2ulong(hdrl_data+i+4);
+ n = PAD_EVEN(n);
+
+ /* Interpret the tag and its args */
+
+ if(strncasecmp(hdrl_data+i,"strh",4)==0)
+ {
+ i += 8;
+ if(strncasecmp(hdrl_data+i,"vids",4) == 0 && !vids_strh_seen)
+ {
+ memcpy(AVI->compressor,hdrl_data+i+4,4);
+ AVI->compressor[4] = 0;
+ AVI->dwScale = str2ulong(hdrl_data+i+20);
+ AVI->dwRate = str2ulong(hdrl_data+i+24);
+
+ if(AVI->dwScale!=0)
+ AVI->fps = (double)AVI->dwRate/(double)AVI->dwScale;
+ this->video_step = (long) (90000.0 / AVI->fps);
+
+ AVI->video_frames = str2ulong(hdrl_data+i+32);
+ AVI->video_strn = num_stream;
+ vids_strh_seen = 1;
+ lasttag = 1; /* vids */
+ }
+ else if (strncasecmp (hdrl_data+i,"auds",4) ==0 && ! auds_strh_seen)
+ {
+ AVI->audio_bytes = str2ulong(hdrl_data+i+32)*avi_sampsize(AVI);
+ AVI->audio_strn = num_stream;
+ auds_strh_seen = 1;
+ lasttag = 2; /* auds */
+ }
+ else
+ lasttag = 0;
+ num_stream++;
+ }
+ else if(strncasecmp(hdrl_data+i,"strf",4)==0)
+ {
+ i += 8;
+ if(lasttag == 1) {
+ /* printf ("size : %d\n",sizeof(AVI->bih)); */
+ memcpy (&AVI->bih, hdrl_data+i, sizeof(AVI->bih));
+ /* stream_read(demuxer->stream,(char*) &avi_header.bih,MIN(size2,sizeof(avi_header.bih))); */
+ AVI->width = str2ulong(hdrl_data+i+4);
+ AVI->height = str2ulong(hdrl_data+i+8);
+
+ /*
+ printf ("size : %d x %d (%d x %d)\n", AVI->width, AVI->height, AVI->bih.biWidth, AVI->bih.biHeight);
+ printf(" biCompression %d='%.4s'\n", AVI->bih.biCompression,
+ &AVI->bih.biCompression);
+ */
+ vids_strf_seen = 1;
+ }
+ else if(lasttag == 2)
+ {
+ memcpy (&AVI->wavex, hdrl_data+i, n);
+
+ AVI->a_fmt = str2ushort(hdrl_data+i );
+ AVI->a_chans = str2ushort(hdrl_data+i+2);
+ AVI->a_rate = str2ulong (hdrl_data+i+4);
+ AVI->a_bits = str2ushort(hdrl_data+i+14);
+ this->avg_bytes_per_sec = str2ulong (hdrl_data+i+8);
+ auds_strf_seen = 1;
+ }
+ lasttag = 0;
+ }
+ else
+ {
+ i += 8;
+ lasttag = 0;
+ }
+
+ i += n;
+ }
+
+ free(hdrl_data);
+
+ if(!vids_strh_seen || !vids_strf_seen || AVI->video_frames==0) ERR_EXIT(AVI_ERR_NO_VIDS)
+
+ AVI->video_tag[0] = AVI->video_strn/10 + '0';
+ AVI->video_tag[1] = AVI->video_strn%10 + '0';
+ AVI->video_tag[2] = 'd';
+ AVI->video_tag[3] = 'b';
+
+ /* Audio tag is set to "99wb" if no audio present */
+ if(!AVI->a_chans) AVI->audio_strn = 99;
+
+ AVI->audio_tag[0] = AVI->audio_strn/10 + '0';
+ AVI->audio_tag[1] = AVI->audio_strn%10 + '0';
+ AVI->audio_tag[2] = 'w';
+ AVI->audio_tag[3] = 'b';
+
+ this->input->seek(AVI->movi_start,SEEK_SET);
+
+ /* if the file has an idx1, check if this is relative
+ to the start of the file or to the start of the movi list */
+
+ idx_type = 0;
+
+ if(AVI->idx)
+ {
+ long pos, len;
+
+ /* Search the first videoframe in the idx1 and look where
+ it is in the file */
+
+ for(i=0;i<AVI->n_idx;i++)
+ if( strncasecmp(AVI->idx[i],AVI->video_tag,3)==0 ) break;
+ if(i>=AVI->n_idx) ERR_EXIT(AVI_ERR_NO_VIDS)
+
+ pos = str2ulong(AVI->idx[i]+ 8);
+ len = str2ulong(AVI->idx[i]+12);
+
+ this->input->seek(pos,SEEK_SET);
+ if(this->input->read(data,8)!=8) ERR_EXIT(AVI_ERR_READ) ;
+ if( strncasecmp(data,AVI->idx[i],4)==0 && str2ulong(data+4)==len )
+ {
+ idx_type = 1; /* Index from start of file */
+ }
+ else
+ {
+ this->input->seek(pos+AVI->movi_start-4,SEEK_SET);
+ if(this->input->read(data,8)!=8) ERR_EXIT(AVI_ERR_READ) ;
+ if( strncasecmp(data,AVI->idx[i],4)==0 && str2ulong(data+4)==len )
+ {
+ idx_type = 2; /* Index from start of movi list */
+ }
+ }
+ /* idx_type remains 0 if neither of the two tests above succeeds */
+ }
+
+ if(idx_type == 0)
+ {
+ /* we must search through the file to get the index */
+
+ this->input->seek( AVI->movi_start, SEEK_SET);
+
+ AVI->n_idx = 0;
+
+ while(1)
+ {
+ if( this->input->read(data,8) != 8 ) break;
+ n = str2ulong(data+4);
+
+ /* The movi list may contain sub-lists, ignore them */
+
+ if(strncasecmp(data,"LIST",4)==0)
+ {
+ this->input->seek(4,SEEK_CUR);
+ continue;
+ }
+
+ /* Check if we got a tag ##db, ##dc or ##wb */
+
+ if( ( (data[2]=='d' || data[2]=='D') &&
+ (data[3]=='b' || data[3]=='B' || data[3]=='c' || data[3]=='C') )
+ || ( (data[2]=='w' || data[2]=='W') &&
+ (data[3]=='b' || data[3]=='B') ) )
+ {
+ avi_add_index_entry(AVI,data,0,this->input->seek(0,SEEK_CUR)-8,n);
+ }
+
+ this->input->seek(PAD_EVEN(n),SEEK_CUR);
+ }
+ idx_type = 1;
+ }
+
+ /* Now generate the video index and audio index arrays */
+
+ nvi = 0;
+ nai = 0;
+
+ for(i=0;i<AVI->n_idx;i++)
+ {
+ if(strncasecmp(AVI->idx[i],AVI->video_tag,3) == 0) nvi++;
+ if(strncasecmp(AVI->idx[i],AVI->audio_tag,4) == 0) nai++;
+ }
+
+ AVI->video_frames = nvi;
+ AVI->audio_chunks = nai;
+
+ if(AVI->video_frames==0) ERR_EXIT(AVI_ERR_NO_VIDS) ;
+
+ AVI->video_index = (video_index_entry_t *) xmalloc(nvi*sizeof(video_index_entry_t));
+ if(AVI->video_index==0) ERR_EXIT(AVI_ERR_NO_MEM) ;
+
+ if(AVI->audio_chunks) {
+ AVI->audio_index = (audio_index_entry_t *) xmalloc(nai*sizeof(audio_index_entry_t));
+ if(AVI->audio_index==0) ERR_EXIT(AVI_ERR_NO_MEM) ;
+ }
+
+ nvi = 0;
+ nai = 0;
+ tot = 0;
+ ioff = idx_type == 1 ? 8 : AVI->movi_start+4;
+
+ for(i=0;i<AVI->n_idx;i++)
+ {
+ if(strncasecmp(AVI->idx[i],AVI->video_tag,3) == 0)
+ {
+ AVI->video_index[nvi].pos = str2ulong(AVI->idx[i]+ 8)+ioff;
+ AVI->video_index[nvi].len = str2ulong(AVI->idx[i]+12);
+ nvi++;
+ }
+ if(strncasecmp(AVI->idx[i],AVI->audio_tag,4) == 0)
+ {
+ AVI->audio_index[nai].pos = str2ulong(AVI->idx[i]+ 8)+ioff;
+ AVI->audio_index[nai].len = str2ulong(AVI->idx[i]+12);
+ AVI->audio_index[nai].tot = tot;
+ tot += AVI->audio_index[nai].len;
+ nai++;
+ }
+ }
+
+ AVI->audio_bytes = tot;
+
+ /* Reposition the file */
+
+ this->input->seek(AVI->movi_start,SEEK_SET);
+ AVI->video_posf = 0;
+ AVI->video_posb = 0;
+
+ return AVI;
+}
+
+static long AVI_frame_size(avi_t *AVI, long frame)
+{
+ if(!AVI->video_index) { AVI->AVI_errno = AVI_ERR_NO_IDX; return -1; }
+
+ if(frame < 0 || frame >= AVI->video_frames) return 0;
+ return(AVI->video_index[frame].len);
+}
+
+static void AVI_seek_start(avi_t *AVI)
+{
+ AVI->video_posf = 0;
+ AVI->video_posb = 0;
+}
+
+static int AVI_set_video_position(avi_t *AVI, long frame)
+{
+ if(!AVI->video_index) { AVI->AVI_errno = AVI_ERR_NO_IDX; return -1; }
+
+ if (frame < 0 ) frame = 0;
+ AVI->video_posf = frame;
+ AVI->video_posb = 0;
+ return 0;
+}
+
+static int AVI_set_audio_position(avi_t *AVI, long byte)
+{
+ long n0, n1, n;
+
+ if(!AVI->audio_index) { AVI->AVI_errno = AVI_ERR_NO_IDX; return -1; }
+
+ if(byte < 0) byte = 0;
+
+ /* Binary search in the audio chunks */
+
+ n0 = 0;
+ n1 = AVI->audio_chunks;
+
+ while(n0<n1-1)
+ {
+ n = (n0+n1)/2;
+ if(AVI->audio_index[n].tot>byte)
+ n1 = n;
+ else
+ n0 = n;
+ }
+
+ AVI->audio_posc = n0;
+ AVI->audio_posb = byte - AVI->audio_index[n0].tot;
+
+ return 0;
+}
+
+static long AVI_read_audio(demux_avi_t *this, avi_t *AVI, char *audbuf,
+ long bytes, int *bFrameDone)
+{
+ long nr, pos, left, todo;
+
+ if(!AVI->audio_index) { AVI->AVI_errno = AVI_ERR_NO_IDX; return -1; }
+
+ nr = 0; /* total number of bytes read */
+
+ /* printf ("avi audio package len: %d\n", AVI->audio_index[AVI->audio_posc].len); */
+
+
+ while(bytes>0)
+ {
+ left = AVI->audio_index[AVI->audio_posc].len - AVI->audio_posb;
+ if(left==0)
+ {
+ AVI->audio_posc++;
+ AVI->audio_posb = 0;
+ if (nr>0) {
+ *bFrameDone = 1;
+ return nr;
+ }
+ left = AVI->audio_index[AVI->audio_posc].len - AVI->audio_posb;
+ }
+ if(bytes<left)
+ todo = bytes;
+ else
+ todo = left;
+ pos = AVI->audio_index[AVI->audio_posc].pos + AVI->audio_posb;
+ /* printf ("demux_avi: read audio from %d\n", pos); */
+ if (this->input->seek (pos, SEEK_SET)<0)
+ return -1;
+ if (this->input->read(audbuf+nr,todo) != todo)
+ {
+ AVI->AVI_errno = AVI_ERR_READ;
+ *bFrameDone = 0;
+ return -1;
+ }
+ bytes -= todo;
+ nr += todo;
+ AVI->audio_posb += todo;
+ }
+
+ left = AVI->audio_index[AVI->audio_posc].len - AVI->audio_posb;
+ *bFrameDone = (left==0);
+
+ return nr;
+}
+
+static long AVI_read_video(demux_avi_t *this, avi_t *AVI, char *vidbuf,
+ long bytes, int *bFrameDone)
+{
+ long nr, pos, left, todo;
+
+ if(!AVI->video_index) { AVI->AVI_errno = AVI_ERR_NO_IDX; return -1; }
+
+ nr = 0; /* total number of bytes read */
+
+ while(bytes>0)
+ {
+ left = AVI->video_index[AVI->video_posf].len - AVI->video_posb;
+ if(left==0)
+ {
+ AVI->video_posf++;
+ AVI->video_posb = 0;
+ if (nr>0) {
+ *bFrameDone = 1;
+ return nr;
+ }
+ left = AVI->video_index[AVI->video_posf].len - AVI->video_posb;
+ }
+ if(bytes<left)
+ todo = bytes;
+ else
+ todo = left;
+ pos = AVI->video_index[AVI->video_posf].pos + AVI->video_posb;
+ /* printf ("demux_avi: read video from %d\n", pos); */
+ if (this->input->seek (pos, SEEK_SET)<0)
+ return -1;
+ if (this->input->read(vidbuf+nr,todo) != todo)
+ {
+ AVI->AVI_errno = AVI_ERR_READ;
+ *bFrameDone = 0;
+ return -1;
+ }
+ bytes -= todo;
+ nr += todo;
+ AVI->video_posb += todo;
+ }
+
+ left = AVI->video_index[AVI->video_posf].len - AVI->video_posb;
+ *bFrameDone = (left==0);
+
+ return nr;
+}
+
+static int demux_avi_next (demux_avi_t *this) {
+
+ buf_element_t *buf;
+
+ if (this->avi->video_frames <= this->avi->video_posf)
+ return 0;
+
+ buf = this->audio_fifo->buffer_pool_alloc ();
+
+ buf->content = buf->mem;
+ buf->DTS = 0 ; /* FIXME */
+
+ if (this->avi->audio_index[this->avi->audio_posc].pos<
+ this->avi->video_index[this->avi->video_posf].pos) {
+
+ /* read audio */
+ xprintf (VERBOSE|DEMUX|VAVI, "demux_avi: audio \n");
+ /* pBuf->nPTS = (uint32_t) (90000.0 * (this->avi->audio_index[this->avi->audio_posc].tot + this->avi->audio_posb) / this->nAvgBytesPerSec) ; */
+
+ buf->size = AVI_read_audio (this, this->avi, buf->mem, 2048, &buf->frame_end);
+ buf->PTS = 0;
+ buf->input_pos = this->input->seek (0, SEEK_CUR);
+
+ switch (this->avi->a_fmt) {
+ case 0x01:
+ buf->type = BUF_AUDIO_LPCM;
+ break;
+ case 0x2000:
+ buf->type = BUF_AUDIO_AC3;
+ break;
+ case 0x50:
+ case 0x55:
+ buf->type = BUF_AUDIO_MPEG;
+ break;
+ case 0x161:
+ buf->type = BUF_AUDIO_AVI;
+ break;
+ default:
+ printf ("demux_avi: unknown audio type 0x%lx =>exit\n", this->avi->a_fmt);
+ this->status = DEMUX_FINISHED;
+ buf->type = BUF_AUDIO_MPEG;
+ break;
+ }
+
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ } else {
+ /* read video */
+ xprintf (VERBOSE|DEMUX|VAVI, "demux_avi: video \n");
+
+ buf->PTS = 0;
+ /* buf->nPTS = this->avi->video_posf * this->video_step ; */
+ buf->size = AVI_read_video (this, this->avi, buf->mem, 2048, &buf->frame_end);
+ buf->type = BUF_VIDEO_AVI ;
+
+ this->video_fifo->put (this->video_fifo, buf);
+ }
+
+ xprintf (VERBOSE|DEMUX|VAVI, "size : %d\n",buf->size);
+
+ return (buf->size>0);
+}
+
+static void *demux_avi_loop (void *this_gen) {
+
+ buf_element_t *buf;
+ demux_avi_t *this = (demux_avi_t *) this_gen;
+
+ do {
+ if (!demux_avi_next(this))
+ this->status = DEMUX_FINISHED;
+
+ } while (this->status == DEMUX_OK) ;
+
+ buf = this->video_fifo->buffer_pool_alloc ();
+ buf->type = BUF_CONTROL_END;
+ this->video_fifo->put (this->video_fifo, buf);
+ buf = this->audio_fifo->buffer_pool_alloc ();
+ buf->type = BUF_CONTROL_END;
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ xprintf (VERBOSE|DEMUX, "demux_avi: demux loop finished.\n");
+
+ return NULL;
+}
+
+static void demux_avi_stop (demux_plugin_t *this_gen) {
+ void *p;
+ demux_avi_t *this = (demux_avi_t *) this_gen;
+
+ this->status = DEMUX_FINISHED;
+
+ pthread_join (this->thread, &p);
+
+ AVI_close (this->avi);
+ this->avi = NULL;
+}
+
+static void demux_avi_close (demux_plugin_t *this_gen) {
+ demux_avi_t *this = (demux_avi_t *) this_gen;
+ free(this);
+}
+
+static int demux_avi_get_status (demux_plugin_t *this_gen) {
+ demux_avi_t *this = (demux_avi_t *) this_gen;
+ return this->status;
+}
+
+static void demux_avi_start (demux_plugin_t *this_gen,
+ fifo_buffer_t *bufVideo,
+ fifo_buffer_t *bufAudio,
+ fifo_buffer_t *bufSPU,
+ off_t pos)
+{
+ buf_element_t *buf;
+ demux_avi_t *this = (demux_avi_t *) this_gen;
+
+ this->audio_fifo = bufVideo;
+ this->video_fifo = bufAudio;
+
+ this->status = DEMUX_OK;
+
+ this->avi = AVI_init(this);
+
+ if (!this->avi) {
+ printf ("demux_avi: init failed, avi_errno=%d .\n", this->avi->AVI_errno);
+ this->status = DEMUX_FINISHED;
+ return;
+ }
+
+ printf ("demux_avi: video format = %s, audio format = 0x%lx\n",
+ this->avi->compressor, this->avi->a_fmt);
+
+ AVI_seek_start (this->avi);
+
+ /*
+ * seek
+ */
+
+ /* seek audio */
+ while (this->avi->audio_index[this->avi->audio_posc].pos < pos) {
+ this->avi->audio_posc++;
+ if (this->avi->audio_posc>this->avi->audio_chunks) {
+ this->status = DEMUX_FINISHED;
+ return;
+ }
+ }
+
+ /* seek video */
+
+ /*
+ while (this->avi->video_index[this->avi->video_posf].pos < pos) {
+ this->avi->video_posf++;
+ if (this->avi->video_posf>this->avi->video_frames) {
+ this->mnStatus = DEMUX_FINISHED;
+ return;
+ }
+ }
+ */
+
+
+ this->avi->video_posf = (long) (((double) this->avi->audio_index[this->avi->audio_posc].tot / (double) this->avi->audio_bytes) * (double) this->avi->video_frames);
+
+
+ /*
+ * send start buffers
+ */
+
+ buf = this->video_fifo->buffer_pool_alloc ();
+ buf->type = BUF_CONTROL_START;
+ this->video_fifo->put (this->video_fifo, buf);
+
+ buf = this->audio_fifo->buffer_pool_alloc ();
+ buf->type = BUF_CONTROL_START;
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ buf = this->video_fifo->buffer_pool_alloc ();
+ buf->content = buf->mem;
+ this->avi->bih.biSize = this->video_step; /* HACK */
+ memcpy (buf->content, &this->avi->bih, sizeof (this->avi->bih));
+ buf->size = sizeof (this->avi->bih);
+ buf->type = BUF_VIDEO_AVI;
+ this->video_fifo->put (this->video_fifo, buf);
+
+ buf = this->audio_fifo->buffer_pool_alloc ();
+ buf->content = buf->mem;
+ memcpy (buf->content, &this->avi->wavex,
+ sizeof (this->avi->wavex));
+ buf->size = sizeof (this->avi->wavex);
+ buf->type = BUF_AUDIO_AVI;
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ pthread_create (&this->thread, NULL, demux_avi_loop, this) ;
+}
+
+static int demux_avi_open(demux_plugin_t *this_gen, input_plugin_t *input, int stage) {
+
+ demux_avi_t *this = (demux_avi_t *) this_gen;
+
+ switch(stage) {
+
+ case STAGE_BY_CONTENT: {
+ uint8_t buf[4096];
+
+ if (input->get_blocksize())
+ return DEMUX_CANNOT_HANDLE;
+
+ if (!(input->get_capabilities() & INPUT_CAP_SEEKABLE))
+ return DEMUX_CANNOT_HANDLE;
+
+ input->seek(0, SEEK_SET);
+
+ if(input->read(buf, 4)) {
+
+ if((buf[0] == 0x52)
+ && (buf[1] == 0x49)
+ && (buf[2] == 0x46)
+ && (buf[3] == 0x46)) {
+ this->input = input;
+ this->avi = AVI_init (this);
+ if (this->avi)
+ return DEMUX_CAN_HANDLE;
+ else {
+ printf ("demux_avi: AVI_init failed.\n");
+ return DEMUX_CANNOT_HANDLE;
+ }
+ }
+
+ }
+ return DEMUX_CANNOT_HANDLE;
+ }
+ break;
+
+ case STAGE_BY_EXTENSION: {
+ char *ending, *mrl;
+
+ mrl = this->input->get_mrl ();
+
+ ending = strrchr(mrl, '.');
+ xprintf(VERBOSE|DEMUX, "demux_avi_can_handle: ending %s of %s\n",
+ ending, mrl);
+
+ if(ending) {
+ if(!strcasecmp(ending, ".avi")) {
+ this->input = input;
+ this->avi = AVI_init (this);
+ if (this->avi)
+ return DEMUX_CAN_HANDLE;
+ else {
+ printf ("demux_avi: AVI_init failed.\n");
+ return DEMUX_CANNOT_HANDLE;
+ }
+ }
+ }
+
+ return DEMUX_CANNOT_HANDLE;
+ }
+ break;
+
+ default:
+ return DEMUX_CANNOT_HANDLE;
+ break;
+ }
+
+ return DEMUX_CANNOT_HANDLE;
+}
+
+static char *demux_avi_get_id(demux_plugin_t *this) {
+ return "AVI";
+}
+
+demux_plugin_t *init_demux_avi(config_values_t *cfg, uint32_t xd) {
+
+ demux_avi_t *this = xmalloc (sizeof (demux_avi_t));
+
+ xine_debug = xd;
+
+ this->demux_plugin.open = demux_avi_open;
+ this->demux_plugin.start = demux_avi_start;
+ this->demux_plugin.stop = demux_avi_stop;
+ this->demux_plugin.close = demux_avi_close;
+ this->demux_plugin.get_status = demux_avi_get_status;
+ this->demux_plugin.get_identifier = demux_avi_get_id;
+
+
+ return (demux_plugin_t *) this;
+}
diff --git a/src/demuxers/demux_elem.c b/src/demuxers/demux_elem.c
new file mode 100644
index 000000000..855c22e17
--- /dev/null
+++ b/src/demuxers/demux_elem.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2000 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: demux_elem.c,v 1.1 2001/04/18 22:33:58 f1rmb Exp $
+ *
+ * demultiplexer for elementary mpeg streams
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+
+#include "xine.h"
+#include "monitor.h"
+#include "demux.h"
+
+static uint32_t xine_debug;
+
+typedef struct _demux_mpeg_elem_globals {
+ fifo_buffer_t *mBufVideo;
+ fifo_buffer_t *mBufAudio;
+
+ input_plugin_t *mInput;
+ pthread_t mThread;
+ int mnBlocksize;
+
+ int mnStatus;
+} demux_mpeg_elem_globals_t ;
+
+static demux_mpeg_elem_globals_t gDemuxMpegElem;
+static fifobuf_functions_t *Ffb;
+
+/*
+ *
+ */
+static int demux_mpeg_elem_next (void) {
+
+ buf_element_t *pBuf;
+
+ pBuf = Ffb->buffer_pool_alloc ();
+
+ pBuf->pContent = pBuf->pMem;
+ pBuf->nDTS = 0;
+ pBuf->nPTS = 0;
+ pBuf->nSize = gDemuxMpegElem.mInput->read(pBuf->pMem,
+ gDemuxMpegElem.mnBlocksize);
+ pBuf->nType = BUF_MPEGELEMENT;
+ pBuf->nInputPos = gDemuxMpegElem.mInput->seek (0, SEEK_CUR);
+
+ Ffb->fifo_buffer_put (gDemuxMpegElem.mBufVideo, pBuf);
+
+ return (pBuf->nSize==gDemuxMpegElem.mnBlocksize);
+}
+
+/*
+ *
+ */
+static void *demux_mpeg_elem_loop (void *dummy) {
+ buf_element_t *pBuf;
+
+ do {
+
+ if (!demux_mpeg_elem_next())
+ gDemuxMpegElem.mnStatus = DEMUX_FINISHED;
+
+ } while (gDemuxMpegElem.mnStatus == DEMUX_OK) ;
+
+ xprintf (VERBOSE|DEMUX, "demux loop finished (status: %d)\n",
+ gDemuxMpegElem.mnStatus);
+
+ pBuf = Ffb->buffer_pool_alloc ();
+ pBuf->nType = BUF_STREAMEND;
+ Ffb->fifo_buffer_put (gDemuxMpegElem.mBufVideo, pBuf);
+
+ pBuf = Ffb->buffer_pool_alloc ();
+ pBuf->nType = BUF_STREAMEND;
+ Ffb->fifo_buffer_put (gDemuxMpegElem.mBufAudio, pBuf);
+
+ return NULL;
+}
+
+/*
+ *
+ */
+static void demux_mpeg_elem_stop (void) {
+ void *p;
+
+ gDemuxMpegElem.mnStatus = DEMUX_FINISHED;
+
+ Ffb->fifo_buffer_clear(gDemuxMpegElem.mBufVideo);
+ Ffb->fifo_buffer_clear(gDemuxMpegElem.mBufAudio);
+
+ pthread_join (gDemuxMpegElem.mThread, &p);
+}
+
+/*
+ *
+ */
+static int demux_mpeg_elem_get_status (void) {
+ return gDemuxMpegElem.mnStatus;
+}
+
+/*
+ *
+ */
+static void demux_mpeg_elem_start (input_plugin_t *input_plugin,
+ fifo_buffer_t *bufVideo,
+ fifo_buffer_t *bufAudio,
+ fifo_buffer_t *bufSPU,
+ off_t pos)
+{
+ buf_element_t *pBuf;
+
+ gDemuxMpegElem.mInput = input_plugin;
+ gDemuxMpegElem.mBufVideo = bufVideo;
+ gDemuxMpegElem.mBufAudio = bufAudio;
+
+ gDemuxMpegElem.mnStatus = DEMUX_OK;
+ /*
+ if ((gDemuxMpegElem.mInput->get_capabilities() & INPUT_CAP_SEEKABLE) != 0 ) {
+ xprintf (VERBOSE|DEMUX, "=>seek to %Ld\n",pos);
+
+ gDemuxMpegElem.mInput->seek (pos, SEEK_SET);
+ }
+ else { */
+ if((gDemuxMpegElem.mInput->get_capabilities() & INPUT_CAP_SEEKABLE) != 0)
+ gDemuxMpegElem.mInput->seek (pos, SEEK_SET);
+/* } */
+
+ gDemuxMpegElem.mnBlocksize = 2048;
+ // pos /= (off_t) gDemuxMpegElem.mnBlocksize;
+ // pos *= (off_t) gDemuxMpegElem.mnBlocksize;
+ // xprintf (VERBOSE|DEMUX, "=>seek to %Ld\n",pos);
+
+ // gDemuxMpegElem.mInput->seek (pos, SEEK_SET);
+
+ /*
+ * send reset buffer
+ */
+
+ pBuf = Ffb->buffer_pool_alloc ();
+ pBuf->nType = BUF_RESET;
+ Ffb->fifo_buffer_put (gDemuxMpegElem.mBufVideo, pBuf);
+
+ pBuf = Ffb->buffer_pool_alloc ();
+ pBuf->nType = BUF_RESET;
+ Ffb->fifo_buffer_put (gDemuxMpegElem.mBufAudio, pBuf);
+
+ /*
+ * now start demuxing
+ */
+
+ pthread_create (&gDemuxMpegElem.mThread, NULL, demux_mpeg_elem_loop, NULL) ;
+}
+
+/*
+ *
+ */
+static void demux_mpeg_elem_select_audio_channel (int nChannel) {
+}
+
+/*
+ *
+ */
+static void demux_mpeg_elem_select_spu_channel (int nChannel) {
+}
+
+/*
+ *
+ */
+static int demux_mpeg_elem_open(input_plugin_t *ip,
+ const char *MRL, int stage) {
+
+ switch(stage) {
+
+ case STAGE_BY_CONTENT: {
+ uint8_t buf[4096];
+ int bs = 0;
+
+ if(!ip)
+ return DEMUX_CANNOT_HANDLE;
+
+ if((ip->get_capabilities() & INPUT_CAP_SEEKABLE) != 0) {
+ ip->seek(0, SEEK_SET);
+
+ if(ip->get_blocksize)
+ bs = ip->get_blocksize();
+
+ bs = (bs > 4) ? bs : 4;
+
+ if(ip->read(buf, bs)) {
+
+ if(buf[0] || buf[1] || (buf[2] != 0x01))
+ return DEMUX_CANNOT_HANDLE;
+
+ switch(buf[3]) {
+ case 0xb3:
+ return DEMUX_CAN_HANDLE;
+ break;
+ }
+ }
+ }
+ return DEMUX_CANNOT_HANDLE;
+ }
+ break;
+
+ case STAGE_BY_EXTENSION: {
+ char *suffix;
+
+ suffix = strrchr(MRL, '.');
+ xprintf(VERBOSE|DEMUX, "demux_pure_can_handle: suffix %s of %s\n",
+ suffix, MRL);
+
+ if(suffix) {
+ if(!strcasecmp(suffix, ".mpv"))
+ return DEMUX_CAN_HANDLE;
+ }
+
+ return DEMUX_CANNOT_HANDLE;
+ }
+ break;
+
+ default:
+ return DEMUX_CANNOT_HANDLE;
+ break;
+ }
+
+ return DEMUX_CANNOT_HANDLE;
+}
+
+/*
+ *
+ */
+static char *demux_mpeg_elem_get_id(void) {
+ return "MPEG_ELEM";
+}
+
+/*
+ *
+ */
+static demux_functions_t demux_mpeg_elem_functions = {
+ NULL,
+ NULL,
+ demux_mpeg_elem_open,
+ demux_mpeg_elem_start,
+ demux_mpeg_elem_stop,
+ demux_mpeg_elem_get_status,
+ demux_mpeg_elem_select_audio_channel,
+ demux_mpeg_elem_select_spu_channel,
+ demux_mpeg_elem_get_id
+};
+
+/*
+ *
+ */
+demux_functions_t *init_demux_mpeg_elem(fifobuf_functions_t *f, uint32_t xd) {
+
+ Ffb = f;
+ xine_debug = xd;
+ return &demux_mpeg_elem_functions;
+}
diff --git a/src/demuxers/demux_mpeg.c b/src/demuxers/demux_mpeg.c
new file mode 100644
index 000000000..9fcb37df4
--- /dev/null
+++ b/src/demuxers/demux_mpeg.c
@@ -0,0 +1,626 @@
+/*
+ * Copyright (C) 2000 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: demux_mpeg.c,v 1.1 2001/04/18 22:33:58 f1rmb Exp $
+ *
+ * demultiplexer for mpeg 1/2 program streams
+ * reads streams of variable blocksizes
+ *
+ * currently only used for mpeg-1-files
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+
+#include "monitor.h"
+#include "xine.h"
+#include "demux.h"
+#include "utils.h"
+
+static uint32_t xine_debug;
+
+typedef struct demux_mpeg_s {
+
+ demux_plugin_t demux_plugin;
+
+ fifo_buffer_t *audio_fifo;
+ fifo_buffer_t *video_fifo;
+
+ input_plugin_t *input;
+
+ pthread_t thread;
+
+ unsigned char dummy_space[100000];
+
+ int status;
+} demux_mpeg_t ;
+
+static uint32_t read_bytes (demux_mpeg_t *this, int n) {
+
+ uint32_t res;
+ uint32_t i;
+ unsigned char buf[6];
+
+ buf[4]=0;
+
+ i = this->input->read (buf, n);
+
+ if (i != n) {
+ this->status = DEMUX_FINISHED;
+ xprintf (VERBOSE|DEMUX, "Unexpected end of stream\n");
+ }
+
+
+ switch (n) {
+ case 1:
+ res = buf[0];
+ break;
+ case 2:
+ res = (buf[0]<<8) | buf[1];
+ break;
+ case 3:
+ res = (buf[0]<<16) | (buf[1]<<8) | buf[2];
+ break;
+ case 4:
+ res = (buf[2]<<8) | buf[3] | (buf[1]<<16) | (buf[0] << 24);
+ break;
+ default:
+ fprintf (stderr,
+ "How how - something wrong in wonderland demux:read_bytes (%d)\n",
+ n);
+ exit (1);
+ }
+
+ return res;
+}
+
+static void parse_mpeg2_packet (demux_mpeg_t *this, int nID) {
+
+ int nLen, i;
+ uint32_t w, flags, header_len, pts;
+ buf_element_t *buf;
+
+ nLen = read_bytes(this, 2);
+
+ xprintf (VERBOSE|DEMUX|MPEG, " mpeg2 packet (len=%d",nLen);
+
+ if (nID==0xbd) {
+
+ int track;
+
+ xprintf (VERBOSE|DEMUX|AC3, ",ac3");
+
+ w = read_bytes(this, 1);
+ flags = read_bytes(this, 1);
+ header_len = read_bytes(this, 1);
+
+ nLen -= header_len + 3;
+
+ pts=0;
+
+ if ((flags & 0x80) == 0x80) {
+
+ w = read_bytes(this, 1);
+ pts = (w & 0x0e) << 29 ;
+ w = read_bytes(this, 2);
+ pts |= (w & 0xFFFE) << 14;
+ w = read_bytes(this, 2);
+ pts |= (w & 0xFFFE) >> 1;
+
+ xprintf (VERBOSE|DEMUX|VPTS, ", pts=%d",pts);
+
+ header_len -= 5 ;
+ }
+
+ /* read rest of header */
+ i = this->input->read (this->dummy_space, header_len+4);
+
+ track = this->dummy_space[0] & 0x0F ;
+
+ xprintf (VERBOSE|DEMUX, ", track=%02x", track);
+
+ /* contents */
+
+ buf = this->input->read_block (this->audio_fifo, nLen-4);
+
+ buf->type = BUF_AUDIO_AC3 + track;
+ buf->PTS = pts;
+ buf->DTS = 0 ; /* FIXME */
+ buf->input_pos = this->input->get_current_pos ();
+
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ } else if ((nID & 0xe0) == 0xc0) {
+ int track = nID & 0x1f;
+
+ xprintf (VERBOSE|DEMUX|AUDIO, ", audio #%d", track);
+
+ w = read_bytes(this, 1);
+ flags = read_bytes(this, 1);
+ header_len = read_bytes(this, 1);
+
+ nLen -= header_len + 3;
+
+ pts = 0;
+
+ if ((flags & 0x80) == 0x80) {
+
+ w = read_bytes(this, 1);
+ pts = (w & 0x0e) << 29 ;
+ w = read_bytes(this, 2);
+ pts |= (w & 0xFFFE) << 14;
+ w = read_bytes(this, 2);
+ pts |= (w & 0xFFFE) >> 1;
+
+ xprintf (VERBOSE|DEMUX|VPTS, ", pts=%d",pts);
+
+ header_len -= 5 ;
+ }
+
+ /* read rest of header */
+ i = this->input->read (this->dummy_space, header_len);
+
+ buf = this->input->read_block (this->audio_fifo, nLen);
+
+ buf->type = BUF_AUDIO_MPEG + track;
+ buf->PTS = pts;
+ buf->DTS = 0; /* FIXME */
+ buf->input_pos = this->input->seek (0, SEEK_CUR);
+
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ } else if ((nID >= 0xbc) && ((nID & 0xf0) == 0xe0)) {
+
+ xprintf (VERBOSE|DEMUX|VIDEO, ",video");
+
+ w = read_bytes(this, 1);
+ flags = read_bytes(this, 1);
+ header_len = read_bytes(this, 1);
+
+ nLen -= header_len + 3;
+
+ pts = 0;
+
+ if ((flags & 0x80) == 0x80) {
+
+ w = read_bytes(this, 1);
+ pts = (w & 0x0e) << 29 ;
+ w = read_bytes(this, 2);
+ pts |= (w & 0xFFFE) << 14;
+ w = read_bytes(this, 2);
+ pts |= (w & 0xFFFE) >> 1;
+
+ xprintf (VERBOSE|DEMUX|VPTS, ", pts=%d",pts);
+
+ header_len -= 5 ;
+ }
+
+ /* read rest of header */
+ i = this->input->read (this->dummy_space, header_len);
+
+ /* contents */
+
+ buf = this->input->read_block (this->audio_fifo, nLen);
+
+ buf->type = BUF_VIDEO_MPEG;
+ buf->PTS = pts;
+ buf->DTS = 0;
+
+ this->video_fifo->put (this->video_fifo, buf);
+
+ } else {
+ xprintf (VERBOSE|DEMUX, ",unknown stream - skipped");
+
+ i = this->input->read (this->dummy_space, nLen);
+ /* (*this->input->seek) (nLen,SEEK_CUR); */
+ }
+
+ xprintf (VERBOSE|DEMUX, ")\n");
+
+}
+
+static void parse_mpeg1_packet (demux_mpeg_t *this, int nID)
+{
+ int nLen;
+ uint32_t w;
+ int i;
+ int pts;
+ buf_element_t *buf;
+
+ xprintf (VERBOSE|DEMUX, " packet (");
+
+ nLen = read_bytes(this, 2);
+
+ xprintf (VERBOSE|DEMUX, "len=%d",nLen);
+
+ pts=0;
+
+ if (nID != 0xbf) {
+
+ w = read_bytes(this, 1); nLen--;
+
+ while ((w & 0x80) == 0x80) {
+
+ if (this->status != DEMUX_OK)
+ return;
+
+ /* stuffing bytes */
+ w = read_bytes(this, 1); nLen--;
+ }
+
+ if ((w & 0xC0) == 0x40) {
+
+ if (this->status != DEMUX_OK)
+ return;
+
+ /* buffer_scale, buffer size */
+ w = read_bytes(this, 1); nLen--;
+ w = read_bytes(this, 1); nLen--;
+ }
+
+ if ((w & 0xF0) == 0x20) {
+
+ if (this->status != DEMUX_OK)
+ return;
+
+ pts = (w & 0xe) << 29 ;
+ w = read_bytes(this, 2); nLen -= 2;
+
+ pts |= (w & 0xFFFE) << 14;
+
+ w = read_bytes(this, 2); nLen -= 2;
+ pts |= (w & 0xFFFE) >> 1;
+
+ xprintf (VERBOSE|DEMUX|VPTS, ", pts=%d",pts);
+
+ /* pts = 0; */
+
+ } else if ((w & 0xF0) == 0x30) {
+
+ if (this->status != DEMUX_OK)
+ return;
+
+ pts = (w & 0x0e) << 29 ;
+ w = read_bytes(this, 2); nLen -= 2;
+
+ pts |= (w & 0xFFFE) << 14;
+
+ w = read_bytes(this, 2); nLen -= 2;
+
+ pts |= (w & 0xFFFE) >> 1;
+
+/* printf ("pts2=%d\n",pts); */
+ xprintf (VERBOSE|DEMUX|VPTS, ", pts2=%d",pts);
+
+ /* Decoding Time Stamp */
+ w = read_bytes(this, 3); nLen -= 3;
+ w = read_bytes(this, 2); nLen -= 2;
+ } else {
+ xprintf (VERBOSE|DEMUX, ", w = %02x",w);
+ if (w != 0x0f)
+ xprintf (VERBOSE|DEMUX, " ERROR w (%02x) != 0x0F ",w);
+ }
+
+ }
+
+ if ((nID & 0xe0) == 0xc0) {
+ int track = nID & 0x1f;
+
+ xprintf (VERBOSE|DEMUX|AUDIO, ", audio #%d", track);
+
+ buf = this->input->read_block (this->audio_fifo, nLen);
+
+ buf->type = BUF_AUDIO_MPEG + track ;
+ buf->PTS = pts;
+ buf->DTS = 0; /* FIXME */
+ buf->input_pos = this->input->seek (0, SEEK_CUR);
+
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ } else if ((nID & 0xf0) == 0xe0) {
+
+ xprintf (VERBOSE|DEMUX|VIDEO, ", video #%d", nID & 0x0f);
+
+ buf = this->input->read_block (this->video_fifo, nLen);
+
+ buf->type = BUF_VIDEO_MPEG;
+ buf->PTS = pts;
+ buf->DTS = 0; /* FIXME */
+
+ this->video_fifo->put (this->video_fifo, buf);
+
+ } else if (nID == 0xbd) {
+ xprintf (VERBOSE|DEMUX|AC3, ", ac3");
+ i = this->input->read (this->dummy_space, nLen);
+ } else {
+ xprintf (VERBOSE|DEMUX, ", unknown (nID = %d)",nID);
+ this->input->read (this->dummy_space, nLen);
+ }
+
+ xprintf (VERBOSE|DEMUX, ")\n");
+}
+
+static uint32_t parse_pack(demux_mpeg_t *this)
+{
+ uint32_t buf ;
+ char scratch[1024];
+ int mpeg_version;
+
+ xprintf (VERBOSE|DEMUX, "pack {\n");
+
+ /* system_clock_reference */
+ buf = read_bytes (this, 1);
+ xprintf (VERBOSE|DEMUX|VIDEO, " mpeg version : %02x",buf>>4);
+
+ if ((buf>>4) == 4) {
+ xprintf (VERBOSE|DEMUX|VIDEO, " => mpeg II \n");
+ buf = read_bytes(this, 2);
+ mpeg_version = 2;
+ } else {
+ xprintf (VERBOSE|DEMUX|VIDEO, " => mpeg I \n");
+ mpeg_version = 1;
+ }
+
+ buf = read_bytes (this, 2);
+ buf = read_bytes (this, 2);
+
+ /* mux_rate */
+
+ buf = read_bytes (this, 3) ;
+
+ /* printf (" mux_rate = %06x\n",buf); */
+
+ /* system header */
+
+ buf = read_bytes (this, 4) ;
+
+ /* printf (" code = %08x\n",buf);*/
+
+ if (buf == 0x000001bb) {
+ buf = read_bytes (this, 2);
+ xprintf (VERBOSE|DEMUX, " system_header (%d +6 bytes)\n",buf);
+
+ this->input->read (scratch,buf);
+
+ buf = read_bytes (this, 4) ;
+ }
+
+ /* printf (" code = %08x\n",buf); */
+
+ while ( ((buf & 0xFFFFFF00) == 0x00000100)
+ && ((buf & 0xff) != 0xba) ) {
+
+ if (this->status != DEMUX_OK)
+ return buf;
+
+ if (mpeg_version == 1)
+ parse_mpeg1_packet (this, buf & 0xFF);
+ else
+ parse_mpeg2_packet (this, buf & 0xFF);
+
+ buf = read_bytes (this, 4);
+ xprintf (VERBOSE|DEMUX, " code = %08x\n",buf);
+ }
+
+ xprintf (VERBOSE|DEMUX, "}\n");
+
+ return buf;
+
+}
+
+static void demux_mpeg_resync (demux_mpeg_t *this, uint32_t buf) {
+
+ while ((buf !=0x000001ba) && (this->status == DEMUX_OK)) {
+ xprintf (VERBOSE|DEMUX, "resync : %08x\n",buf);
+ buf = (buf << 8) | read_bytes (this, 1);
+ }
+}
+
+static void *demux_mpeg_loop (void *this_gen) {
+
+ demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
+ buf_element_t *buf;
+ uint32_t w;
+
+ do {
+ w = parse_pack (this);
+
+ if (w != 0x000001ba)
+ demux_mpeg_resync (this, w);
+
+ } while (this->status == DEMUX_OK) ;
+
+ buf = this->video_fifo->buffer_pool_alloc ();
+ buf->type = BUF_CONTROL_END;
+ this->video_fifo->put (this->video_fifo, buf);
+ buf = this->audio_fifo->buffer_pool_alloc ();
+ buf->type = BUF_CONTROL_END;
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ xprintf (VERBOSE|DEMUX, "demux loop finished (status: %d, buf:%x)\n",
+ this->status, w);
+
+ return NULL;
+}
+
+static void demux_mpeg_stop (demux_plugin_t *this_gen) {
+ void *p;
+ demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
+
+ this->status = DEMUX_FINISHED;
+
+ pthread_join (this->thread, &p);
+}
+
+static int demux_mpeg_get_status (demux_plugin_t *this_gen) {
+ demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
+ return this->status;
+}
+
+static void demux_mpeg_start (demux_plugin_t *this_gen,
+ fifo_buffer_t *video_fifo,
+ fifo_buffer_t *audio_fifo,
+ fifo_buffer_t *spu_fifo,
+ off_t pos)
+{
+ demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
+ buf_element_t *buf;
+
+ this->video_fifo = video_fifo;
+ this->audio_fifo = audio_fifo;
+
+ this->status = DEMUX_OK;
+
+ if ((this->input->get_capabilities () & INPUT_CAP_SEEKABLE) != 0 ) {
+ xprintf (VERBOSE|DEMUX, "=>seek to %Ld\n",pos);
+ this->input->seek (pos+4, SEEK_SET);
+ }
+
+ buf = this->video_fifo->buffer_pool_alloc ();
+ buf->type = BUF_CONTROL_START;
+ this->video_fifo->put (this->video_fifo, buf);
+ buf = this->audio_fifo->buffer_pool_alloc ();
+ buf->type = BUF_CONTROL_START;
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ pthread_create (&this->thread, NULL, demux_mpeg_loop, this) ;
+}
+
+static int demux_mpeg_open(demux_plugin_t *this_gen, input_plugin_t *ip, int stage) {
+
+ demux_mpeg_t *this = (demux_mpeg_t *) this_gen;
+
+ this->input = ip;
+
+ switch(stage) {
+
+ case STAGE_BY_CONTENT: {
+ uint8_t buf[4096];
+
+ if((ip->get_capabilities() & INPUT_CAP_SEEKABLE) != 0) {
+ ip->seek(0, SEEK_SET);
+
+ if(ip->get_blocksize())
+ return DEMUX_CANNOT_HANDLE;
+
+ if(ip->read(buf, 6)) {
+
+ if(buf[0] || buf[1] || (buf[2] != 0x01))
+ return DEMUX_CANNOT_HANDLE;
+
+ switch(buf[3]) {
+
+ case 0xba:
+ if((buf[4] & 0xf0) == 0x20)
+ return DEMUX_CAN_HANDLE;
+ break;
+
+ case 0xe0:
+ if((buf[6] & 0xc0) != 0x80)
+ return DEMUX_CAN_HANDLE;
+ break;
+
+ }
+ }
+ }
+ return DEMUX_CANNOT_HANDLE;
+ }
+ break;
+
+ case STAGE_BY_EXTENSION: {
+ char *media;
+ char *ending;
+ char *MRL = ip->get_mrl();
+
+ media = strstr(MRL, "://");
+ if(media) {
+ if((!(strncasecmp(MRL, "stdin", 5)))
+ || (!(strncasecmp(MRL, "fifo", 4)))) {
+ if(!(strncasecmp((media+3), "mpeg1", 5))) {
+ perr("%s(%d)mpeg\n", __FUNCTION__, stage);
+ return DEMUX_CAN_HANDLE;
+ }
+ else if(!(strncasecmp((media+3), "mpeg2", 5))) {
+ return DEMUX_CANNOT_HANDLE;
+ }
+ fprintf(stderr, "You should specify mpeg(mpeg1/mpeg2) stream type.\n");
+ return DEMUX_CANNOT_HANDLE;
+ }
+ else if(strncasecmp(MRL, "file", 4)) {
+ return DEMUX_CANNOT_HANDLE;
+ }
+ }
+
+ ending = strrchr(MRL, '.');
+ xprintf(VERBOSE|DEMUX, "demux_mpeg_can_handle: ending %s of %s\n",
+ ending, MRL);
+
+ if(!ending)
+ return DEMUX_CANNOT_HANDLE;
+
+ if(!strcasecmp(ending, ".mpg")
+ || (!strcasecmp(ending, ".mpeg"))) {
+ return DEMUX_CAN_HANDLE;
+ }
+ }
+ break;
+
+ default:
+ return DEMUX_CANNOT_HANDLE;
+ break;
+ }
+
+ return DEMUX_CANNOT_HANDLE;
+}
+
+static void demux_mpeg_select_spu_channel (int nChannel) {
+}
+
+static char *demux_mpeg_get_id(demux_plugin_t *this) {
+ return "MPEG";
+}
+
+static void demux_mpeg_close (demux_plugin_t *this) {
+ /* nothing */
+}
+
+demux_plugin_t *init_demux_mpeg(config_values_t *cfg, uint32_t xd) {
+
+ demux_mpeg_t *this = xmalloc (sizeof (demux_mpeg_t));
+
+ xine_debug = xd;
+
+ this->demux_plugin.open = demux_mpeg_open;
+ this->demux_plugin.start = demux_mpeg_start;
+ this->demux_plugin.stop = demux_mpeg_stop;
+ this->demux_plugin.close = demux_mpeg_close;
+ this->demux_plugin.get_status = demux_mpeg_get_status;
+ this->demux_plugin.get_identifier = demux_mpeg_get_id;
+
+ return (demux_plugin_t *) this;
+}
+
diff --git a/src/demuxers/demux_mpeg_block.c b/src/demuxers/demux_mpeg_block.c
new file mode 100644
index 000000000..531bf44aa
--- /dev/null
+++ b/src/demuxers/demux_mpeg_block.c
@@ -0,0 +1,519 @@
+/*
+ * Copyright (C) 2000 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: demux_mpeg_block.c,v 1.1 2001/04/18 22:33:58 f1rmb Exp $
+ *
+ * demultiplexer for mpeg 1/2 program streams
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+
+#include "xine.h"
+#include "monitor.h"
+#include "demux.h"
+#include "utils.h"
+
+static uint32_t xine_debug;
+
+typedef struct demux_mpeg_block_s {
+ demux_plugin_t demux_plugin;
+
+ fifo_buffer_t *audio_fifo;
+ fifo_buffer_t *video_fifo;
+ fifo_buffer_t *spu_fifo;
+
+ input_plugin_t *input;
+
+ pthread_t thread;
+
+ int status;
+
+ int blocksize;
+} demux_mpeg_block_t ;
+
+
+static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this) {
+
+ buf_element_t *buf;
+ unsigned char *p;
+ int bMpeg1=0;
+ uint32_t nHeaderLen;
+ uint32_t nPTS;
+ uint32_t nDTS;
+ uint32_t nPacketLen;
+ uint32_t nStreamID;
+
+
+ buf = this->input->read_block (this->video_fifo, this->blocksize);
+
+ if (buf==NULL) {
+ this->status = DEMUX_FINISHED;
+ return ;
+ }
+
+ p = buf->content; /* len = this->mnBlocksize; */
+
+ if (p[3] == 0xBA) { /* program stream pack header */
+
+ int nStuffingBytes;
+
+ xprintf (VERBOSE|DEMUX, "program stream pack header\n");
+
+ bMpeg1 = (p[4] & 0x40) == 0;
+
+ if (bMpeg1) {
+
+ p += 12;
+
+ } else { /* mpeg2 */
+
+ nStuffingBytes = p[0xD] & 0x07;
+
+ xprintf (VERBOSE|DEMUX, "%d stuffing bytes\n",nStuffingBytes);
+
+ p += 14 + nStuffingBytes;
+ }
+ }
+
+
+ if (p[3] == 0xbb) { /* program stream system header */
+
+ int nHeaderLen;
+
+ xprintf (VERBOSE|DEMUX, "program stream system header\n");
+
+ nHeaderLen = (p[4] << 8) | p[5];
+
+ p += 6 + nHeaderLen;
+ }
+
+ /* we should now have a PES packet here */
+
+ if (p[0] || p[1] || (p[2] != 1)) {
+ fprintf (stderr, "demux error! %02x %02x %02x (should be 0x000001) \n",p[0],p[1],p[2]);
+ buf->free_buffer (buf);
+ return ;
+ }
+
+ nPacketLen = p[4] << 8 | p[5];
+ nStreamID = p[3];
+
+ xprintf (VERBOSE|DEMUX, "packet id = %02x len = %d\n",nStreamID, nPacketLen);
+
+ if (bMpeg1) {
+
+ if (nStreamID == 0xBF) {
+ buf->free_buffer (buf);
+ return ;
+ }
+
+ p += 6; /* nPacketLen -= 6; */
+
+ while ((p[0] & 0x80) == 0x80) {
+ p++;
+ nPacketLen--;
+ /* printf ("stuffing\n");*/
+ }
+
+ if ((p[0] & 0xc0) == 0x40) {
+ /* STD_buffer_scale, STD_buffer_size */
+ p += 2;
+ nPacketLen -=2;
+ }
+
+ nPTS = 0;
+ nDTS = 0;
+ if ((p[0] & 0xf0) == 0x20) {
+ nPTS = (p[ 0] & 0x0E) << 29 ;
+ nPTS |= p[ 1] << 22 ;
+ nPTS |= (p[ 2] & 0xFE) << 14 ;
+ nPTS |= p[ 3] << 7 ;
+ nPTS |= (p[ 4] & 0xFE) >> 1 ;
+ p += 5;
+ nPacketLen -=5;
+ } else if ((p[0] & 0xf0) == 0x30) {
+ nPTS = (p[ 0] & 0x0E) << 29 ;
+ nPTS |= p[ 1] << 22 ;
+ nPTS |= (p[ 2] & 0xFE) << 14 ;
+ nPTS |= p[ 3] << 7 ;
+ nPTS |= (p[ 4] & 0xFE) >> 1 ;
+ nDTS = (p[ 5] & 0x0E) << 29 ;
+ nDTS |= p[ 6] << 22 ;
+ nDTS |= (p[ 7] & 0xFE) << 14 ;
+ nDTS |= p[ 8] << 7 ;
+ nDTS |= (p[ 9] & 0xFE) >> 1 ;
+ p += 10;
+ nPacketLen -= 10;
+ } else {
+ p++;
+ nPacketLen --;
+ }
+
+ } else { /* mpeg 2 */
+
+ if (p[7] & 0x80) { /* PTS avail */
+
+ nPTS = (p[ 9] & 0x0E) << 29 ;
+ nPTS |= p[10] << 22 ;
+ nPTS |= (p[11] & 0xFE) << 14 ;
+ nPTS |= p[12] << 7 ;
+ nPTS |= (p[13] & 0xFE) >> 1 ;
+
+ } else
+ nPTS = 0;
+
+ if (p[7] & 0x40) { /* PTS avail */
+
+ nDTS = (p[14] & 0x0E) << 29 ;
+ nDTS |= p[15] << 22 ;
+ nDTS |= (p[16] & 0xFE) << 14 ;
+ nDTS |= p[17] << 7 ;
+ nDTS |= (p[18] & 0xFE) >> 1 ;
+
+ } else
+ nDTS = 0;
+
+
+ nHeaderLen = p[8];
+
+ p += nHeaderLen + 9;
+ nPacketLen -= nHeaderLen + 3;
+ }
+
+ xprintf (VERBOSE|DEMUX, "stream_id=%x len=%d pts=%d dts=%d\n", nStreamID, nPacketLen, nPTS, nDTS);
+
+ if (nStreamID == 0xbd) {
+
+ int nTrack, nSPUID;
+
+ nTrack = p[0] & 0x0F; /* hack : ac3 track */
+
+ if((p[0] & 0xE0) == 0x20) {
+ nSPUID = (p[0] & 0x1f);
+
+ xprintf(VERBOSE|DEMUX, "SPU PES packet, id 0x%03x\n",p[0] & 0x1f);
+
+ buf->content = p+1;
+ buf->size = nPacketLen-1;
+ buf->type = BUF_SPU_PACKAGE + nSPUID;
+ buf->PTS = nPTS;
+ buf->DTS = nDTS ;
+ buf->input_pos = this->input->seek (0, SEEK_CUR);
+
+ this->spu_fifo->put (this->spu_fifo, buf);
+
+ return;
+ }
+
+ if ((p[0]&0xF0) == 0x80) {
+
+ xprintf (VERBOSE|DEMUX|AC3, "ac3 PES packet, track %02x\n",nTrack);
+ /* printf ( "ac3 PES packet, track %02x\n",nTrack); */
+
+ buf->content = p+4;
+ buf->size = nPacketLen-4;
+ buf->type = BUF_AUDIO_AC3 + nTrack;
+ buf->PTS = nPTS;
+ buf->DTS = nDTS ;
+ buf->input_pos = this->input->seek (0, SEEK_CUR);
+
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ return ;
+ } else if ((p[0]&0xf0) == 0xa0) {
+
+ int pcm_offset;
+
+ xprintf (VERBOSE|DEMUX,"LPCMacket, len : %d %02x\n",nPacketLen-4, p[0]);
+
+ for( pcm_offset=0; ++pcm_offset < nPacketLen-1 ; ){
+ if ( p[pcm_offset] == 0x01 && p[pcm_offset+1] == 0x80 ) { /* START */
+ pcm_offset += 2;
+ break;
+ }
+ }
+
+ buf->content = p+pcm_offset;
+ buf->size = nPacketLen-pcm_offset;
+ buf->type = BUF_AUDIO_LPCM + nTrack;
+ buf->PTS = nPTS;
+ buf->DTS = nDTS ;
+ buf->input_pos = this->input->seek (0, SEEK_CUR);
+
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ return ;
+ }
+
+ } else if ((nStreamID >= 0xbc) && ((nStreamID & 0xf0) == 0xe0)) {
+
+ xprintf (VERBOSE|DEMUX, "video %d\n", nStreamID);
+
+ buf->content = p;
+ buf->size = nPacketLen;
+ buf->type = BUF_VIDEO_MPEG;
+ buf->PTS = nPTS;
+ buf->DTS = nDTS;
+ buf->input_pos = this->input->seek (0, SEEK_CUR);
+
+ this->video_fifo->put (this->video_fifo, buf);
+
+ return ;
+
+ } else if ((nStreamID & 0xe0) == 0xc0) {
+ int nTrack;
+
+ nTrack = nStreamID & 0x1f;
+
+ xprintf (VERBOSE|DEMUX|MPEG, "mpg audio #%d", nTrack);
+
+ buf->content = p;
+ buf->size = nPacketLen;
+ buf->type = BUF_AUDIO_MPEG + nTrack;
+ buf->PTS = nPTS;
+ buf->DTS = nDTS;
+ buf->input_pos = this->input->seek (0, SEEK_CUR);
+
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ return ;
+
+ } else {
+ xprintf (VERBOSE | DEMUX, "unknown packet, id = %x\n",nStreamID);
+ }
+
+ buf->free_buffer (buf);
+
+ return ;
+
+}
+
+static void *demux_mpeg_block_loop (void *this_gen) {
+
+ buf_element_t *buf;
+ demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen;
+
+ do {
+
+ demux_mpeg_block_parse_pack(this);
+
+ } while (this->status == DEMUX_OK) ;
+
+ xprintf (VERBOSE|DEMUX, "demux loop finished (status: %d)\n",
+ this->mnStatus);
+
+ this->status = DEMUX_FINISHED;
+
+ buf = this->video_fifo->buffer_pool_alloc ();
+ buf->type = BUF_CONTROL_END;
+ this->video_fifo->put (this->video_fifo, buf);
+
+ buf = this->audio_fifo->buffer_pool_alloc ();
+ buf->type = BUF_CONTROL_END;
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ return NULL;
+}
+
+static void demux_mpeg_block_stop (demux_plugin_t *this_gen) {
+
+ demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen;
+ void *p;
+
+ this->status = DEMUX_FINISHED;
+
+ pthread_join (this->thread, &p);
+}
+
+static int demux_mpeg_block_get_status (demux_plugin_t *this_gen) {
+ demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen;
+
+ return this->status;
+}
+
+static void demux_mpeg_block_start (demux_plugin_t *this_gen,
+ fifo_buffer_t *video_fifo,
+ fifo_buffer_t *audio_fifo,
+ fifo_buffer_t *spu_fifo,
+ off_t pos)
+{
+
+ demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen;
+ buf_element_t *buf;
+
+ this->video_fifo = video_fifo;
+ this->audio_fifo = audio_fifo;
+ this->spu_fifo = spu_fifo;
+
+ this->status = DEMUX_OK;
+
+ pos /= (off_t) this->blocksize;
+ pos *= (off_t) this->blocksize;
+
+ if((this->input->get_capabilities() & INPUT_CAP_SEEKABLE) != 0) {
+ xprintf (VERBOSE|DEMUX, "=>seek to %Ld\n",pos);
+ this->input->seek (pos, SEEK_SET);
+ }
+
+ /*
+ * send start buffer
+ */
+
+ buf = this->video_fifo->buffer_pool_alloc ();
+ buf->type = BUF_CONTROL_START;
+ this->video_fifo->put (this->video_fifo, buf);
+ buf = this->audio_fifo->buffer_pool_alloc ();
+ buf->type = BUF_CONTROL_START;
+ this->audio_fifo->put (this->audio_fifo, buf);
+
+ /*
+ * now start demuxing
+ */
+
+ pthread_create (&this->thread, NULL, demux_mpeg_block_loop, this) ;
+}
+
+static int demux_mpeg_block_open(demux_plugin_t *this_gen,
+ input_plugin_t *input, int stage) {
+
+ demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen;
+
+ this->input = input;
+
+ switch(stage) {
+
+ case STAGE_BY_CONTENT: {
+ uint8_t buf[4096];
+
+ if((input->get_capabilities() & INPUT_CAP_SEEKABLE) != 0) {
+ input->seek(0, SEEK_SET);
+
+ this->blocksize = input->get_blocksize();
+
+ if (!this->blocksize)
+ return DEMUX_CANNOT_HANDLE;
+
+ if (input->read(buf, this->blocksize)) {
+
+ if(buf[0] || buf[1] || (buf[2] != 0x01))
+ return DEMUX_CANNOT_HANDLE;
+
+ switch(buf[3]) {
+
+ case 0xba:
+ if((buf[4] & 0xc0) == 0x40)
+ return DEMUX_CAN_HANDLE;
+
+ break;
+
+ case 0xe0:
+ if((buf[6] & 0xc0) == 0x80)
+ return DEMUX_CAN_HANDLE;
+
+ break;
+
+ }
+ }
+ }
+ return DEMUX_CANNOT_HANDLE;
+ }
+ break;
+
+ case STAGE_BY_EXTENSION: {
+ char *media;
+ char *ending;
+ char *MRL;
+
+ MRL = input->get_mrl ();
+
+ media = strstr(MRL, "://");
+ if(media) {
+ if(!strncmp(MRL, "dvd", 3)
+ || !strncmp(MRL, "fifo", 4)
+ || (((!strncmp(MRL, "stdin", 5) || !strncmp(MRL, "fifo", 4))
+ && (!strncmp((media+3), "mpeg2", 5) )))
+ ) {
+ this->blocksize = 2048;
+ return DEMUX_CAN_HANDLE;
+ }
+ if(!strncmp(MRL, "vcd", 3)) {
+ this->blocksize = 2324;
+ return DEMUX_CAN_HANDLE;
+ }
+ }
+
+ /*
+ * check ending
+ */
+
+ ending = strrchr(MRL, '.');
+
+ xprintf(VERBOSE|DEMUX, "demux_mpeg_block_can_handle: ending %s of %s\n",
+ ending ? ending :"(none)", MRL);
+
+ if(!ending)
+ return DEMUX_CANNOT_HANDLE;
+
+ if(!strcasecmp(ending, ".vob")) {
+ this->blocksize = 2048;
+ return DEMUX_CAN_HANDLE;
+ }
+ }
+ break;
+
+ default:
+ return DEMUX_CANNOT_HANDLE;
+ break;
+ }
+
+ return DEMUX_CANNOT_HANDLE;
+}
+
+static char *demux_mpeg_block_get_id(demux_plugin_t *this) {
+ return "MPEG_BLOCK";
+}
+
+static void demux_mpeg_block_close (demux_plugin_t *this) {
+ /* nothing */
+}
+
+demux_plugin_t *init_demux_mpeg_block(config_values_t *cfg, uint32_t xd) {
+
+ demux_mpeg_block_t *this = xmalloc (sizeof (demux_mpeg_block_t));
+
+ xine_debug = xd;
+
+ this->demux_plugin.open = demux_mpeg_block_open;
+ this->demux_plugin.start = demux_mpeg_block_start;
+ this->demux_plugin.stop = demux_mpeg_block_stop;
+ this->demux_plugin.close = demux_mpeg_block_close;
+ this->demux_plugin.get_status = demux_mpeg_block_get_status;
+ this->demux_plugin.get_identifier = demux_mpeg_block_get_id;
+
+ return (demux_plugin_t *) this;
+}
diff --git a/src/demuxers/demux_mpgaudio.c b/src/demuxers/demux_mpgaudio.c
new file mode 100644
index 000000000..8eea5bddf
--- /dev/null
+++ b/src/demuxers/demux_mpgaudio.c
@@ -0,0 +1,440 @@
+/*
+ * Copyright (C) 2000 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: demux_mpgaudio.c,v 1.1 2001/04/18 22:33:58 f1rmb Exp $
+ *
+ * demultiplexer for mpeg audio (i.e. mp3) streams
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "xine.h"
+#include "monitor.h"
+#include "demux.h"
+
+#include "libmpg123/mpg123.h"
+#include "libmpg123/mpglib.h"
+
+/* The following variable indicates the kind of error */
+
+static uint32_t xine_debug;
+
+typedef struct _demux_mpgaudio_globals {
+ fifo_buffer_t *mBufAudio;
+ fifo_buffer_t *mBufVideo;
+
+ input_plugin_t *mInput;
+
+ pthread_t mThread;
+
+ int mnStatus;
+} demux_mpgaudio_globals_t ;
+
+static demux_mpgaudio_globals_t gDemuxMpgAudio;
+static fifobuf_functions_t *Ffb;
+
+/*
+ * ***********************************************************************
+ * Adds some (very slightly hacked) parts of libmpg123 here:
+ * I don't want to link the lib to this demuxer.
+ */
+static int ssize;
+static int grp_3tab[32 * 3] = {0,};
+static int grp_5tab[128 * 3] = {0,};
+static int grp_9tab[1024 * 3] = {0,};
+static real mpg123_muls[27][64];
+static int tabsel_123[2][3][16] = {
+ {
+ {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
+ {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
+ {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}},
+
+ {
+ {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
+ {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
+ {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}}
+};
+static long mpg123_freqs[9] = {
+ 44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000
+};
+/*
+ *
+ */
+static void mpg123_init_layer2(void) {
+ static double mulmul[27] = {
+ 0.0, -2.0 / 3.0, 2.0 / 3.0,
+ 2.0 / 7.0, 2.0 / 15.0, 2.0 / 31.0, 2.0 / 63.0, 2.0 / 127.0, 2.0 / 255.0,
+ 2.0 / 511.0, 2.0 / 1023.0, 2.0 / 2047.0, 2.0 / 4095.0, 2.0 / 8191.0,
+ 2.0 / 16383.0, 2.0 / 32767.0, 2.0 / 65535.0,
+ -4.0 / 5.0, -2.0 / 5.0, 2.0 / 5.0, 4.0 / 5.0,
+ -8.0 / 9.0, -4.0 / 9.0, -2.0 / 9.0, 2.0 / 9.0, 4.0 / 9.0, 8.0 / 9.0
+ };
+ static int base[3][9] = {
+ {1, 0, 2,},
+ {17, 18, 0, 19, 20,},
+ {21, 1, 22, 23, 0, 24, 25, 2, 26}
+ };
+ int i, j, k, l, len;
+ real *table;
+ static int tablen[3] = { 3, 5, 9 };
+ static int *itable, *tables[3] = { grp_3tab, grp_5tab, grp_9tab };
+
+ for (i = 0; i < 3; i++) {
+ itable = tables[i];
+ len = tablen[i];
+ for (j = 0; j < len; j++)
+ for (k = 0; k < len; k++)
+ for (l = 0; l < len; l++) {
+ *itable++ = base[i][l];
+ *itable++ = base[i][k];
+ *itable++ = base[i][j];
+ }
+ }
+
+ for (k = 0; k < 27; k++) {
+ double m = mulmul[k];
+
+ table = mpg123_muls[k];
+ for (j = 3, i = 0; i < 63; i++, j--)
+ *table++ = m * pow(2.0, (double) j / 3.0);
+ *table++ = 0.0;
+ }
+}
+/*
+ *
+ */
+static int mpg123_decode_header(struct frame *fr, unsigned long newhead) {
+ if (newhead & (1 << 20)) {
+ fr->lsf = (newhead & (1 << 19)) ? 0x0 : 0x1;
+ fr->mpeg25 = 0;
+ }
+ else {
+ fr->lsf = 1;
+ fr->mpeg25 = 1;
+ }
+ fr->lay = 4 - ((newhead >> 17) & 3);
+ if (fr->mpeg25) {
+ fr->sampling_frequency = 6 + ((newhead >> 10) & 0x3);
+ }
+ else
+ fr->sampling_frequency = ((newhead >> 10) & 0x3) + (fr->lsf * 3);
+
+ fr->error_protection = ((newhead >> 16) & 0x1) ^ 0x1;
+
+ if (fr->mpeg25) /* allow Bitrate change for 2.5 ... */
+ fr->bitrate_index = ((newhead >> 12) & 0xf);
+
+ fr->bitrate_index = ((newhead >> 12) & 0xf);
+ fr->padding = ((newhead >> 9) & 0x1);
+ fr->extension = ((newhead >> 8) & 0x1);
+ fr->mode = ((newhead >> 6) & 0x3);
+ fr->mode_ext = ((newhead >> 4) & 0x3);
+ fr->copyright = ((newhead >> 3) & 0x1);
+ fr->original = ((newhead >> 2) & 0x1);
+ fr->emphasis = newhead & 0x3;
+
+ fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
+
+ ssize = 0;
+
+ if (!fr->bitrate_index)
+ return (0);
+
+ switch (fr->lay) {
+ case 1:
+ mpg123_init_layer2(); /* inits also shared tables with layer1 */
+ fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
+ fr->framesize /= mpg123_freqs[fr->sampling_frequency];
+ fr->framesize = ((fr->framesize + fr->padding) << 2) - 4;
+ break;
+ case 2:
+ mpg123_init_layer2(); /* inits also shared tables with layer1 */
+ fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
+ fr->framesize /= mpg123_freqs[fr->sampling_frequency];
+ fr->framesize += fr->padding - 4;
+ break;
+ case 3:
+ if (fr->lsf)
+ ssize = (fr->stereo == 1) ? 9 : 17;
+ else
+ ssize = (fr->stereo == 1) ? 17 : 32;
+ if (fr->error_protection)
+ ssize += 2;
+ fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
+ fr->framesize /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf);
+ fr->framesize = fr->framesize + fr->padding - 4;
+ break;
+ default:
+ return (0);
+ }
+ if(fr->framesize > MAXFRAMESIZE)
+ return 0;
+ return 1;
+}
+/*
+ *
+ */
+static int mpg123_head_check(unsigned long head) {
+ if ((head & 0xffe00000) != 0xffe00000)
+ return 0;
+ if (!((head >> 17) & 3))
+ return 0;
+ if (((head >> 12) & 0xf) == 0xf)
+ return 0;
+ if (!((head >> 12) & 0xf))
+ return 0;
+ if (((head >> 10) & 0x3) == 0x3)
+ return 0;
+ if (((head >> 19) & 1) == 1
+ && ((head >> 17) & 3) == 3
+ && ((head >> 16) & 1) == 1)
+ return 0;
+ if ((head & 0xffff0000) == 0xfffe0000)
+ return 0;
+
+ return 1;
+}
+/*
+ * End of libmpg123 adds.
+ ************************************************************************
+ */
+
+int demux_mpgaudio_next (void) {
+
+ buf_element_t *pBuf;
+
+ pBuf = Ffb->buffer_pool_alloc ();
+
+ pBuf->pContent = pBuf->pMem;
+ pBuf->nDTS = 0 ; /* FIXME ? */
+ pBuf->nPTS = 0 ; /* FIXME ? */
+ pBuf->nSize = gDemuxMpgAudio.mInput->read (pBuf->pMem, 2048) ;
+ pBuf->nType = BUF_MPEGAUDIO; /* FIXME */
+ pBuf->nInputPos = gDemuxMpgAudio.mInput->seek (0, SEEK_CUR);
+
+ Ffb->fifo_buffer_put (gDemuxMpgAudio.mBufAudio, pBuf);
+
+ return (pBuf->nSize==2048);
+}
+
+static void *demux_mpgaudio_loop (void *dummy) {
+
+ buf_element_t *pBuf;
+
+ do {
+ if (!demux_mpgaudio_next())
+ gDemuxMpgAudio.mnStatus = DEMUX_FINISHED;
+
+ } while (gDemuxMpgAudio.mnStatus == DEMUX_OK) ;
+
+ xprintf (VERBOSE|DEMUX, "mpgaudio demux loop finished (status: %d)\n",
+ gDemuxMpgAudio.mnStatus);
+
+ pBuf = Ffb->buffer_pool_alloc ();
+ pBuf->nType = BUF_STREAMEND;
+ Ffb->fifo_buffer_put (gDemuxMpgAudio.mBufVideo, pBuf);
+ pBuf = Ffb->buffer_pool_alloc ();
+ pBuf->nType = BUF_STREAMEND;
+ Ffb->fifo_buffer_put (gDemuxMpgAudio.mBufAudio, pBuf);
+
+ return NULL;
+}
+
+static void demux_mpgaudio_stop (void) {
+ void *p;
+
+ gDemuxMpgAudio.mnStatus = DEMUX_FINISHED;
+
+ Ffb->fifo_buffer_clear(gDemuxMpgAudio.mBufVideo);
+ Ffb->fifo_buffer_clear(gDemuxMpgAudio.mBufAudio);
+
+ pthread_join (gDemuxMpgAudio.mThread, &p);
+}
+
+static int demux_mpgaudio_get_status (void) {
+ return gDemuxMpgAudio.mnStatus;
+}
+
+static void demux_mpgaudio_start (input_plugin_t *input_plugin,
+ fifo_buffer_t *bufVideo,
+ fifo_buffer_t *bufAudio,
+ fifo_buffer_t *bufSPU, off_t pos)
+{
+ buf_element_t *pBuf;
+
+ gDemuxMpgAudio.mInput = input_plugin;
+ gDemuxMpgAudio.mBufVideo = bufVideo;
+ gDemuxMpgAudio.mBufAudio = bufAudio;
+
+ gDemuxMpgAudio.mnStatus = DEMUX_OK;
+
+ if((gDemuxMpgAudio.mInput->get_capabilities() & INPUT_CAP_SEEKABLE) != 0)
+ gDemuxMpgAudio.mInput->seek (pos, SEEK_SET);
+
+ pBuf = Ffb->buffer_pool_alloc ();
+ pBuf->nType = BUF_RESET;
+ Ffb->fifo_buffer_put (gDemuxMpgAudio.mBufVideo, pBuf);
+ pBuf = Ffb->buffer_pool_alloc ();
+ pBuf->nType = BUF_RESET;
+ Ffb->fifo_buffer_put (gDemuxMpgAudio.mBufAudio, pBuf);
+
+ pthread_create (&gDemuxMpgAudio.mThread, NULL, demux_mpgaudio_loop, NULL) ;
+}
+
+static void demux_mpgaudio_select_audio_channel (int nChannel) {
+}
+
+static void demux_mpgaudio_select_spu_channel (int nChannel) {
+}
+
+static int demux_mpgaudio_open(input_plugin_t *ip,
+ const char *MRL, int stage) {
+
+ switch(stage) {
+
+ case STAGE_BY_CONTENT: {
+ uint8_t buf[4096];
+ uint8_t *pbuf;
+ struct frame fr;
+ uint32_t head;
+ int in_buf, i;
+ int bs = 0;
+
+ if(!ip)
+ return DEMUX_CANNOT_HANDLE;
+
+ if((ip->get_capabilities() & INPUT_CAP_SEEKABLE) != 0) {
+ ip->seek(0, SEEK_SET);
+
+ if(ip->get_blocksize)
+ bs = ip->get_blocksize();
+
+ if(bs > 4)
+ return DEMUX_CANNOT_HANDLE;
+
+ if(!bs)
+ bs = 4;
+
+ if(ip->read(buf, bs)) {
+
+ /* Not an AVI ?? */
+ if(buf[0] || buf[1] || (buf[2] != 0x01) || (buf[3] != 0x46)) {
+
+ pbuf = (uint8_t *) malloc(1024);
+ head = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
+
+ while(!mpg123_head_check(head)) {
+
+ in_buf = ip->read(pbuf, 1024);
+
+ if(in_buf == 0) {
+ free(pbuf);
+ return DEMUX_CANNOT_HANDLE;
+ }
+
+ for(i = 0; i < in_buf; i++) {
+ head <<= 8;
+ head |= pbuf[i];
+
+ if(mpg123_head_check(head)) {
+ ip->seek(i+1-in_buf, SEEK_CUR);
+ break;
+ }
+ }
+ }
+ free(pbuf);
+
+ if(decode_header(&fr, head)) {
+
+ if((ip->seek(fr.framesize, SEEK_CUR)) <= 0)
+ return DEMUX_CANNOT_HANDLE;
+
+ if((ip->read(buf, 4)) != 4)
+ return DEMUX_CANNOT_HANDLE;
+ }
+
+ head = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
+
+ if(mpg123_head_check(head) &&
+ (((head >> 8) & 0x1) == 0x0) && (((head >> 6) & 0x3) == 0x1))
+ return DEMUX_CAN_HANDLE;
+ }
+ }
+ }
+ return DEMUX_CANNOT_HANDLE;
+ }
+ break;
+
+ case STAGE_BY_EXTENSION: {
+ char *suffix;
+
+ suffix = strrchr(MRL, '.');
+ xprintf(VERBOSE|DEMUX, "demux_mpgaudio_can_handle: suffix %s of %s\n",
+ suffix, MRL);
+
+ if(!suffix)
+ return DEMUX_CANNOT_HANDLE;
+
+ if(!strcasecmp(suffix, ".mp3")
+ || (!strcasecmp(suffix, ".mp2"))) {
+ return DEMUX_CAN_HANDLE;
+ }
+ }
+ break;
+
+ default:
+ return DEMUX_CANNOT_HANDLE;
+ break;
+ }
+
+ return DEMUX_CANNOT_HANDLE;
+}
+
+static char *demux_mpgaudio_get_id(void) {
+ return "MPEGAUDIO";
+}
+
+static demux_functions_t demux_mpgaudio_functions = {
+ NULL,
+ NULL,
+ demux_mpgaudio_open,
+ demux_mpgaudio_start,
+ demux_mpgaudio_stop,
+ demux_mpgaudio_get_status,
+ demux_mpgaudio_select_audio_channel,
+ demux_mpgaudio_select_spu_channel,
+ demux_mpgaudio_get_id
+};
+
+demux_functions_t *init_demux_mpeg_audio(fifobuf_functions_t *f, uint32_t xd) {
+
+ Ffb = f;
+ xine_debug = xd;
+ return &demux_mpgaudio_functions;
+}
diff --git a/src/input/Makefile.am b/src/input/Makefile.am
new file mode 100644
index 000000000..b30549404
--- /dev/null
+++ b/src/input/Makefile.am
@@ -0,0 +1,72 @@
+##
+## Process this file with automake to produce Makefile.in
+##
+
+#CFLAGS += @GLOBAL_CFLAGS@
+CFLAGS += -D_FILE_OFFSET_BITS=64 -Wall -DXINE_COMPILE
+
+LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic
+
+libdir = $(XINE_PLUGINDIR)
+
+#lib_LTLIBRARIES = input_file.la input_net.la input_dvd.la input_vcd.la \
+# input_stdin_fifo.la
+lib_LTLIBRARIES = input_file.la
+
+#input_dvd_la_SOURCES = input_dvd.c dvd_udf.c
+#input_dvd_la_LDFLAGS = -avoid-version -module -Wl,-soname,input_dvd.so
+#input_dvd_la_LIBADD =
+
+input_file_la_SOURCES = input_file.c
+input_file_la_LDFLAGS = -avoid-version -module -Wl,-soname,input_file.so
+input_file_la_LIBADD =
+
+#input_net_la_SOURCES = input_net.c
+#input_net_la_LDFLAGS = -avoid-version -module -Wl,-soname,input_net.so
+#input_net_la_LIBADD =
+
+#input_vcd_la_SOURCES = input_vcd.c
+#input_vcd_la_LDFLAGS = -avoid-version -module -Wl,-soname,input_vcd.so
+#input_vcd_la_LIBADD =
+
+#input_stdin_fifo_la_SOURCES = input_stdin_fifo.c
+#input_stdin_fifo_la_LDFLAGS = -avoid-version -module -Wl,-soname,input_stdin_fifo.so
+
+
+include_HEADERS = input_plugin.h
+noinst_HEADERS = dvd_udf.h
+
+
+##
+## Install header files (default=$includedir/xine)
+##
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)/xine
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p; \
+ done
+
+
+##
+## Remove them
+##
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/xine/$$p; \
+ done
+
+
+debug:
+ $(MAKE) CFLAGS="-D_FILE_OFFSET_BITS=64 -Wall -DDEBUG -g"
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/input/dvd_udf.c b/src/input/dvd_udf.c
new file mode 100644
index 000000000..e2a0692b4
--- /dev/null
+++ b/src/input/dvd_udf.c
@@ -0,0 +1,661 @@
+/*
+ * dvdudf: parse and read the UDF volume information of a DVD Video
+ * Copyright (C) 1999 Christian Wolff for convergence integrated media GmbH
+ * minor modifications by Thomas Mirlacher
+ * dir support and bugfixes by Guenter Bartsch for use in xine
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ * The author can be reached at scarabaeus@convergence.de,
+ * the project's page is at http://linuxtv.org/dvd/
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include "dvd_udf.h"
+
+static int _Unicodedecode (uint8_t *data, int len, char *target);
+
+#define MAX_FILE_LEN 2048
+
+struct Partition {
+ int valid;
+ uint8_t VolumeDesc[128];
+ uint16_t Flags;
+ uint16_t Number;
+ uint8_t Contents[32];
+ uint32_t AccessType;
+ uint32_t Start;
+ uint32_t Length;
+} partition;
+
+struct AD {
+ uint32_t Location;
+ uint32_t Length;
+ uint8_t Flags;
+ uint16_t Partition;
+};
+
+/* for direct data access, LSB first */
+#define GETN1(p) ((uint8_t)data[p])
+#define GETN2(p) ((uint16_t)data[p]|((uint16_t)data[(p)+1]<<8))
+#define GETN4(p) ((uint32_t)data[p]|((uint32_t)data[(p)+1]<<8)|((uint32_t)data[(p)+2]<<16)|((uint32_t)data[(p)+3]<<24))
+#define GETN(p,n,target) memcpy(target,&data[p],n)
+
+
+/*
+ * reads absolute Logical Block of the disc
+ * returns number of read bytes on success, 0 on error
+ */
+
+int UDFReadLB (int fd, off_t lb_number, size_t block_count, uint8_t *data)
+{
+ if (fd < 0)
+ return 0;
+
+ if (lseek (fd, lb_number * (off_t) DVD_VIDEO_LB_LEN, SEEK_SET) < 0)
+ return 0; /* position not found */
+
+ return read (fd, data, block_count*DVD_VIDEO_LB_LEN);
+}
+
+
+static int _Unicodedecode (uint8_t *data, int len, char *target)
+{
+ int p=1,i=0;
+
+ if (!(data[0] & 0x18)) {
+ target[0] ='\0';
+ return 0;
+ }
+
+ if (data[0] & 0x10) { /* ignore MSB of unicode16 */
+ p++;
+
+ while (p<len)
+ target[i++]=data[p+=2];
+ } else {
+ while (p<len)
+ target[i++]=data[p++];
+ }
+
+ target[i]='\0';
+
+ return 0;
+}
+
+
+int UDFEntity (uint8_t *data, uint8_t *Flags, char *Identifier)
+{
+ Flags[0] = data[0];
+ strncpy (Identifier, &data[1], 5);
+
+ return 0;
+}
+
+
+int UDFDescriptor (uint8_t *data, uint16_t *TagID)
+{
+ TagID[0] = GETN2(0);
+ /* TODO: check CRC n stuff */
+
+ return 0;
+}
+
+
+int UDFExtentAD (uint8_t *data, uint32_t *Length, uint32_t *Location)
+{
+ Length[0] =GETN4(0);
+ Location[0]=GETN4(4);
+
+ return 0;
+}
+
+#define UDFADshort 1
+#define UDFADlong 2
+#define UDFADext 4
+
+int UDFAD (uint8_t *data, struct AD *ad, uint8_t type)
+{
+ ad->Length = GETN4(0);
+ ad->Flags = ad->Length>>30;
+ ad->Length &= 0x3FFFFFFF;
+
+ switch (type) {
+ case UDFADshort:
+ ad->Location = GETN4(4);
+ ad->Partition = partition.Number; /* use number of current partition */
+ break;
+ case UDFADlong:
+ ad->Location = GETN4(4);
+ ad->Partition = GETN2(8);
+ break;
+ case UDFADext:
+ ad->Location = GETN4(12);
+ ad->Partition = GETN2(16);
+ break;
+ }
+
+ return 0;
+}
+
+int UDFICB (uint8_t *data, uint8_t *FileType, uint16_t *Flags)
+{
+ FileType[0]=GETN1(11);
+ Flags[0]=GETN2(18);
+
+ return 0;
+}
+
+int UDFPartition (uint8_t *data, uint16_t *Flags, uint16_t *Number, char *Contents,
+ uint32_t *Start, uint32_t *Length)
+{
+ Flags[0] = GETN2(20);
+ Number[0] = GETN2(22);
+ GETN(24,32,Contents);
+ Start[0] = GETN4(188);
+ Length[0] = GETN4(192);
+
+ return 0;
+}
+
+
+/*
+ * reads the volume descriptor and checks the parameters
+ * returns 0 on OK, 1 on error
+ */
+
+int UDFLogVolume (uint8_t *data, char *VolumeDescriptor)
+{
+ uint32_t lbsize,MT_L,N_PM;
+
+ _Unicodedecode (&data[84],128,VolumeDescriptor);
+ lbsize = GETN4(212); /* should be 2048 */
+ MT_L = GETN4(264); /* should be 6 */
+ N_PM = GETN4(268); /* should be 1 */
+
+ if (lbsize!=DVD_VIDEO_LB_LEN)
+ return 1;
+
+ return 0;
+}
+
+
+int UDFFileEntry (uint8_t *data, uint8_t *FileType, struct AD *ad)
+{
+ uint8_t filetype;
+ uint16_t flags;
+ uint32_t L_EA,L_AD;
+ int p;
+
+ UDFICB(&data[16],&filetype,&flags);
+ FileType[0]=filetype;
+ L_EA=GETN4(168);
+ L_AD=GETN4(172);
+ p=176+L_EA;
+
+ while (p<176+L_EA+L_AD) {
+ switch (flags&0x07) {
+ case 0:
+ UDFAD (&data[p], ad, UDFADshort);
+ p += 0x08;
+ break;
+ case 1:
+ UDFAD (&data[p], ad, UDFADlong);
+ p += 0x10;
+ break;
+ case 2: UDFAD (&data[p], ad, UDFADext);
+ p += 0x14;
+ break;
+ case 3:
+ switch (L_AD) {
+ case 0x08:
+ UDFAD (&data[p], ad, UDFADshort);
+ break;
+ case 0x10:
+ UDFAD (&data[p], ad, UDFADlong);
+ break;
+ case 0x14:
+ UDFAD (&data[p], ad, UDFADext);
+ break;
+ }
+ default:
+ p += L_AD;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+
+int UDFFileIdentifier (uint8_t *data, uint8_t *FileCharacteristics, char *FileName, struct AD *FileICB)
+{
+ uint8_t L_FI;
+ uint16_t L_IU;
+
+ FileCharacteristics[0]=GETN1(18);
+ L_FI=GETN1(19);
+ UDFAD(&data[20],FileICB,UDFADlong);
+ L_IU=GETN2(36);
+
+ if (L_FI)
+ _Unicodedecode (&data[38+L_IU],L_FI,FileName);
+ else
+ FileName[0]='\0';
+
+ return 4*((38+L_FI+L_IU+3)/4);
+}
+
+
+/*
+ * Maps ICB to FileAD
+ * ICB: Location of ICB of directory to scan
+ * FileType: Type of the file
+ * File: Location of file the ICB is pointing to
+ * return 1 on success, 0 on error;
+ */
+
+int UDFMapICB (int fd, struct AD ICB, uint8_t *FileType, struct AD *File)
+{
+ uint8_t *LogBlock;
+ uint32_t lbnum;
+ uint16_t TagID;
+
+ if ((LogBlock = (uint8_t*)malloc(DVD_VIDEO_LB_LEN)) == NULL) {
+ fprintf(stderr, "%s: malloc failed\n", __FUNCTION__);
+ return 0;
+ }
+
+ lbnum=partition.Start+ICB.Location;
+
+ do {
+ if (!UDFReadLB(fd, lbnum++,1,LogBlock)) TagID=0;
+ else UDFDescriptor(LogBlock,&TagID);
+
+ if (TagID==261) {
+ UDFFileEntry(LogBlock,FileType,File);
+ free(LogBlock);
+ return 1;
+ };
+ } while ((lbnum<=partition.Start+ICB.Location+(ICB.Length-1)/DVD_VIDEO_LB_LEN) && (TagID!=261));
+
+ free(LogBlock);
+ return 0;
+}
+
+/*
+ * Dir: Location of directory to scan
+ * FileName: Name of file to look for
+ * FileICB: Location of ICB of the found file
+ * return 1 on success, 0 on error;
+ */
+
+int UDFScanDir (int fd, struct AD Dir, char *FileName, struct AD *FileICB)
+{
+ uint8_t *LogBlock;
+ uint32_t lbnum, lb_dir_end, offset;
+ uint16_t TagID;
+ uint8_t filechar;
+ char *filename;
+ int p, retval = 0;
+
+ LogBlock = (uint8_t*)malloc(DVD_VIDEO_LB_LEN * 30);
+ filename = (char*)malloc(MAX_FILE_LEN);
+ if ((LogBlock == NULL) || (filename == NULL)) {
+ fprintf(stderr, "%s: malloc failed\n", __FUNCTION__);
+ goto bail;
+ }
+
+ /*
+ * read complete directory
+ */
+
+ lbnum = partition.Start+Dir.Location;
+ lb_dir_end = partition.Start+Dir.Location+(Dir.Length-1)/DVD_VIDEO_LB_LEN;
+ offset = 0;
+
+ while (lbnum<=lb_dir_end) {
+
+ if (!UDFReadLB(fd, lbnum++,1,&LogBlock[offset]))
+ break;
+
+ offset += DVD_VIDEO_LB_LEN;
+ }
+
+ /* Scan dir for ICB of file */
+
+ p=0;
+ while (p<offset) {
+ UDFDescriptor (&LogBlock[p],&TagID);
+
+ if (TagID==257) {
+ p += UDFFileIdentifier(&LogBlock[p],&filechar,filename,FileICB);
+ if (!strcasecmp (FileName,filename)) {
+ retval = 1;
+ goto bail;
+ }
+ } else
+ p=offset;
+ }
+
+ retval = 0;
+
+bail:
+ free(LogBlock);
+ free(filename);
+ return retval;
+}
+
+
+/*
+ * looks for partition on the disc
+ * partnum: number of the partition, starting at 0
+ * part: structure to fill with the partition information
+ * return 1 if partition found, 0 on error;
+ */
+
+int UDFFindPartition (int fd, int partnum, struct Partition *part)
+{
+ uint8_t *LogBlock,*Anchor;
+ uint32_t lbnum,MVDS_location,MVDS_length;
+ uint16_t TagID;
+ uint32_t lastsector;
+ int i,terminate,volvalid,retval = 0;
+
+ LogBlock = (uint8_t*)malloc(DVD_VIDEO_LB_LEN);
+ Anchor = (uint8_t*)malloc(DVD_VIDEO_LB_LEN);
+ if ((LogBlock == NULL) || (Anchor == NULL)) {
+ fprintf(stderr, "%s: malloc failed\n", __FUNCTION__);
+ goto bail;
+ }
+
+ /* find anchor */
+ lastsector=0;
+ lbnum=256; /* try #1, prime anchor */
+ terminate=0;
+
+ while (1) { /* loop da loop */
+ if (UDFReadLB(fd, lbnum,1,Anchor)) {
+ UDFDescriptor(Anchor,&TagID);
+ } else
+ TagID=0;
+
+ if (TagID!=2) { /* not an anchor? */
+ if (terminate) goto bail; /* final try failed */
+ if (lastsector) { /* we already found the last sector */
+ lbnum=lastsector; /* try #3, alternative backup anchor */
+ terminate=1; /* but thats just about enough, then! */
+ } else {
+ /* TODO: find last sector of the disc (this is optional) */
+ if (lastsector) lbnum=lastsector-256; /* try #2, backup anchor */
+ else goto bail; /* unable to find last sector */
+ }
+ } else break; /* it is an anchor! continue... */
+ }
+
+ UDFExtentAD(&Anchor[16],&MVDS_length,&MVDS_location); /* main volume descriptor */
+
+ part->valid=0;
+ volvalid=0;
+ part->VolumeDesc[0]='\0';
+
+ i=1;
+ do {
+ /* Find Volume Descriptor */
+ lbnum=MVDS_location;
+ do {
+ if (!UDFReadLB (fd, lbnum++, 1, LogBlock))
+ TagID=0;
+ else
+ UDFDescriptor (LogBlock, &TagID);
+ if ((TagID==5) && (!part->valid)) { /* Partition Descriptor */
+ UDFPartition (LogBlock,&part->Flags,&part->Number,part->Contents,
+ &part->Start,&part->Length);
+ part->valid=(partnum==part->Number);
+ } else if ((TagID==6) && (!volvalid)) { /* Logical Volume Descriptor */
+ if (UDFLogVolume(LogBlock,part->VolumeDesc)) {
+ /* TODO: sector size wrong! */
+ } else volvalid=1;
+ }
+ } while ((lbnum<=MVDS_location+(MVDS_length-1)/DVD_VIDEO_LB_LEN) && (TagID!=8) && ((!part->valid) || (!volvalid)));
+ if ((!part->valid) || (!volvalid)) UDFExtentAD(&Anchor[24],&MVDS_length,&MVDS_location); /* backup volume descriptor */
+ } while (i-- && ((!part->valid) || (!volvalid)));
+
+ retval = part->valid; /* we only care for the partition, not the volume */
+
+bail:
+ free(LogBlock);
+ free(Anchor);
+ return retval;
+}
+
+
+/*
+ * looks for a file on the UDF disc/imagefile and seeks to it's location
+ * filename has to be the absolute pathname on the UDF filesystem,
+ * starting with '/'
+ * returns absolute LB number, or 0 on error
+ */
+
+uint32_t UDFFindFile (int fd, char *filename, off_t *size)
+{
+ uint8_t *LogBlock;
+ uint8_t filetype;
+ uint32_t lbnum, retval = 0;
+ uint16_t TagID;
+ struct AD RootICB,File,ICB;
+ char *tokenline;
+ char *token;
+ off_t lb_number;
+ int Partition=0; /* this is the standard location for DVD Video */
+
+ LogBlock = (uint8_t*)malloc(DVD_VIDEO_LB_LEN);
+ tokenline = (char*)malloc(MAX_FILE_LEN);
+ if ((LogBlock == NULL) || (tokenline == NULL)) {
+ fprintf(stderr, "%s: malloc failed\n", __FUNCTION__);
+ goto bail;
+ }
+ memset(tokenline, 0, MAX_FILE_LEN);
+
+ strncat (tokenline,filename,MAX_FILE_LEN);
+
+ /* Find partition */
+ if (!UDFFindPartition(fd, Partition,&partition))
+ goto bail;
+
+ /* Find root dir ICB */
+ lbnum=partition.Start;
+
+ do {
+ if (!UDFReadLB(fd, lbnum++,1,LogBlock))
+ TagID=0;
+ else
+ UDFDescriptor(LogBlock,&TagID);
+
+ if (TagID==256) /* File Set Descriptor */
+ UDFAD(&LogBlock[400],&RootICB,UDFADlong);
+ } while ((lbnum<partition.Start+partition.Length) && (TagID!=8) && (TagID!=256));
+ if (TagID!=256)
+ goto bail;
+ if (RootICB.Partition!=Partition)
+ goto bail;
+
+ /* Find root dir */
+ if (!UDFMapICB(fd, RootICB,&filetype,&File))
+ goto bail;
+ if (filetype!=4) /* root dir should be dir */
+ goto bail;
+
+ /* Tokenize filepath */
+ token=strtok(tokenline,"/");
+ while (token) {
+ if (!UDFScanDir(fd, File,token,&ICB))
+ goto bail;
+ if (!UDFMapICB(fd, ICB,&filetype,&File))
+ goto bail;
+ token=strtok(NULL,"/");
+ }
+
+ *size = File.Length;
+
+ lb_number = partition.Start+File.Location ;
+
+ printf ("lb_number : %ld\n", (long int)lb_number);
+
+ retval = lb_number;
+
+bail:
+ free(LogBlock);
+ free(tokenline);
+ return retval;
+}
+
+
+/*
+ * lists contents of given directory
+ */
+
+void UDFListDir(int fd, char *dirname, int nMaxFiles, char **file_list, int *nFiles) {
+ uint8_t *LogBlock;
+ uint32_t lbnum;
+ uint16_t TagID;
+ struct AD RootICB,Dir,ICB;
+ char *tokenline;
+ char *token, *ntoken;
+ uint8_t filetype;
+ char *filename;
+ int p;
+ uint8_t filechar;
+ char *dest;
+ int Partition=0; /* this is the standard location for DVD Video */
+
+ LogBlock = (uint8_t*)malloc(DVD_VIDEO_LB_LEN * 30);
+ tokenline = (char*)malloc(MAX_FILE_LEN);
+ filename = (char*)malloc(MAX_FILE_LEN);
+ if ((LogBlock == NULL) || (tokenline == NULL) || (filename == NULL)) {
+ fprintf(stderr, "%s: malloc failed\n", __FUNCTION__);
+ goto bail;
+ }
+
+ *nFiles = 0;
+ tokenline[0]='\0';
+ strncat(tokenline,dirname,MAX_FILE_LEN);
+
+ /* Find partition */
+ if (!UDFFindPartition(fd, Partition,&partition))
+ goto bail; /* no partition found (no disc ??) */
+
+ /* Find root dir ICB */
+ lbnum=partition.Start;
+ do {
+ if (!UDFReadLB(fd, lbnum++,1,LogBlock))
+ TagID=0;
+ else
+ UDFDescriptor(LogBlock,&TagID);
+
+ if (TagID==256) { // File Set Descriptor
+ UDFAD(&LogBlock[400],&RootICB,UDFADlong);
+ }
+ } while ((lbnum<partition.Start+partition.Length)
+ && (TagID!=8) && (TagID!=256));
+
+ if (TagID!=256)
+ goto bail;
+ if (RootICB.Partition!=Partition)
+ goto bail;
+
+ /* Find root dir */
+ if (!UDFMapICB(fd, RootICB,&filetype,&Dir))
+ goto bail;
+ if (filetype!=4)
+ goto bail; /* root dir should be dir */
+
+
+
+ /* Tokenize filepath */
+ token=strtok(tokenline,"/");
+ ntoken=strtok(NULL,"/");
+ while (token != NULL) {
+
+ if (!UDFScanDir(fd, Dir,token,&ICB))
+ goto bail;
+ if (!UDFMapICB(fd, ICB,&filetype,&Dir))
+ goto bail;
+
+ if (ntoken == NULL) {
+ uint32_t lb_dir_end, offset;
+
+ /*
+ * read complete directory
+ */
+
+ lbnum = partition.Start+Dir.Location;
+ lb_dir_end = partition.Start+Dir.Location+(Dir.Length-1)/DVD_VIDEO_LB_LEN;
+ offset = 0;
+
+ while (lbnum<=lb_dir_end) {
+
+ if (!UDFReadLB(fd, lbnum++,1,&LogBlock[offset]))
+ break;
+
+ offset += DVD_VIDEO_LB_LEN;
+ }
+
+
+ p=0;
+ while (p<offset) {
+ UDFDescriptor(&LogBlock[p],&TagID);
+ /* printf ("tagid : %d\n",TagID); */
+ if (TagID==257) {
+ p+=UDFFileIdentifier(&LogBlock[p],&filechar,filename,&ICB);
+
+ /* printf ("file : >%s< %d (p: %d)\n", filename, *nFiles,p); */
+
+ if (strcmp (filename,"")) {
+
+ dest = file_list[*nFiles];
+ strncpy (dest,filename,256);
+ (*nFiles)++;
+
+ if ((*nFiles)>=nMaxFiles)
+ goto bail;
+
+ }
+
+ } else {
+ p=offset;
+ }
+ }
+
+ }
+
+ token=ntoken;
+ ntoken=strtok(NULL,"/");
+ }
+
+bail:
+ free(LogBlock);
+ free(tokenline);
+ free(filename);
+ return;
+}
+
diff --git a/src/input/dvd_udf.h b/src/input/dvd_udf.h
new file mode 100644
index 000000000..5db31b1fc
--- /dev/null
+++ b/src/input/dvd_udf.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2000-2001 plitsch-platsch
+ *
+ * xine_dvd_plugin is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine_dvd_plugin is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ */
+
+#ifndef DVD_UDF_H
+#define DVD_UDF_H
+
+#include <inttypes.h>
+
+#define DVD_UDF_VERSION 19991115
+
+/*
+ * The length of one Logical Block of a DVD Video
+ */
+
+#define DVD_VIDEO_LB_LEN 2048
+
+int UDFReadLB (int fd, off_t lb_number, size_t block_count, uint8_t *data);
+
+uint32_t UDFFindFile(int fd, char *filename, off_t *size);
+
+void UDFListDir(int fd, char *dirname, int nMaxFiles, char **file_list, int *nFiles) ;
+
+#endif /* DVD_UDF_H */
diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c
new file mode 100644
index 000000000..b3f105bbd
--- /dev/null
+++ b/src/input/input_dvd.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: input_dvd.c,v 1.1 2001/04/18 22:34:04 f1rmb Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <fcntl.h>
+#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__)
+# include <sys/cdio.h>
+#elif defined(__linux__)
+# include <linux/cdrom.h>
+#else
+# error "Need the DVD ioctls"
+#endif
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "xine.h"
+#include "monitor.h"
+#include "input_plugin.h"
+#include "dvd_udf.h"
+
+static uint32_t xine_debug;
+
+#define DVD "/dev/dvd"
+#define RDVD "/dev/rdvd"
+
+/*
+ * global Variables:
+ */
+
+static int dvd_fd, raw_fd;
+static off_t file_size, file_size_left;
+static int file_lbstart, file_lbcur;
+static int gVTSMinor, gVTSMajor;
+
+/*
+ * udf dir function
+ */
+
+#define MAX_DIR_ENTRIES 250
+
+static char *filelist[MAX_DIR_ENTRIES];
+static char *filelist2[MAX_DIR_ENTRIES];
+
+static int openDrive () {
+
+ dvd_fd = open(DVD, O_RDONLY | O_NONBLOCK);
+
+ if (dvd_fd < 0) {
+ printf ("input_dvd: unable to open dvd drive (%s): %s\n", DVD,
+ strerror(errno));
+ return -1;
+ }
+
+ raw_fd = open(RDVD, O_RDONLY | O_NONBLOCK);
+ if (raw_fd < 0) {
+ raw_fd = dvd_fd;
+ }
+ return raw_fd;
+}
+
+static void closeDrive () {
+
+ if (dvd_fd<0)
+ return;
+
+ close (dvd_fd);
+ if (raw_fd!=dvd_fd)
+ close (raw_fd);
+
+ dvd_fd = -1;
+}
+
+/*
+ * try to open dvd and prepare to read >filename<
+ *
+ * returns lbnum on success, 0 otherwise
+ */
+
+static int openDVDFile (char *filename, off_t *size) {
+
+ char str[256];
+ int lbnum;
+
+ xprintf (VERBOSE|INPUT, "input_dvd : openDVDFile >%s<\n",filename);
+
+ if (openDrive() < 0) {
+ printf ("input_dvd: cannot open dvd drive >%s<\n", DVD);
+ return 0;
+ }
+
+ snprintf (str, sizeof(str), "/VIDEO_TS/%s", filename);
+
+ xprintf (VERBOSE|INPUT, "UDFFindFile %s\n",str);
+
+ if (!(lbnum=UDFFindFile(dvd_fd, str, size))) {
+ printf ("input_dvd: cannot open file >%s<\n", filename);
+
+ closeDrive ();
+
+ return 0;
+ }
+
+ lseek (raw_fd, lbnum * (off_t) DVD_VIDEO_LB_LEN, SEEK_SET) ;
+
+ return lbnum;
+}
+
+
+static void input_plugin_init (void) {
+ int i;
+
+ /*
+ * allocate space for directory listing
+ */
+
+ for (i=0; i<MAX_DIR_ENTRIES; i++) {
+ filelist[i] = (char *) malloc (256);
+ filelist2[i] = (char *) malloc (256);
+ }
+}
+
+static int input_plugin_open (const char *mrl) {
+
+ char *filename;
+
+ xprintf (VERBOSE|INPUT, "input dvd : input_plugin_open >%s<\n", mrl);
+
+ /*
+ * do we handle this kind of MRL ?
+ */
+
+ if (strncasecmp (mrl, "dvd://",6))
+ return 0;
+
+ filename = (char *) &mrl[6];
+
+ xprintf (VERBOSE|INPUT, "input dvd : input_plugin_open media type correct. file name is %s\n",
+ filename);
+
+ sscanf (filename, "VTS_%d_%d.VOB", &gVTSMajor, &gVTSMinor);
+
+ file_lbstart = openDVDFile (filename, &file_size) ;
+ file_lbcur = file_lbstart;
+
+ if (!file_lbstart) {
+ fprintf (stderr, "unable to find >%s< on dvd.\n",filename);
+ return 0;
+ }
+
+ file_size_left = file_size;
+
+ return 1 ;
+}
+
+static uint32_t input_plugin_read (char *buf, uint32_t nlen) {
+
+ if (nlen != DVD_VIDEO_LB_LEN) {
+ /*
+ * Hide the error reporting now, demuxer try to read 6 bytes
+ * at STAGE_BY_CONTENT probe stage
+ */
+ fprintf (stderr, "ERROR in input_dvd plugin read: %d bytes "
+ "is not a sector!\n", nlen);
+ return 0;
+ }
+
+ if (file_size_left < nlen)
+ return 0;
+
+ if (read (raw_fd, buf, DVD_VIDEO_LB_LEN)) {
+
+ file_lbcur++;
+ file_size_left -= DVD_VIDEO_LB_LEN;
+
+ return DVD_VIDEO_LB_LEN;
+ } else
+ fprintf (stderr, "read error in input_dvd plugin\n");
+
+ return 0;
+}
+
+static off_t input_plugin_seek (off_t offset, int origin) {
+
+ offset /= DVD_VIDEO_LB_LEN;
+
+ switch (origin) {
+ case SEEK_END:
+ offset = (file_size / DVD_VIDEO_LB_LEN) - offset;
+
+ case SEEK_SET:
+ file_lbcur = file_lbstart + offset;
+ file_size_left = file_size - (offset * DVD_VIDEO_LB_LEN);
+ break;
+ case SEEK_CUR:
+ if (offset) {
+ file_lbcur += offset;
+ file_size_left = file_size - ((file_lbcur - file_lbstart) * DVD_VIDEO_LB_LEN);
+ } else {
+ return (file_lbcur - file_lbstart) * (off_t) DVD_VIDEO_LB_LEN;
+ }
+
+ break;
+ default:
+ fprintf (stderr, "error in input dvd plugin seek:%d is an unknown origin\n"
+ ,origin);
+ }
+
+ return lseek (raw_fd, file_lbcur * (off_t) DVD_VIDEO_LB_LEN, SEEK_SET) - file_lbstart * (off_t) DVD_VIDEO_LB_LEN;
+}
+
+static off_t input_plugin_get_length (void) {
+ return file_size;
+}
+
+static uint32_t input_plugin_get_capabilities (void) {
+ return INPUT_CAP_SEEKABLE | INPUT_CAP_BLOCK | INPUT_CAP_AUTOPLAY;
+}
+
+static uint32_t input_plugin_get_blocksize (void) {
+ return DVD_VIDEO_LB_LEN;
+}
+
+static int input_plugin_eject (void) {
+ int ret, status;
+ int fd;
+
+ if((fd = open(DVD, O_RDONLY|O_NONBLOCK)) > -1) {
+
+#if defined (__linux__)
+ if((status = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) > 0) {
+ switch(status) {
+ case CDS_TRAY_OPEN:
+ if((ret = ioctl(fd, CDROMCLOSETRAY)) != 0) {
+ xprintf(VERBOSE|INPUT, "CDROMCLOSETRAY failed: %s\n", strerror(errno));
+ }
+ break;
+ case CDS_DISC_OK:
+ if((ret = ioctl(fd, CDROMEJECT)) != 0) {
+ xprintf(VERBOSE|INPUT, "CDROMEJECT failed: %s\n", strerror(errno));
+ }
+ break;
+ }
+ }
+ else {
+ xprintf(VERBOSE|INPUT, "CDROM_DRIVE_STATUS failed: %s\n",
+ strerror(errno));
+ close(fd);
+ return 0;
+ }
+
+#elif defined (__NetBSD__) || defined (__OpenBSD__) || defined (__FreeBSD__)
+
+ if (ioctl(fd, CDIOCALLOW) == -1) {
+ perror("ioctl(cdromallow)");
+ } else {
+ if (ioctl(fd, CDIOCEJECT) == -1) {
+ perror("ioctl(cdromeject)");
+ }
+ }
+
+#endif
+
+ close(fd);
+ }
+ return 1;
+}
+
+static void input_plugin_close (void) {
+ closeDrive ();
+}
+
+static char *input_plugin_get_identifier (void) {
+ return "DVD";
+}
+
+static char** input_plugin_get_dir (char *filename, int *nEntries) {
+
+ int i, fd;
+
+ if (filename) {
+ *nEntries = 0;
+ return NULL;
+ }
+
+ if((fd = open(DVD, O_RDONLY|O_NONBLOCK)) > -1) {
+
+ int nFiles, nFiles2;
+
+ UDFListDir (fd, "/VIDEO_TS", MAX_DIR_ENTRIES, filelist, &nFiles);
+
+ nFiles2 = 0;
+ for (i=0; i<nFiles; i++) {
+ int nLen;
+
+ nLen = strlen (filelist[i]);
+
+ if (nLen<4)
+ continue;
+
+ if (!strcasecmp (&filelist[i][nLen-4], ".VOB")) {
+
+ sprintf (filelist2[nFiles2], "dvd://%s",filelist[i]);
+
+ nFiles2++;
+ }
+
+ }
+
+ *nEntries = nFiles2;
+
+ close (fd);
+
+ } else {
+ *nEntries = 0;
+ return NULL;
+ }
+
+ return filelist2;
+}
+
+static char **input_plugin_get_autoplay_list (int *nFiles) {
+
+ int i, fd;
+
+ if((fd = open(DVD, O_RDONLY|O_NONBLOCK)) > -1) {
+ int nFiles3, nFiles2;
+
+ UDFListDir (fd, "/VIDEO_TS", MAX_DIR_ENTRIES, filelist, &nFiles3);
+
+ nFiles2 = 0;
+ for (i=0; i<nFiles3; i++) {
+ int nLen;
+
+ nLen = strlen (filelist[i]);
+
+ if (nLen<4)
+ continue;
+
+ if (!strcasecmp (&filelist[i][nLen-4], ".VOB")) {
+
+ sprintf (filelist2[nFiles2], "dvd://%s",filelist[i]);
+
+ nFiles2++;
+ }
+
+ }
+
+ *nFiles = nFiles2;
+
+ close (fd);
+
+ } else {
+ *nFiles = 0;
+ return NULL;
+ }
+
+ return filelist2;
+}
+
+static int input_plugin_is_branch_possible (const char *next_mrl) {
+
+ char *filename;
+ int vts_minor, vts_major;
+
+ printf ("input_dvd: is_branch_possible to %s ?\n", next_mrl);
+
+ /*
+ * do we handle this kind of MRL ?
+ */
+
+ if (strncmp (next_mrl, "dvd://",6))
+ return 0;
+
+ filename = (char *) &next_mrl[6];
+
+ if (sscanf (filename, "VTS_%d_%d.VOB", &vts_major, &vts_minor) == 2) {
+ if ((vts_major==gVTSMajor) && (vts_minor==(gVTSMinor+1))) {
+ printf ("input_dvd: branching is possible\n");
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static input_plugin_t plugin_op = {
+ NULL,
+ NULL,
+ input_plugin_init,
+ input_plugin_open,
+ input_plugin_read,
+ input_plugin_seek,
+ input_plugin_get_length,
+ input_plugin_get_capabilities,
+ input_plugin_get_dir,
+ input_plugin_get_blocksize,
+ input_plugin_eject,
+ input_plugin_close,
+ input_plugin_get_identifier,
+ input_plugin_get_autoplay_list,
+ input_plugin_is_branch_possible,
+ NULL
+};
+
+input_plugin_t *input_plugin_getinfo(uint32_t dbglvl) {
+
+ xine_debug = dbglvl;
+
+ return &plugin_op;
+}
diff --git a/src/input/input_file.c b/src/input/input_file.c
new file mode 100644
index 000000000..d2591d2bd
--- /dev/null
+++ b/src/input/input_file.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2000 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: input_file.c,v 1.1 2001/04/18 22:34:04 f1rmb Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "xine.h"
+#include "monitor.h"
+#include "input_plugin.h"
+
+
+static uint32_t xine_debug;
+static int input_file_handle;
+static char *input_file_mrl;
+
+static uint32_t file_plugin_get_capabilities () {
+ return INPUT_CAP_SEEKABLE;
+}
+
+static int file_plugin_open (char *mrl) {
+
+ char *filename;
+
+ input_file_mrl = mrl;
+
+ if (!strncasecmp (mrl, "file:",5))
+ filename = &mrl[5];
+ else
+ filename = mrl;
+
+ xprintf (VERBOSE|INPUT, "Opening >%s<\n",filename);
+
+ input_file_handle = open (filename, O_RDONLY);
+
+ if (input_file_handle == -1) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
+static off_t file_plugin_read (char *buf, off_t len) {
+ return read (input_file_handle, buf, len);
+}
+
+static buf_element_t *file_plugin_read_block (fifo_buffer_t *fifo, off_t todo) {
+
+ off_t num_bytes, total_bytes;
+ buf_element_t *buf = fifo->buffer_pool_alloc ();
+
+ buf->content = buf->mem;
+ total_bytes = 0;
+
+ while (total_bytes < todo) {
+ num_bytes = read (input_file_handle, buf->mem + total_bytes, todo-total_bytes);
+ total_bytes += num_bytes;
+ if (!num_bytes) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
+ }
+
+ return buf;
+}
+
+
+static off_t file_plugin_seek (off_t offset, int origin) {
+ return lseek (input_file_handle, offset, origin);
+}
+
+
+static off_t file_plugin_get_current_pos (){
+ return lseek (input_file_handle, 0, SEEK_CUR);
+}
+
+
+static off_t file_plugin_get_length (void) {
+ struct stat buf ;
+
+ if (fstat (input_file_handle, &buf) == 0) {
+ return buf.st_size;
+ } else
+ perror ("system call fstat");
+ return 0;
+}
+
+static uint32_t file_plugin_get_blocksize () {
+ return 0;
+}
+
+static char **file_plugin_get_dir (char *filename, int *nFiles) {
+ /* not yet implemented */
+
+ printf ("input_file : get_dir () not implemented yet!\n");
+
+ return NULL;
+}
+
+static int file_plugin_eject_media () {
+ return 1; /* doesn't make sense */
+}
+
+static char* file_plugin_get_mrl () {
+ return input_file_mrl;
+}
+
+static void file_plugin_close (void) {
+ xprintf (VERBOSE|INPUT, "closing input\n");
+
+ close(input_file_handle);
+ input_file_handle = -1;
+}
+
+
+static char *file_plugin_get_description (void) {
+ return "plain file input plugin as shipped with xine";
+}
+
+
+static char *file_plugin_get_identifier (void) {
+ return "file";
+}
+
+
+static input_plugin_t plugin_info = {
+ INPUT_INTERFACE_VERSION,
+ file_plugin_get_capabilities,
+ file_plugin_open,
+ file_plugin_read,
+ file_plugin_read_block,
+ file_plugin_seek,
+ file_plugin_get_current_pos,
+ file_plugin_get_length,
+ file_plugin_get_blocksize,
+ file_plugin_get_dir,
+ file_plugin_eject_media,
+ file_plugin_get_mrl,
+ file_plugin_close,
+ file_plugin_get_description,
+ file_plugin_get_identifier,
+ NULL, /* autoplay */
+ NULL /* clut */
+};
+
+
+input_plugin_t *get_input_plugin (int iface, config_values_t *config) {
+
+ /* FIXME: set debug level (from config?) */
+
+ switch (iface) {
+ case 1:
+ input_file_handle = -1;
+ return &plugin_info;
+ break;
+ default:
+ fprintf(stderr,
+ "File input plugin doesn't support plugin API version %d.\n"
+ "PLUGIN DISABLED.\n"
+ "This means there's a version mismatch between xine and this input"
+ "plugin.\nInstalling current input plugins should help.\n",
+ iface);
+ return NULL;
+ }
+}
diff --git a/src/input/input_net.c b/src/input/input_net.c
new file mode 100644
index 000000000..67684320e
--- /dev/null
+++ b/src/input/input_net.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Read from a tcp network stream over a lan (put a tweaked mp1e encoder the
+ * other end and you can watch tv anywhere in the house ..)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#include "xine.h"
+#include "monitor.h"
+#include "input_plugin.h"
+
+static uint32_t xine_debug;
+
+static int input_file_handle;
+
+static int host_connect_attempt(struct in_addr ia, int port) {
+ int s=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ struct sockaddr_in sin;
+
+ fd_set wfd;
+ struct timeval tv;
+
+ if(s==-1)
+ {
+ perror("socket");
+ return -1;
+ }
+
+ if(fcntl(s, F_SETFL, FNDELAY)==-1)
+ {
+ perror("nonblocking");
+ close(s);
+ return -1;
+ }
+
+ sin.sin_family = AF_INET;
+ sin.sin_addr = ia;
+ sin.sin_port = htons(port);
+
+ if(connect(s, (struct sockaddr *)&sin, sizeof(sin))==-1 && errno != EINPROGRESS)
+ {
+ perror("connect");
+ close(s);
+ return -1;
+ }
+
+ tv.tv_sec = 60; /* We use 60 second timeouts for now */
+ tv.tv_usec = 0;
+
+ FD_ZERO(&wfd);
+ FD_SET(s, &wfd);
+
+ switch(select(s+1, NULL, &wfd, NULL, &tv))
+ {
+ case 0:
+ /* Time out */
+ close(s);
+ return -1;
+ case -1:
+ /* Ermm.. ?? */
+ perror("select");
+ close(s);
+ return -1;
+ }
+
+ return s;
+}
+
+static int host_connect(const char *host, int port) {
+ struct hostent *h;
+ int i;
+ int s;
+
+ h=gethostbyname(host);
+ if(h==NULL)
+ {
+ fprintf(stderr,"unable to resolve '%s'.\n", host);
+ return -1;
+ }
+
+
+ for(i=0; h->h_addr_list[i]; i++)
+ {
+ struct in_addr ia;
+ memcpy(&ia, h->h_addr_list[i],4);
+ s=host_connect_attempt(ia, port);
+ if(s != -1)
+ return s;
+ }
+ fprintf(stderr, "unable to connect to '%s'.\n", host);
+ return -1;
+}
+
+static void input_plugin_init (void) {
+ input_file_handle = -1;
+}
+
+static int input_plugin_open (const char *mrl) {
+
+ char *filename;
+ char *pptr;
+ int port = 7658;
+
+ if (!strncasecmp (mrl, "tcp:",4))
+ filename = (char *) &mrl[4];
+ else
+ return 0;
+
+ if(strncmp(filename, "//", 2)==0)
+ filename+=2;
+
+ xprintf (VERBOSE|INPUT, "Opening >%s<\n", filename);
+
+ pptr=strrchr(filename, ':');
+ if(pptr)
+ {
+ *pptr++=0;
+ sscanf(pptr,"%d", &port);
+ }
+
+ input_file_handle = host_connect(filename, port);
+
+ if (input_file_handle == -1) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static uint32_t input_plugin_read (char *buf, uint32_t nlen) {
+ return read (input_file_handle, buf, nlen);
+}
+
+static off_t input_plugin_seek (off_t offset, int origin) {
+
+ return -1;
+}
+
+static off_t input_plugin_get_length (void) {
+ return 0;
+}
+
+static uint32_t input_plugin_get_capabilities (void) {
+ return 0;
+}
+
+static uint32_t input_plugin_get_blocksize (void) {
+ return 2324;
+}
+
+static int input_plugin_eject (void) {
+ return 1;
+}
+
+static void input_plugin_close (void) {
+ close(input_file_handle);
+ input_file_handle = -1;
+}
+
+static char *input_plugin_get_identifier (void) {
+ return "TCP";
+}
+
+static int input_plugin_is_branch_possible (const char *next_mrl) {
+ return 0;
+}
+
+static input_plugin_t plugin_op = {
+ NULL,
+ NULL,
+ input_plugin_init,
+ input_plugin_open,
+ input_plugin_read,
+ input_plugin_seek,
+ input_plugin_get_length,
+ input_plugin_get_capabilities,
+ NULL,
+ input_plugin_get_blocksize,
+ input_plugin_eject,
+ input_plugin_close,
+ input_plugin_get_identifier,
+ NULL,
+ input_plugin_is_branch_possible,
+ NULL
+};
+
+input_plugin_t *input_plugin_getinfo(uint32_t dbglvl) {
+
+ xine_debug = dbglvl;
+
+ return &plugin_op;
+}
diff --git a/src/input/input_plugin.h b/src/input/input_plugin.h
new file mode 100644
index 000000000..002c1b650
--- /dev/null
+++ b/src/input/input_plugin.h
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2000 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: input_plugin.h,v 1.1 2001/04/18 22:34:05 f1rmb Exp $
+ */
+
+#ifndef HAVE_INPUT_PLUGIN_H
+#define HAVE_INPUT_PLUGIN_H
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include "buffer.h"
+#include "configfile.h"
+
+#define INPUT_INTERFACE_VERSION 1
+
+#ifndef CLUT_T
+#define CLUT_T
+typedef struct { /* CLUT == Color LookUp Table */
+ uint8_t foo : 8; /* UNKNOWN: 0x00? */
+ uint8_t y : 8;
+ uint8_t cr : 8;
+ uint8_t cb : 8;
+} __attribute__ ((packed)) clut_t;
+#endif
+
+typedef struct input_plugin_s
+{
+
+ /*
+ * plugin interface version, lower versions _may_ be supported
+ */
+ int interface_version;
+
+ /*
+ * return capabilities of input source
+ */
+
+ uint32_t (*get_capabilities) (void);
+
+ /*
+ * open input MRL - return 1 if succ
+ */
+ int (*open) (char *mrl);
+
+
+ /*
+ * read nlen bytes, return number of bytes read
+ */
+ off_t (*read) (char *buf, off_t nlen);
+
+
+ /*
+ * read one block, return newly allocated block (or NULL on failure)
+ * for blocked input sources len must be == blocksize
+ * the fifo parameter is only used to get access to the buffer_pool_alloc function
+ */
+ buf_element_t *(*read_block)(fifo_buffer_t *fifo, off_t len);
+
+
+ /*
+ * seek position, return new position
+ *
+ * if seeking failed, -1 is returned
+ */
+ off_t (*seek) (off_t offset, int origin);
+
+
+ /*
+ * get current position in stream.
+ *
+ */
+ off_t (*get_current_pos) (void);
+
+
+ /*
+ * return length of input (-1 => unlimited, e.g. stream)
+ */
+ off_t (*get_length) (void);
+
+
+ /*
+ * return block size of input source (if supported, 0 otherwise)
+ */
+
+ uint32_t (*get_blocksize) (void);
+
+
+ /*
+ * ls function
+ * return value: NULL => filename is a file, **char=> filename is a dir
+ */
+ char** (*get_dir) (char *filename, int *nFiles);
+
+
+ /*
+ * eject/load the media (if it's possible)
+ *
+ * returns 0 for temporary failures
+ */
+ int (*eject_media) (void);
+
+
+ /*
+ * return current MRL
+ */
+ char * (*get_mrl) (void);
+
+
+ /*
+ * close input source
+ */
+ void (*close) (void);
+
+
+ /*
+ * return human readable (verbose = 1 line) description for this plugin
+ */
+ char* (*get_description) (void);
+
+
+ /*
+ * return short, human readable identifier for this plugin
+ * this is used for GUI buttons, The identifier must have max. 4 characters
+ * characters (max. 5 including terminating \0)
+ */
+ char* (*get_identifier) (void);
+
+
+ /*
+ * generate autoplay list
+ * return value: list of MRLs
+ */
+ char** (*get_autoplay_list) (int *nFiles);
+
+
+ /*
+ * gets the subtitle/menu palette
+ */
+ clut_t* (*get_clut) (void);
+
+
+} input_plugin_t;
+
+#define INPUT_CAP_SEEKABLE 1
+#define INPUT_CAP_BLOCK 2
+#define INPUT_CAP_AUTOPLAY 4
+#define INPUT_CAP_CLUT 8
+
+
+/*
+ * init/get plugin structure
+ *
+ * try to initialize the plugin with given interface version
+ * and configuration options
+ */
+input_plugin_t *get_input_plugin (int requested_interface,
+ config_values_t *config);
+
+
+
+#endif
diff --git a/src/input/input_rtp.c b/src/input/input_rtp.c
new file mode 100644
index 000000000..88fa5784d
--- /dev/null
+++ b/src/input/input_rtp.c
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * Xine input plugin for multicast video streams.
+ *
+ *
+ * This is something of an experiment - it doesn't work well yet. Originally
+ * the intent was to read an rtp stream, from, for example, Cisco IP
+ * Tv. That's still a long term goal but RTP doesn't fit well in an input
+ * plugin because typically video is carried on one multicast group and audio
+ * in another - i.e it's already demultiplexed and an input plugin would
+ * actually have to reassemble the content. Now that demultiplexers are
+ * becomming separate loadable objects the right thing to do is to write an
+ * RTP demux plugin and a playlist plugin that handles SDP.
+ *
+ *
+ * In the meantime some experience with multicast video was wanted. Not
+ * having hardware available to construct a stream on the fly a server was
+ * written to multicast the contents of an mpeg program stream - it just
+ * reads a pack then transmits it at the appropriate time as follows.
+ *
+ * fd is open for read on mpeg stream, sock for write on a multicast socket.
+ *
+ * while (1) {
+ * /* read pack */
+ * read(fd, buf, 2048)
+ * /* end of stream */
+ * if (buf[3] == 0xb9)
+ * return 0;
+ *
+ * /* extract the system reference clock, srcb, from the pack */
+ *
+ * send_at = srcb/90000.0;
+ * while (time_now < send_at) {
+ * wait;
+ * }
+ * r = write(sock, buf, 2048);
+ * }
+ *
+ * One problem is that a stream from a DVD needs each pack sending
+ * at approx 2.5ms intervals which is a shorter interval than the
+ * standard linux clock. The RTC can be used for more finely grained
+ * timing.
+ *
+ * If you live in a non multicast friendly environment then the stream
+ * can be unicast.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <errno.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include <stdlib.h>
+
+#include "input_plugin.h"
+
+static int last_input_error;
+static int input_eof;
+static uint32_t xine_debug;
+
+typedef struct _input_buffer {
+ struct _input_buffer *next;
+ unsigned char *buf;
+} input_buffer;
+
+#define N_BUFFERS 128
+#define IBUFFER_SIZE 2048
+
+static int input_file_handle = -1;
+
+input_buffer *free_buffers;
+input_buffer **fifo_head;
+input_buffer fifo_tail;
+
+pthread_mutex_t buffer_mutex;
+pthread_cond_t buffer_notempty;
+
+static pthread_t reader_thread;
+
+static void * input_plugin_read_loop(void *);
+
+static int host_connect_attempt(struct in_addr ia, int port) {
+ int s=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ struct sockaddr_in sin;
+
+ if(s==-1) {
+ perror("socket");
+ return -1;
+ }
+
+ sin.sin_family = AF_INET;
+ sin.sin_addr = ia;
+ sin.sin_port = htons(port);
+
+ /* datagram socket */
+ if (bind(s, (struct sockaddr *)&sin, sizeof(sin))) {
+ perror("bind failed");
+ exit(1);
+ }
+ /* multicast ? */
+ if ((ntohl(sin.sin_addr.s_addr) >> 28) == 0xe) {
+ struct ip_mreqn mreqn;
+
+ mreqn.imr_multiaddr.s_addr = sin.sin_addr.s_addr;
+ mreqn.imr_address.s_addr = INADDR_ANY;
+ mreqn.imr_ifindex = 0;
+ if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreqn,sizeof(mreqn))) {
+ perror("setsockopt IP_ADD_MEMBERSHIP failed (multicast kernel?)");
+ exit(1);
+ }
+ }
+
+ return s;
+}
+
+static int host_connect(const char *host, int port) {
+ struct hostent *h;
+ int i;
+ int s;
+
+ h=gethostbyname(host);
+ if(h==NULL)
+ {
+ fprintf(stderr,"unable to resolve '%s'.\n", host);
+ return -1;
+ }
+
+
+ for(i=0; h->h_addr_list[i]; i++)
+ {
+ struct in_addr ia;
+ memcpy(&ia, h->h_addr_list[i],4);
+ s=host_connect_attempt(ia, port);
+ if(s != -1)
+ return s;
+ }
+ fprintf(stderr, "unable to connect to '%s'.\n", host);
+ return -1;
+}
+
+static void input_plugin_init (void) {
+ int bufn;
+
+ for (bufn = 0; bufn < N_BUFFERS; bufn++) {
+ input_buffer *buf = malloc(sizeof(input_buffer));
+ if (!buf) {
+ fprintf(stderr, "unable to allocate input buffer.\n");
+ exit(1);
+ }
+ buf->buf = malloc(IBUFFER_SIZE);
+ if (!buf->buf) {
+ fprintf(stderr, "unable to allocate input buffer.\n");
+ exit(1);
+ }
+ buf->next = free_buffers;
+ free_buffers = buf;
+ }
+}
+
+static int input_plugin_open (char *mrl) {
+ char *filename;
+ char *pptr;
+ int port = 7658;
+ pthread_attr_t thread_attrs;
+
+ if (!strncmp (mrl, "rtp:",4)) {
+ filename = &mrl[4];
+ } else if (!strncmp (mrl, "udp:",4)) {
+ filename = &mrl[4];
+ } else
+ return 0;
+
+ if(strncmp(filename, "//", 2)==0)
+ filename+=2;
+
+ printf ("Opening >%s<\n", filename);
+
+ pptr=strrchr(filename, ':');
+ if(pptr)
+ {
+ *pptr++=0;
+ sscanf(pptr,"%d", &port);
+ }
+
+ if (input_file_handle != -1)
+ close(input_file_handle);
+ input_file_handle = host_connect(filename, port);
+
+ if (input_file_handle == -1) {
+ return 0;
+ }
+
+ last_input_error = 0;
+ input_eof = 0;
+ fifo_tail.next = &fifo_tail;
+ fifo_head = &fifo_tail.next;
+
+ pthread_cond_init(&buffer_notempty, NULL);
+ pthread_attr_init(&thread_attrs);
+ pthread_attr_setdetachstate(&thread_attrs, PTHREAD_CREATE_DETACHED);
+ pthread_create(&reader_thread, &thread_attrs, input_plugin_read_loop, (void *)input_file_handle);
+ pthread_attr_destroy(&thread_attrs);
+
+ return 1;
+}
+
+static uint32_t input_plugin_read (char *buf, uint32_t nlen) {
+ input_buffer *ibuf;
+
+ pthread_mutex_lock (&buffer_mutex);
+ while (fifo_tail.next == &fifo_tail) {
+ if (input_eof) {
+ pthread_mutex_unlock (&buffer_mutex);
+ return 0;
+ }
+ if (last_input_error) {
+ pthread_mutex_unlock (&buffer_mutex);
+ return last_input_error;
+ }
+ pthread_cond_wait(&buffer_notempty, &buffer_mutex);
+ }
+ ibuf = fifo_tail.next;
+ fifo_tail.next = fifo_tail.next->next;
+
+ /* Is FIFO now empty */
+ if (fifo_tail.next == &fifo_tail)
+ fifo_head = &fifo_tail.next;
+
+ pthread_mutex_unlock (&buffer_mutex);
+
+ memcpy(buf, ibuf->buf, nlen < IBUFFER_SIZE ? nlen : IBUFFER_SIZE);
+
+ pthread_mutex_lock (&buffer_mutex);
+ ibuf->next = free_buffers;
+ free_buffers = ibuf;
+ pthread_mutex_unlock (&buffer_mutex);
+
+ return nlen < IBUFFER_SIZE ? nlen : IBUFFER_SIZE;
+}
+
+static void * input_plugin_read_loop(void *arg) {
+ int inf = (int) arg;
+ input_buffer *buf;
+ int r;
+ unsigned short seq = 0;
+ static int warned = 0;
+
+ char whirly[] = "/-\\|";
+ int gig = 0;
+
+ while (1) {
+ pthread_mutex_lock (&buffer_mutex);
+ /* we expect to be able to get a free buffer - possibly we
+ could be a bit more reasonable but this will do for now. */
+ if (!free_buffers) {
+ input_eof = 1;
+ if (!warned) {
+ printf("OUCH - ran out of buffers\n");
+ warned = 1;
+ }
+ pthread_cond_signal(&buffer_notempty);
+ continue;
+ }
+ warned = 0;
+ buf = free_buffers;
+ free_buffers = free_buffers->next;
+ pthread_mutex_unlock (&buffer_mutex);
+
+ /* printf("%c\r", whirly[(gig++ % 4)]); */
+ /* fflush(stdout); */
+ r = read(inf, buf->buf, IBUFFER_SIZE);
+ if (r < 0) {
+ /* descriptor may be closed by main thread */
+ if (r != EBADF)
+ last_input_error = r;
+ return 0;
+ }
+ if (r == 0) {
+ input_eof = 1;
+ return 0;
+ }
+
+ /* For now - check whether we're dropping input */
+ if (++seq != *(unsigned short *)buf->buf) {
+ printf("OUCH - dropped input packet %d %d\n", seq, *(unsigned short *)buf->buf);
+ seq = *(unsigned short *)buf->buf;
+ }
+ buf->buf[1] = buf->buf[0] = 0;
+ pthread_mutex_lock (&buffer_mutex);
+ buf->next = *fifo_head;
+ *fifo_head = buf;
+ fifo_head = &buf->next;
+ pthread_cond_signal(&buffer_notempty);
+ pthread_mutex_unlock (&buffer_mutex);
+ }
+}
+
+static off_t input_plugin_seek (off_t offset, int origin) {
+
+ return -1;
+}
+
+static uint32_t input_plugin_get_length (void) {
+ return 0;
+}
+
+static uint32_t input_plugin_get_capabilities (void) {
+ return 0;
+}
+
+static uint32_t input_plugin_get_blocksize (void) {
+ return 2048;
+}
+
+static void input_plugin_close (void) {
+ close(input_file_handle);
+ input_file_handle = -1;
+}
+
+static int input_plugin_eject (void) {
+ return 1;
+}
+
+static char *input_plugin_get_identifier (void) {
+ return "RTP";
+}
+
+static int input_plugin_is_branch_possible (char *next_mrl) {
+ return 0;
+}
+
+static input_plugin_t plugin_op = {
+ NULL,
+ NULL,
+ input_plugin_init,
+ input_plugin_open,
+ input_plugin_read,
+ input_plugin_seek,
+ input_plugin_get_length,
+ input_plugin_get_capabilities,
+ NULL,
+ input_plugin_get_blocksize,
+ input_plugin_eject,
+ input_plugin_close,
+ input_plugin_get_identifier,
+ NULL,
+ input_plugin_is_branch_possible,
+ NULL
+};
+
+input_plugin_t *input_plugin_getinfo(uint32_t dbglvl) {
+
+ xine_debug = dbglvl;
+
+ return &plugin_op;
+}
diff --git a/src/input/input_stdin_fifo.c b/src/input/input_stdin_fifo.c
new file mode 100644
index 000000000..488564795
--- /dev/null
+++ b/src/input/input_stdin_fifo.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: input_stdin_fifo.c,v 1.1 2001/04/18 22:34:05 f1rmb Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#include "input_plugin.h"
+
+static uint32_t xine_debug;
+
+static int input_file_handle;
+
+/* ------------------------------------------------------------------------- */
+/*
+ *
+ */
+static void input_plugin_init(void) {
+
+ input_file_handle = -1;
+}
+/* ------------------------------------------------------------------------- */
+/*
+ *
+ */
+static int input_plugin_open(const char *mrl) {
+ char *filename;
+ char *pfn;
+
+ if(!strncasecmp(mrl, "stdin:", 6)
+ || !strncmp(mrl, "-", 1)) {
+ filename = "/dev/stdin";
+ }
+ else if(!strncasecmp(mrl, "fifo:", 5)) {
+
+ if((pfn = strrchr((mrl+5), ':')) != NULL) {
+ filename = ++pfn;
+ }
+ else {
+ filename = (char *) &mrl[5];
+ }
+
+ }
+ else {
+ filename = (char *) mrl;
+ }
+
+#ifdef DEBUG
+ fprintf(stderr, "%s(%d): opening >%s< file\n",
+ __FILE__, __LINE__, filename);
+#endif
+
+ input_file_handle = open(filename, O_RDONLY);
+
+ if(input_file_handle == -1) {
+ return 0;
+ }
+
+ return 1;
+}
+/* ------------------------------------------------------------------------- */
+/*
+ *
+ */
+static uint32_t input_plugin_read(char *buf, uint32_t nlen) {
+
+ int n, nBytesRead;
+
+ nBytesRead = 0;
+
+ while (nBytesRead < nlen) {
+ n = read(input_file_handle, &buf[nBytesRead], nlen-nBytesRead);
+
+ if (n<0)
+ return n;
+ else if (!n)
+ return nBytesRead;
+
+ nBytesRead += n;
+ }
+ return nBytesRead;
+}
+/* ------------------------------------------------------------------------- */
+/*
+ *
+ */
+static off_t input_plugin_seek(off_t offset, int origin) {
+
+ return lseek(input_file_handle, offset, origin);
+}
+/* ------------------------------------------------------------------------- */
+/*
+ *
+ */
+static off_t input_plugin_get_length(void) {
+ struct stat buf ;
+
+ if(fstat(input_file_handle, &buf) == 0) {
+ return buf.st_size;
+ }
+ else {
+ fprintf(stderr, "%s(%d): fstat() failed: %s\n",
+ __FILE__, __LINE__, strerror(errno));
+ }
+
+ return 0;
+}
+/* ------------------------------------------------------------------------- */
+/*
+ *
+ */
+static uint32_t input_plugin_get_capabilities(void) {
+
+ return 0;
+}
+/* ------------------------------------------------------------------------- */
+/*
+ *
+ */
+static uint32_t input_plugin_get_blocksize(void) {
+
+ return 0;
+}
+/* ------------------------------------------------------------------------- */
+/*
+ *
+ */
+static int input_plugin_eject (void) {
+ return 1;
+}
+/* ------------------------------------------------------------------------- */
+/*
+ *
+ */
+static void input_plugin_close(void) {
+
+#ifdef DEBUG
+ fprintf(stderr, "%s(%d): closing input\n",
+ __FILE__, __LINE__);
+#endif
+
+ close(input_file_handle);
+ input_file_handle = -1;
+}
+/* ------------------------------------------------------------------------- */
+/*
+ *
+ */
+static char *input_plugin_get_identifier(void) {
+
+ return "stdin_fifo";
+}
+/* ------------------------------------------------------------------------- */
+/*
+ *
+ */
+static int input_plugin_is_branch_possible (const char *next_mrl) {
+
+ return 0;
+}
+/* ------------------------------------------------------------------------- */
+/*
+ *
+ */
+static input_plugin_t plugin_op = {
+ NULL,
+ NULL,
+ input_plugin_init,
+ input_plugin_open,
+ input_plugin_read,
+ input_plugin_seek,
+ input_plugin_get_length,
+ input_plugin_get_capabilities,
+ NULL,
+ input_plugin_get_blocksize,
+ input_plugin_eject,
+ input_plugin_close,
+ input_plugin_get_identifier,
+ NULL,
+ input_plugin_is_branch_possible,
+ NULL
+};
+/* ------------------------------------------------------------------------- */
+/*
+ *
+ */
+input_plugin_t *input_plugin_getinfo(uint32_t dbglvl) {
+
+ xine_debug = dbglvl;
+
+ return &plugin_op;
+}
+/* ------------------------------------------------------------------------- */
diff --git a/src/input/input_vcd.c b/src/input/input_vcd.c
new file mode 100644
index 000000000..42ccade80
--- /dev/null
+++ b/src/input/input_vcd.c
@@ -0,0 +1,586 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: input_vcd.c,v 1.1 2001/04/18 22:34:05 f1rmb Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <string.h>
+#if defined (__linux__)
+#include <linux/cdrom.h>
+#elif defined (__FreeBSD__)
+#include <sys/cdio.h>
+#include <sys/cdrio.h>
+#else
+#error "you need to add cdrom / VCD support for your platform to input_vcd"
+#endif
+
+#include "xine.h"
+#include "monitor.h"
+#include "input_plugin.h"
+
+static uint32_t xine_debug;
+
+/* for FreeBSD make a link to the right devnode, like /dev/acd0c */
+#define CDROM "/dev/cdrom"
+#define VCDSECTORSIZE 2324
+
+typedef struct {
+ uint8_t sync [12];
+ uint8_t header [4];
+ uint8_t subheader [8];
+ uint8_t data [2324];
+ uint8_t spare [4];
+} cdsector_t;
+
+typedef struct {
+ int fd;
+
+#if defined (__linux__)
+ struct cdrom_tochdr tochdr;
+ struct cdrom_tocentry tocent[100];
+#elif defined (__FreeBSD__)
+ struct ioc_toc_header tochdr;
+ struct cd_toc_entry *tocent;
+ off_t cur_sector;
+#endif
+ int total_tracks;
+ int cur_track;
+
+#if defined (__linux__)
+ uint8_t cur_min, cur_sec, cur_frame;
+#endif
+
+ char *filelist[100];
+
+} input_vcd_t;
+
+static input_vcd_t gVCD;
+
+static void input_plugin_init (void) {
+ int i;
+
+ gVCD.fd = -1;
+ for (i=0; i<100; i++)
+ gVCD.filelist[i] = (char *) malloc (256);
+}
+
+
+#if defined (__linux__)
+static int input_vcd_read_toc (void) {
+ int i;
+
+ /* read TOC header */
+ if ( ioctl(gVCD.fd, CDROMREADTOCHDR, &gVCD.tochdr) == -1 ) {
+ fprintf (stderr, "input_vcd : error in ioctl CDROMREADTOCHDR\n");
+ return -1;
+ }
+
+ /* read individual tracks */
+ for (i=gVCD.tochdr.cdth_trk0; i<=gVCD.tochdr.cdth_trk1; i++) {
+ gVCD.tocent[i-1].cdte_track = i;
+ gVCD.tocent[i-1].cdte_format = CDROM_MSF;
+ if ( ioctl(gVCD.fd, CDROMREADTOCENTRY, &gVCD.tocent[i-1]) == -1 ) {
+ fprintf (stderr, "input_vcd: error in ioctl CDROMREADTOCENTRY\n");
+ return -1;
+ }
+ }
+
+ /* read the lead-out track */
+ gVCD.tocent[gVCD.tochdr.cdth_trk1].cdte_track = CDROM_LEADOUT;
+ gVCD.tocent[gVCD.tochdr.cdth_trk1].cdte_format = CDROM_MSF;
+
+ if (ioctl(gVCD.fd, CDROMREADTOCENTRY, &gVCD.tocent[gVCD.tochdr.cdth_trk1]) == -1 ) {
+ fprintf (stderr, "input_vcd: error in ioctl CDROMREADTOCENTRY\n");
+ return -1;
+ }
+
+ gVCD.total_tracks = gVCD.tochdr.cdth_trk1;
+
+ return 0;
+}
+#elif defined (__FreeBSD__)
+static int input_vcd_read_toc (void) {
+
+ struct ioc_read_toc_entry te;
+ int ntracks;
+
+ /* read TOC header */
+ if ( ioctl(gVCD.fd, CDIOREADTOCHEADER, &gVCD.tochdr) == -1 ) {
+ fprintf (stderr, "input_vcd : error in ioctl CDROMREADTOCHDR\n");
+ return -1;
+ }
+
+ ntracks = gVCD.tochdr.ending_track
+ - gVCD.tochdr.starting_track + 2;
+ gVCD.tocent = (struct cd_toc_entry *)malloc(sizeof(*gVCD.tocent) * ntracks);
+
+ te.address_format = CD_LBA_FORMAT;
+ te.starting_track = 0;
+ te.data_len = ntracks * sizeof(struct cd_toc_entry);
+ te.data = gVCD.tocent;
+
+ if ( ioctl(gVCD.fd, CDIOREADTOCENTRYS, &te) == -1 ){
+ fprintf (stderr, "input_vcd: error in ioctl CDROMREADTOCENTRY\n");
+ return -1;
+ }
+
+ gVCD.total_tracks = gVCD.tochdr.ending_track
+ - gVCD.tochdr.starting_track +1;
+
+ return 0;
+}
+#endif
+
+static int input_plugin_open (const char *mrl) {
+
+ char *filename;
+
+ if (strncasecmp (mrl, "vcd://",6))
+ return 0;
+
+ gVCD.fd = open (CDROM, O_RDONLY);
+
+ if (gVCD.fd == -1) {
+ return 0;
+ }
+
+ if (input_vcd_read_toc ()) {
+ close (gVCD.fd);
+ gVCD.fd = -1;
+ return 0;
+ }
+
+ filename = (char *) &mrl[6];
+
+ xprintf (VERBOSE|INPUT, "Opening >%s<\n",filename);
+
+ if (sscanf (filename, "%d", &gVCD.cur_track) != 1) {
+ fprintf (stderr, "input_vcd: malformed MRL. Use vcd://<track #>\n");
+ close (gVCD.fd);
+ gVCD.fd = -1;
+ return 0;
+ }
+
+ if (gVCD.cur_track>=gVCD.total_tracks) {
+ fprintf (stderr, "input_vcd: invalid track %d (valid range: 0 .. %d)\n",
+ gVCD.cur_track, gVCD.total_tracks-1);
+ close (gVCD.fd);
+ gVCD.fd = -1;
+ return 0;
+ }
+
+#if defined (__linux__)
+ gVCD.cur_min = gVCD.tocent[gVCD.cur_track].cdte_addr.msf.minute;
+ gVCD.cur_sec = gVCD.tocent[gVCD.cur_track].cdte_addr.msf.second;
+ gVCD.cur_frame = gVCD.tocent[gVCD.cur_track].cdte_addr.msf.frame;
+#elif defined (__FreeBSD__)
+ {
+ int bsize = 2352;
+ if (ioctl (gVCD.fd, CDRIOCSETBLOCKSIZE, &bsize) == -1) {
+ fprintf (stderr, "input_vcd: error in CDRIOCSETBLOCKSIZE %d\n", errno);
+ return 0;
+ }
+
+ gVCD.cur_sector =
+ ntohl(gVCD.tocent
+ [gVCD.cur_track+1 - gVCD.tochdr.starting_track].addr.lba);
+
+ }
+#endif
+
+ return 1;
+}
+
+
+
+#if defined (__linux__)
+static uint32_t input_plugin_read (char *buf, uint32_t nlen) {
+
+ static struct cdrom_msf msf ;
+ static cdsector_t data;
+ struct cdrom_msf0 *end_msf;
+
+ if (nlen != VCDSECTORSIZE)
+ return 0;
+
+ do
+ {
+ end_msf = &gVCD.tocent[gVCD.cur_track+1].cdte_addr.msf;
+
+ /*
+ printf ("cur: %02d:%02d:%02d end: %02d:%02d:%02d\n",
+ gVCD.cur_min, gVCD.cur_sec, gVCD.cur_frame,
+ end_msf->minute, end_msf->second, end_msf->frame);
+ */
+
+ if ( (gVCD.cur_min>=end_msf->minute) && (gVCD.cur_sec>=end_msf->second)
+ && (gVCD.cur_frame>=end_msf->frame))
+ return 0;
+
+ msf.cdmsf_min0 = gVCD.cur_min;
+ msf.cdmsf_sec0 = gVCD.cur_sec;
+ msf.cdmsf_frame0 = gVCD.cur_frame;
+
+ memcpy (&data, &msf, sizeof (msf));
+
+ if (ioctl (gVCD.fd, CDROMREADRAW, &data) == -1) {
+ fprintf (stderr, "input_vcd: error in CDROMREADRAW\n");
+ return 0;
+ }
+
+
+ gVCD.cur_frame++;
+ if (gVCD.cur_frame>=75) {
+ gVCD.cur_frame = 0;
+ gVCD.cur_sec++;
+ if (gVCD.cur_sec>=60) {
+ gVCD.cur_sec = 0;
+ gVCD.cur_min++;
+ }
+ }
+
+ /* Header ID check for padding sector. VCD uses this to keep constant
+ bitrate so the CD doesn't stop/start */
+ }
+ while((data.subheader[2]&~0x01)==0x60);
+
+ memcpy (buf, data.data, VCDSECTORSIZE); /* FIXME */
+ return VCDSECTORSIZE;
+}
+#elif defined (__FreeBSD__)
+static uint32_t input_plugin_read (char *buf, uint32_t nlen) {
+ static cdsector_t data;
+ int bsize = 2352;
+
+ if (nlen != VCDSECTORSIZE)
+ return 0;
+
+ do {
+ if (lseek (gVCD.fd, gVCD.cur_sector * bsize, SEEK_SET) == -1) {
+ fprintf (stderr, "input_vcd: seek error %d\n", errno);
+ return 0;
+ }
+ if (read (gVCD.fd, &data, bsize) == -1) {
+ fprintf (stderr, "input_vcd: read error %d\n", errno);
+ return 0;
+ }
+ gVCD.cur_sector++;
+ } while ((data.subheader[2]&~0x01)==0x60);
+ memcpy (buf, data.data, VCDSECTORSIZE);
+ return VCDSECTORSIZE;
+}
+#endif
+
+
+#if defined (__linux__)
+static off_t input_plugin_seek (off_t offset, int origin) {
+
+ struct cdrom_msf0 *start_msf;
+ uint32_t dist ;
+ off_t sector_pos;
+
+ start_msf = &gVCD.tocent[gVCD.cur_track].cdte_addr.msf;
+
+ switch (origin) {
+ case SEEK_SET:
+ dist = offset / VCDSECTORSIZE;
+
+ gVCD.cur_min = dist / (60*75) + start_msf->minute;
+ dist %= 60;
+ gVCD.cur_sec = dist / 75 + start_msf->second;
+ dist %= 75;
+ gVCD.cur_frame = dist + start_msf->frame;
+
+ xprintf (VERBOSE|INPUT, "%d => %02d:%02d:%02d\n",offset,gVCD.cur_min,gVCD.cur_sec,gVCD.cur_frame);
+
+ break;
+ case SEEK_CUR:
+ if (offset)
+ fprintf (stderr, "input_vcd: SEEK_CUR not implemented for offset != 0\n");
+
+ sector_pos = 75 - start_msf->frame;
+
+ if (start_msf->second<60)
+ sector_pos += (59 - start_msf->second) * 75;
+
+ if ( gVCD.cur_min > start_msf->minute) {
+ sector_pos += (gVCD.cur_min - start_msf->minute-1) * 60 * 75;
+
+ sector_pos += gVCD.cur_sec * 60;
+
+ sector_pos += gVCD.cur_frame ;
+ }
+
+ return sector_pos * VCDSECTORSIZE;
+
+ break;
+ default:
+ fprintf (stderr, "input_vcd: error seek to origin %d not implemented!\n",
+ origin);
+ return 0;
+ }
+
+ return offset ; /* FIXME */
+}
+#elif defined (__FreeBSD__)
+static off_t input_plugin_seek (off_t offset, int origin) {
+
+
+ u_long start;
+ uint32_t dist ;
+ off_t sector_pos;
+
+ start =
+ ntohl(gVCD.tocent
+ [gVCD.cur_track+1 - gVCD.tochdr.starting_track].addr.lba);
+
+ /* printf("seek: start sector:%lu, origin: %d, offset:%qu\n",
+ start, origin, offset);
+ */
+
+ switch (origin) {
+ case SEEK_SET:
+ dist = offset / VCDSECTORSIZE;
+ gVCD.cur_sector = start + dist;
+ break;
+ case SEEK_CUR:
+
+ if (offset)
+ fprintf (stderr, "input_vcd: SEEK_CUR not implemented for offset != 0\n");
+
+ sector_pos = gVCD.cur_sector;
+
+ return sector_pos * VCDSECTORSIZE;
+
+ break;
+ default:
+ fprintf (stderr, "input_vcd: error seek to origin %d not implemented!\n",
+ origin);
+ return 0;
+ }
+
+ return offset ; /* FIXME */
+}
+#endif
+
+#if defined (__linux__)
+static off_t input_plugin_get_length (void) {
+ struct cdrom_msf0 *end_msf, *start_msf;
+ off_t len ;
+
+ start_msf = &gVCD.tocent[gVCD.cur_track].cdte_addr.msf;
+ end_msf = &gVCD.tocent[gVCD.cur_track+1].cdte_addr.msf;
+
+ len = 75 - start_msf->frame;
+
+ if (start_msf->second<60)
+ len += (59 - start_msf->second) * 75;
+
+ if (end_msf->minute > start_msf->minute) {
+ len += (end_msf->minute - start_msf->minute-1) * 60 * 75;
+
+ len += end_msf->second * 60;
+
+ len += end_msf->frame ;
+ }
+
+ return len * VCDSECTORSIZE;
+}
+#elif defined (__FreeBSD__)
+static off_t input_plugin_get_length (void) {
+
+ off_t len ;
+
+
+ len =
+ ntohl(gVCD.tocent
+ [gVCD.cur_track+2
+ - gVCD.tochdr.starting_track].addr.lba)
+ - ntohl(gVCD.tocent
+ [gVCD.cur_track+1
+ - gVCD.tochdr.starting_track].addr.lba);
+
+ return len * 2352; /*VCDSECTORSIZE;*/
+
+}
+#endif
+
+static uint32_t input_plugin_get_capabilities (void) {
+ return INPUT_CAP_SEEKABLE | INPUT_CAP_BLOCK | INPUT_CAP_AUTOPLAY;
+}
+
+static uint32_t input_plugin_get_blocksize (void) {
+ return VCDSECTORSIZE;
+}
+
+#if defined (__linux__)
+static int input_plugin_eject (void) {
+ int ret, status;
+
+ if((gVCD.fd = open(CDROM, O_RDONLY|O_NONBLOCK)) > -1) {
+ if((status = ioctl(gVCD.fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) > 0) {
+ switch(status) {
+ case CDS_TRAY_OPEN:
+ if((ret = ioctl(gVCD.fd, CDROMCLOSETRAY)) != 0) {
+ xprintf(VERBOSE|INPUT, "CDROMCLOSETRAY failed: %s\n", strerror(errno));
+ }
+ break;
+ case CDS_DISC_OK:
+ if((ret = ioctl(gVCD.fd, CDROMEJECT)) != 0) {
+ xprintf(VERBOSE|INPUT, "CDROMEJECT failed: %s\n", strerror(errno));
+ }
+ break;
+ }
+ }
+ else {
+ xprintf(VERBOSE|INPUT, "CDROM_DRIVE_STATUS failed: %s\n",
+ strerror(errno));
+ close(gVCD.fd);
+ return 0;
+ }
+ }
+
+ close(gVCD.fd);
+
+ return 1;
+}
+#elif defined (__FreeBSD__)
+static int input_plugin_eject (void) {
+ int fd;
+
+ if ((fd = open(CDROM, O_RDONLY|O_NONBLOCK)) > -1) {
+ if (ioctl(fd, CDIOCALLOW) == -1) {
+ perror("ioctl(cdromallow)");
+ } else {
+ if (ioctl(fd, CDIOCEJECT) == -1) {
+ perror("ioctl(cdromeject)");
+ }
+ }
+ close(fd);
+ }
+
+ return 1;
+}
+#endif
+
+static void input_plugin_close (void) {
+ xprintf (VERBOSE|INPUT, "closing input\n");
+
+ close(gVCD.fd);
+ gVCD.fd = -1;
+}
+
+static char *input_plugin_get_identifier (void) {
+ return "VCD";
+}
+
+static char **input_plugin_get_autoplay_list (int *nFiles) {
+
+ int i;
+
+ gVCD.fd = open (CDROM, O_RDONLY);
+
+ if (gVCD.fd == -1) {
+ perror ("unable to open /dev/cdrom");
+ return NULL;
+ }
+
+ if (input_vcd_read_toc ()) {
+ close (gVCD.fd);
+ gVCD.fd = -1;
+
+ printf ("vcd_read_toc failed\n");
+
+ return NULL;
+ }
+
+ close (gVCD.fd);
+ gVCD.fd = -1;
+
+ *nFiles = gVCD.total_tracks;
+
+ /* printf ("%d tracks\n",gVCD.total_tracks); */
+
+ for (i=1; i<gVCD.total_tracks; i++) { /* FIXME: check if track 0 contains valid data */
+ sprintf (gVCD.filelist[i-1], "vcd://%d",i);
+ /* printf ("list[%d] : %d %s\n", i, gVCD.filelist[i-1], gVCD.filelist[i-1]); */
+ }
+
+ return gVCD.filelist;
+}
+
+static int input_plugin_is_branch_possible (const char *next_mrl) {
+
+ char *filename;
+ int track;
+
+ if (strncasecmp (next_mrl, "vcd://",6))
+ return 0;
+
+ filename = (char *) &next_mrl[6];
+
+ if (sscanf (filename, "%d", &track) != 1) {
+ return 0;
+ }
+
+ if ((track>=gVCD.total_tracks) || (track != (gVCD.cur_track+1)))
+ return 0;
+
+ return 1;
+}
+
+
+static input_plugin_t plugin_op = {
+ NULL,
+ NULL,
+ input_plugin_init,
+ input_plugin_open,
+ input_plugin_read,
+ input_plugin_seek,
+ input_plugin_get_length,
+ input_plugin_get_capabilities,
+ NULL,
+ input_plugin_get_blocksize,
+ input_plugin_eject,
+ input_plugin_close,
+ input_plugin_get_identifier,
+ input_plugin_get_autoplay_list,
+ input_plugin_is_branch_possible,
+ NULL
+};
+
+input_plugin_t *input_plugin_getinfo(uint32_t dbglvl) {
+
+ xine_debug = dbglvl;
+
+ return &plugin_op;
+}
+
+
diff --git a/src/libac3/Makefile.am b/src/libac3/Makefile.am
new file mode 100644
index 000000000..6318b3255
--- /dev/null
+++ b/src/libac3/Makefile.am
@@ -0,0 +1,47 @@
+CFLAGS = @BUILD_LIB_STATIC@ @GLOBAL_CFLAGS@
+
+noinst_LTLIBRARIES = libac3.la
+
+libac3_la_SOURCES = bitstream.c bit_allocate.c \
+ decode.c coeff.c exponent.c parse.c crc.c rematrix.c \
+ dither.c sanity_check.c srfft.c imdct.c downmix.c
+
+noinst_HEADERS = ac3.h ac3_internal.h bitstream.h \
+ imdct.h coeff.h exponent.h bit_allocate.h parse.h \
+ crc.h rematrix.h downmix.h dither.h \
+ sanity_check.h srfft.h srfftp.h cmplx.h decode.h \
+ bswap.h
+
+##
+## Install header files (default=$includedir/xine)
+##
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)/xine
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p; \
+ done
+
+
+##
+## Remove them
+##
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/xine/$$p; \
+ done
+
+
+debug:
+ $(MAKE) CFLAGS="$(DEBUG_CFLAGS)"
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/libac3/ac3.h b/src/libac3/ac3.h
new file mode 100644
index 000000000..dcc125f85
--- /dev/null
+++ b/src/libac3/ac3.h
@@ -0,0 +1,54 @@
+/*
+ * ac3.h
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+#ifndef __AC3_H__
+#define __AC3_H__
+
+#include <inttypes.h>
+#include "audio_out.h"
+
+#define AC3_DOLBY_SURR_ENABLE (1<<0)
+#define AC3_ALTIVEC_ENABLE (1<<1)
+#define AC3_3DNOW_ENABLE (1<<2)
+#define AC3_MMX_ENABLE (1<<3)
+#define AC3_SSE_ENABLE (1<<4)
+
+typedef struct ac3_config_s {
+ // Bit flags that enable various things
+ uint32_t flags;
+ //Callback that points the decoder to new stream data
+ void (*fill_buffer_callback)(uint8_t **, uint8_t **);
+ // Number of discrete channels in final output (for downmixing)
+ uint16_t num_output_ch;
+ // Which channel of a dual mono stream to select
+ uint16_t dual_mono_ch_sel;
+} ac3_config_t;
+
+void ac3_init(ac3_config_t *,ao_functions_t*);
+
+size_t ac3_decode_data(uint8_t *data_start,uint8_t *data_end,uint32_t pts);
+
+void ac3_reset(void);
+
+#endif
diff --git a/src/libac3/ac3_internal.h b/src/libac3/ac3_internal.h
new file mode 100644
index 000000000..cac0c7940
--- /dev/null
+++ b/src/libac3/ac3_internal.h
@@ -0,0 +1,359 @@
+/*
+ * ac3_internal.h
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef __GNUC__
+#define inline
+#endif
+
+#define FAST_ERROR
+#ifdef FAST_ERROR
+#include <setjmp.h>
+#endif
+
+/* Exponent strategy constants */
+#define EXP_REUSE (0)
+#define EXP_D15 (1)
+#define EXP_D25 (2)
+#define EXP_D45 (3)
+
+/* Delta bit allocation constants */
+#define DELTA_BIT_REUSE (0)
+#define DELTA_BIT_NEW (1)
+#define DELTA_BIT_NONE (2)
+#define DELTA_BIT_RESERVED (3)
+
+/* samples work structure */
+typedef float stream_samples_t[6][256];
+
+/* global config structure */
+extern ac3_config_t ac3_config;
+/* global error flag */
+#ifdef FAST_ERROR
+extern jmp_buf error_jmp_mark;
+#define HANDLE_ERROR() longjmp (error_jmp_mark, -1)
+#else
+extern uint32_t error_flag;
+#endif
+
+/* Everything you wanted to know about band structure */
+/*
+ * The entire frequency domain is represented by 256 real
+ * floating point fourier coefficients. Only the lower 253
+ * coefficients are actually utilized however. We use arrays
+ * of 256 to be efficient in some cases.
+ *
+ * The 5 full bandwidth channels (fbw) can have their higher
+ * frequencies coupled together. These coupled channels then
+ * share their high frequency components.
+ *
+ * This coupling band is broken up into 18 sub-bands starting
+ * at mantissa number 37. Each sub-band is 12 bins wide.
+ *
+ * There are 50 bit allocation sub-bands which cover the entire
+ * frequency range. The sub-bands are of non-uniform width, and
+ * approximate a 1/6 octave scale.
+ */
+
+/* The following structures are filled in by their corresponding parse_*
+ * functions. See http://www.atsc.org/Standards/A52/a_52.pdf for
+ * full details on each field. Indented fields are used to denote
+ * conditional fields.
+ */
+
+typedef struct syncinfo_s
+{
+ uint32_t magic;
+ /* Sync word == 0x0B77 */
+ uint16_t syncword;
+ /* crc for the first 5/8 of the sync block */
+ /* uint16_t crc1; */
+ /* Stream Sampling Rate (kHz) 0 = 48, 1 = 44.1, 2 = 32, 3 = reserved */
+ uint16_t fscod;
+ /* Frame size code */
+ uint16_t frmsizecod;
+
+ /* Information not in the AC-3 bitstream, but derived */
+ /* Frame size in 16 bit words */
+ uint16_t frame_size;
+ /* Bit rate in kilobits */
+ uint16_t bit_rate;
+ /* sampling rate in hertz */
+ uint32_t sampling_rate;
+} syncinfo_t;
+
+typedef struct bsi_s
+{
+ uint32_t magic;
+ /* Bit stream identification == 0x8 */
+ uint16_t bsid;
+ /* Bit stream mode */
+ uint16_t bsmod;
+ /* Audio coding mode */
+ uint16_t acmod;
+ /* If we're using the centre channel then */
+ /* centre mix level */
+ uint16_t cmixlev;
+ /* If we're using the surround channel then */
+ /* surround mix level */
+ uint16_t surmixlev;
+ /* If we're in 2/0 mode then */
+ /* Dolby surround mix level - NOT USED - */
+ uint16_t dsurmod;
+ /* Low frequency effects on */
+ uint16_t lfeon;
+ /* Dialogue Normalization level */
+ uint16_t dialnorm;
+ /* Compression exists */
+ uint16_t compre;
+ /* Compression level */
+ uint16_t compr;
+ /* Language code exists */
+ uint16_t langcode;
+ /* Language code */
+ uint16_t langcod;
+ /* Audio production info exists*/
+ uint16_t audprodie;
+ uint16_t mixlevel;
+ uint16_t roomtyp;
+ /* If we're in dual mono mode (acmod == 0) then extra stuff */
+ uint16_t dialnorm2;
+ uint16_t compr2e;
+ uint16_t compr2;
+ uint16_t langcod2e;
+ uint16_t langcod2;
+ uint16_t audprodi2e;
+ uint16_t mixlevel2;
+ uint16_t roomtyp2;
+ /* Copyright bit */
+ uint16_t copyrightb;
+ /* Original bit */
+ uint16_t origbs;
+ /* Timecode 1 exists */
+ uint16_t timecod1e;
+ /* Timecode 1 */
+ uint16_t timecod1;
+ /* Timecode 2 exists */
+ uint16_t timecod2e;
+ /* Timecode 2 */
+ uint16_t timecod2;
+ /* Additional bit stream info exists */
+ uint16_t addbsie;
+ /* Additional bit stream length - 1 (in bytes) */
+ uint16_t addbsil;
+ /* Additional bit stream information (max 64 bytes) */
+ uint8_t addbsi[64];
+
+ /* Information not in the AC-3 bitstream, but derived */
+ /* Number of channels (excluding LFE)
+ * Derived from acmod */
+ uint16_t nfchans;
+} bsi_t;
+
+
+/* more pain */
+typedef struct audblk_s
+{
+ uint32_t magic1;
+ /* block switch bit indexed by channel num */
+ uint16_t blksw[5];
+ /* dither enable bit indexed by channel num */
+ uint16_t dithflag[5];
+ /* dynamic range gain exists */
+ uint16_t dynrnge;
+ /* dynamic range gain */
+ uint16_t dynrng;
+ /* if acmod==0 then */
+ /* dynamic range 2 gain exists */
+ uint16_t dynrng2e;
+ /* dynamic range 2 gain */
+ uint16_t dynrng2;
+ /* coupling strategy exists */
+ uint16_t cplstre;
+ /* coupling in use */
+ uint16_t cplinu;
+ /* channel coupled */
+ uint16_t chincpl[5];
+ /* if acmod==2 then */
+ /* Phase flags in use */
+ uint16_t phsflginu;
+ /* coupling begin frequency code */
+ uint16_t cplbegf;
+ /* coupling end frequency code */
+ uint16_t cplendf;
+ /* coupling band structure bits */
+ uint16_t cplbndstrc[18];
+ /* Do coupling co-ords exist for this channel? */
+ uint16_t cplcoe[5];
+ /* Master coupling co-ordinate */
+ uint16_t mstrcplco[5];
+ /* Per coupling band coupling co-ordinates */
+ uint16_t cplcoexp[5][18];
+ uint16_t cplcomant[5][18];
+ /* Phase flags for dual mono */
+ uint16_t phsflg[18];
+ /* Is there a rematrixing strategy */
+ uint16_t rematstr;
+ /* Rematrixing bits */
+ uint16_t rematflg[4];
+ /* Coupling exponent strategy */
+ uint16_t cplexpstr;
+ /* Exponent strategy for full bandwidth channels */
+ uint16_t chexpstr[5];
+ /* Exponent strategy for lfe channel */
+ uint16_t lfeexpstr;
+ /* Channel bandwidth for independent channels */
+ uint16_t chbwcod[5];
+ /* The absolute coupling exponent */
+ uint16_t cplabsexp;
+ /* Coupling channel exponents (D15 mode gives 18 * 12 /3 encoded exponents */
+ uint16_t cplexps[18 * 12 / 3];
+ /* Sanity checking constant */
+ uint32_t magic2;
+ /* fbw channel exponents */
+ uint16_t exps[5][252 / 3];
+ /* channel gain range */
+ uint16_t gainrng[5];
+ /* low frequency exponents */
+ uint16_t lfeexps[3];
+
+ /* Bit allocation info */
+ uint16_t baie;
+ /* Slow decay code */
+ uint16_t sdcycod;
+ /* Fast decay code */
+ uint16_t fdcycod;
+ /* Slow gain code */
+ uint16_t sgaincod;
+ /* dB per bit code */
+ uint16_t dbpbcod;
+ /* masking floor code */
+ uint16_t floorcod;
+
+ /* SNR offset info */
+ uint16_t snroffste;
+ /* coarse SNR offset */
+ uint16_t csnroffst;
+ /* coupling fine SNR offset */
+ uint16_t cplfsnroffst;
+ /* coupling fast gain code */
+ uint16_t cplfgaincod;
+ /* fbw fine SNR offset */
+ uint16_t fsnroffst[5];
+ /* fbw fast gain code */
+ uint16_t fgaincod[5];
+ /* lfe fine SNR offset */
+ uint16_t lfefsnroffst;
+ /* lfe fast gain code */
+ uint16_t lfefgaincod;
+
+ /* Coupling leak info */
+ uint16_t cplleake;
+ /* coupling fast leak initialization */
+ uint16_t cplfleak;
+ /* coupling slow leak initialization */
+ uint16_t cplsleak;
+
+ /* delta bit allocation info */
+ uint16_t deltbaie;
+ /* coupling delta bit allocation exists */
+ uint16_t cpldeltbae;
+ /* fbw delta bit allocation exists */
+ uint16_t deltbae[5];
+ /* number of cpl delta bit segments */
+ uint16_t cpldeltnseg;
+ /* coupling delta bit allocation offset */
+ uint16_t cpldeltoffst[8];
+ /* coupling delta bit allocation length */
+ uint16_t cpldeltlen[8];
+ /* coupling delta bit allocation length */
+ uint16_t cpldeltba[8];
+ /* number of delta bit segments */
+ uint16_t deltnseg[5];
+ /* fbw delta bit allocation offset */
+ uint16_t deltoffst[5][8];
+ /* fbw delta bit allocation length */
+ uint16_t deltlen[5][8];
+ /* fbw delta bit allocation length */
+ uint16_t deltba[5][8];
+
+ /* skip length exists */
+ uint16_t skiple;
+ /* skip length */
+ uint16_t skipl;
+
+ //Removed Feb 2000 -ah
+ //added Jul 2000 ++dent
+ /* channel mantissas */
+ uint16_t chmant[5][256];
+
+ /* coupling mantissas */
+// uint16_t cplmant[256];
+
+ //Added Jun 2000 -MaXX
+ /* coupling floats */
+ float cpl_flt[ 256 ];
+
+ //Removed Feb 2000 -ah
+ //added Jul 2000 ++dent
+ /* coupling mantissas */
+ uint16_t lfemant[7];
+
+
+ /* -- Information not in the bitstream, but derived thereof -- */
+
+ /* Number of coupling sub-bands */
+ uint16_t ncplsubnd;
+
+ /* Number of combined coupling sub-bands
+ * Derived from ncplsubnd and cplbndstrc */
+ uint16_t ncplbnd;
+
+ /* Number of exponent groups by channel
+ * Derived from strmant, endmant */
+ uint16_t nchgrps[5];
+
+ /* Number of coupling exponent groups
+ * Derived from cplbegf, cplendf, cplexpstr */
+ uint16_t ncplgrps;
+
+ /* End mantissa numbers of fbw channels */
+ uint16_t endmant[5];
+
+ /* Start and end mantissa numbers for the coupling channel */
+ uint16_t cplstrtmant;
+ uint16_t cplendmant;
+
+ /* Decoded exponent info */
+ uint16_t fbw_exp[5][256];
+ uint16_t cpl_exp[256];
+ uint16_t lfe_exp[7];
+
+ /* Bit allocation pointer results */
+ uint16_t fbw_bap[5][256];
+ uint16_t cpl_bap[256];
+ uint16_t lfe_bap[7];
+
+ uint32_t magic3;
+} audblk_t;
+
+
diff --git a/src/libac3/bit_allocate.c b/src/libac3/bit_allocate.c
new file mode 100644
index 000000000..7a233a519
--- /dev/null
+++ b/src/libac3/bit_allocate.c
@@ -0,0 +1,509 @@
+/*
+ * bit_allocate.c
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include "ac3.h"
+#include "ac3_internal.h"
+
+
+
+static inline int16_t logadd(int16_t a,int16_t b);
+static int16_t calc_lowcomp(int16_t a,int16_t b0,int16_t b1,int16_t bin);
+static inline uint16_t min(int16_t a,int16_t b);
+static inline uint16_t max(int16_t a,int16_t b);
+static void ba_compute_psd(int16_t start, int16_t end, int16_t exps[],
+ int16_t psd[], int16_t bndpsd[]);
+
+static void ba_compute_excitation(int16_t start, int16_t end,int16_t fgain,
+ int16_t fastleak, int16_t slowleak, int16_t is_lfe, int16_t bndpsd[],
+ int16_t excite[]);
+static void ba_compute_mask(int16_t start, int16_t end, uint16_t fscod,
+ uint16_t deltbae, uint16_t deltnseg, uint16_t deltoffst[], uint16_t deltba[],
+ uint16_t deltlen[], int16_t excite[], int16_t mask[]);
+static void ba_compute_bap(int16_t start, int16_t end, int16_t snroffset,
+ int16_t psd[], int16_t mask[], int16_t bap[]);
+
+/* Misc LUTs for bit allocation process */
+
+static int16_t slowdec[] = { 0x0f, 0x11, 0x13, 0x15 };
+static int16_t fastdec[] = { 0x3f, 0x53, 0x67, 0x7b };
+static int16_t slowgain[] = { 0x540, 0x4d8, 0x478, 0x410 };
+static int16_t dbpbtab[] = { 0x000, 0x700, 0x900, 0xb00 };
+
+static uint16_t floortab[] = { 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800 };
+static int16_t fastgain[] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 };
+
+
+static int16_t bndtab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 28, 31,
+ 34, 37, 40, 43, 46, 49, 55, 61, 67, 73,
+ 79, 85, 97, 109, 121, 133, 157, 181, 205, 229 };
+
+static int16_t bndsz[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
+ 3, 3, 3, 3, 3, 6, 6, 6, 6, 6,
+ 6, 12, 12, 12, 12, 24, 24, 24, 24, 24 };
+
+static int16_t masktab[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 28, 29,
+ 29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34,
+ 34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37,
+ 37, 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 40,
+ 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43,
+ 43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44,
+ 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46,
+ 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+ 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
+ 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48,
+ 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+ 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 0, 0, 0 };
+
+
+static int16_t latab[] = { 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003b, 0x003a, 0x0039,
+ 0x0038, 0x0037, 0x0036, 0x0035, 0x0034, 0x0034, 0x0033, 0x0032,
+ 0x0031, 0x0030, 0x002f, 0x002f, 0x002e, 0x002d, 0x002c, 0x002c,
+ 0x002b, 0x002a, 0x0029, 0x0029, 0x0028, 0x0027, 0x0026, 0x0026,
+ 0x0025, 0x0024, 0x0024, 0x0023, 0x0023, 0x0022, 0x0021, 0x0021,
+ 0x0020, 0x0020, 0x001f, 0x001e, 0x001e, 0x001d, 0x001d, 0x001c,
+ 0x001c, 0x001b, 0x001b, 0x001a, 0x001a, 0x0019, 0x0019, 0x0018,
+ 0x0018, 0x0017, 0x0017, 0x0016, 0x0016, 0x0015, 0x0015, 0x0015,
+ 0x0014, 0x0014, 0x0013, 0x0013, 0x0013, 0x0012, 0x0012, 0x0012,
+ 0x0011, 0x0011, 0x0011, 0x0010, 0x0010, 0x0010, 0x000f, 0x000f,
+ 0x000f, 0x000e, 0x000e, 0x000e, 0x000d, 0x000d, 0x000d, 0x000d,
+ 0x000c, 0x000c, 0x000c, 0x000c, 0x000b, 0x000b, 0x000b, 0x000b,
+ 0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0009, 0x0009, 0x0009,
+ 0x0009, 0x0009, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
+ 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0006, 0x0006,
+ 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0005, 0x0005,
+ 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0004, 0x0004,
+ 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
+ 0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003,
+ 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002,
+ 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+ 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
+ 0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
+ 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
+ 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
+ 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
+ 0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000};
+
+static int16_t hth[][50] = {{ 0x04d0, 0x04d0, 0x0440, 0x0400, 0x03e0, 0x03c0, 0x03b0, 0x03b0,
+ 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390,
+ 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360, 0x0350, 0x0350,
+ 0x0340, 0x0340, 0x0330, 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0,
+ 0x02f0, 0x02f0, 0x0300, 0x0310, 0x0340, 0x0390, 0x03e0, 0x0420,
+ 0x0460, 0x0490, 0x04a0, 0x0460, 0x0440, 0x0440, 0x0520, 0x0800,
+ 0x0840, 0x0840 },
+
+ { 0x04f0, 0x04f0, 0x0460, 0x0410, 0x03e0, 0x03d0, 0x03c0, 0x03b0,
+ 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390,
+ 0x0390, 0x0380, 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360,
+ 0x0350, 0x0350, 0x0340, 0x0340, 0x0320, 0x0310, 0x0300, 0x02f0,
+ 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0320, 0x0350, 0x0390, 0x03e0,
+ 0x0420, 0x0450, 0x04a0, 0x0490, 0x0460, 0x0440, 0x0480, 0x0630,
+ 0x0840, 0x0840 },
+
+ { 0x0580, 0x0580, 0x04b0, 0x0450, 0x0420, 0x03f0, 0x03e0, 0x03d0,
+ 0x03c0, 0x03b0, 0x03b0, 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0,
+ 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390, 0x0390,
+ 0x0380, 0x0380, 0x0380, 0x0370, 0x0360, 0x0350, 0x0340, 0x0330,
+ 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0310,
+ 0x0330, 0x0350, 0x03c0, 0x0410, 0x0470, 0x04a0, 0x0460, 0x0440,
+ 0x0450, 0x04e0 }};
+
+
+static int16_t baptab[] = { 0, 1, 1, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
+ 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10,
+ 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14,
+ 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15 };
+
+static int16_t sdecay;
+static int16_t fdecay;
+static int16_t sgain;
+static int16_t dbknee;
+static int16_t floor;
+static int16_t psd[256];
+static int16_t bndpsd[256];
+static int16_t excite[256];
+static int16_t mask[256];
+
+
+/**
+ *
+ **/
+
+static inline uint16_t max(int16_t a,int16_t b)
+{
+ return (a > b ? a : b);
+}
+
+
+/**
+ *
+ **/
+
+static inline uint16_t min(int16_t a,int16_t b)
+{
+ return (a < b ? a : b);
+}
+
+
+/**
+ *
+ **/
+
+static inline int16_t logadd(int16_t a,int16_t b)
+{
+ int16_t c;
+ int16_t address;
+
+ c = a - b;
+ address = min((abs(c) >> 1), 255);
+
+ if (c >= 0)
+ return(a + latab[address]);
+ else
+ return(b + latab[address]);
+}
+
+
+/**
+ *
+ **/
+
+void bit_allocate(uint16_t fscod, bsi_t *bsi, audblk_t *audblk)
+{
+ uint16_t i;
+ int16_t fgain;
+ int16_t snroffset;
+ int16_t start;
+ int16_t end;
+ int16_t fastleak;
+ int16_t slowleak;
+
+ /* Only perform bit_allocation if the exponents have changed or we
+ * have new sideband information */
+ if (audblk->chexpstr[0] == 0 && audblk->chexpstr[1] == 0 &&
+ audblk->chexpstr[2] == 0 && audblk->chexpstr[3] == 0 &&
+ audblk->chexpstr[4] == 0 && audblk->cplexpstr == 0 &&
+ audblk->lfeexpstr == 0 && audblk->baie == 0 &&
+ audblk->snroffste == 0 && audblk->deltbaie == 0)
+ return;
+
+ /* Do some setup before we do the bit alloc */
+ sdecay = slowdec[audblk->sdcycod];
+ fdecay = fastdec[audblk->fdcycod];
+ sgain = slowgain[audblk->sgaincod];
+ dbknee = dbpbtab[audblk->dbpbcod];
+ floor = floortab[audblk->floorcod];
+
+ /* if all the SNR offset constants are zero then the whole block is zero */
+ if(!audblk->csnroffst && !audblk->fsnroffst[0] &&
+ !audblk->fsnroffst[1] && !audblk->fsnroffst[2] &&
+ !audblk->fsnroffst[3] && !audblk->fsnroffst[4] &&
+ !audblk->cplfsnroffst && !audblk->lfefsnroffst) {
+ memset(audblk->fbw_bap,0,sizeof(uint16_t) * 256 * 5);
+ memset(audblk->cpl_bap,0,sizeof(uint16_t) * 256);
+ memset(audblk->lfe_bap,0,sizeof(uint16_t) * 7);
+ return;
+ }
+
+
+ for(i = 0; i < bsi->nfchans; i++)
+ {
+ start = 0;
+ end = audblk->endmant[i] ;
+ fgain = fastgain[audblk->fgaincod[i]];
+ snroffset = (((audblk->csnroffst - 15) << 4) + audblk->fsnroffst[i]) << 2 ;
+ fastleak = 0;
+ slowleak = 0;
+
+ ba_compute_psd(start, end, audblk->fbw_exp[i], psd, bndpsd);
+
+ ba_compute_excitation(start, end , fgain, fastleak, slowleak, 0, bndpsd, excite);
+
+ ba_compute_mask(start, end, fscod, audblk->deltbae[i], audblk->deltnseg[i],
+ audblk->deltoffst[i], audblk->deltba[i], audblk->deltlen[i], excite, mask);
+
+ ba_compute_bap(start, end, snroffset, psd, mask, audblk->fbw_bap[i]);
+ }
+
+ if(audblk->cplinu) {
+ start = audblk->cplstrtmant;
+ end = audblk->cplendmant;
+ fgain = fastgain[audblk->cplfgaincod];
+ snroffset = (((audblk->csnroffst - 15) << 4) + audblk->cplfsnroffst) << 2 ;
+ fastleak = (audblk->cplfleak << 8) + 768;
+ slowleak = (audblk->cplsleak << 8) + 768;
+
+ ba_compute_psd(start, end, audblk->cpl_exp, psd, bndpsd);
+
+ ba_compute_excitation(start, end , fgain, fastleak, slowleak, 0, bndpsd, excite);
+
+ ba_compute_mask(start, end, fscod, audblk->cpldeltbae, audblk->cpldeltnseg,
+ audblk->cpldeltoffst, audblk->cpldeltba, audblk->cpldeltlen, excite, mask);
+
+ ba_compute_bap(start, end, snroffset, psd, mask, audblk->cpl_bap);
+ }
+
+ if(bsi->lfeon) {
+ start = 0;
+ end = 7;
+ fgain = fastgain[audblk->lfefgaincod];
+ snroffset = (((audblk->csnroffst - 15) << 4) + audblk->lfefsnroffst) << 2 ;
+ fastleak = 0;
+ slowleak = 0;
+
+ ba_compute_psd(start, end, audblk->lfe_exp, psd, bndpsd);
+
+ ba_compute_excitation(start, end , fgain, fastleak, slowleak, 1, bndpsd, excite);
+
+ /* Perform no delta bit allocation for lfe */
+ ba_compute_mask(start, end, fscod, 2, 0, 0, 0, 0, excite, mask);
+
+ ba_compute_bap(start, end, snroffset, psd, mask, audblk->lfe_bap);
+ }
+}
+
+
+/**
+ *
+ **/
+
+static void ba_compute_psd(int16_t start, int16_t end, int16_t exps[],
+ int16_t psd[], int16_t bndpsd[])
+{
+ int bin,j,k;
+ int16_t lastbin = 0;
+
+ /* Map the exponents into dBs */
+ for (bin=start; bin<end; bin++) {
+ psd[bin] = (3072 - (exps[bin] << 7));
+ }
+
+ /* Integrate the psd function over each bit allocation band */
+ j = start;
+ k = masktab[start];
+
+ do {
+ lastbin = min(bndtab[k] + bndsz[k], end);
+ bndpsd[k] = psd[j];
+ j++;
+
+ for (; j < lastbin; j++) {
+ bndpsd[k] = logadd(bndpsd[k], psd[j]);
+ }
+
+ k++;
+ } while (end > lastbin);
+}
+
+
+/**
+ *
+ **/
+
+static void ba_compute_excitation(int16_t start, int16_t end,int16_t fgain,
+ int16_t fastleak, int16_t slowleak, int16_t is_lfe, int16_t bndpsd[],
+ int16_t excite[])
+{
+ int bin;
+ int16_t bndstrt;
+ int16_t bndend;
+ int16_t lowcomp = 0;
+ int16_t begin = 0;
+
+ /* Compute excitation function */
+ bndstrt = masktab[start];
+ bndend = masktab[end - 1] + 1;
+
+ if (bndstrt == 0) { /* For fbw and lfe channels */
+ lowcomp = calc_lowcomp(lowcomp, bndpsd[0], bndpsd[1], 0);
+ excite[0] = bndpsd[0] - fgain - lowcomp;
+ lowcomp = calc_lowcomp(lowcomp, bndpsd[1], bndpsd[2], 1);
+ excite[1] = bndpsd[1] - fgain - lowcomp;
+ begin = 7 ;
+
+// Note: Do not call calc_lowcomp() for the last band of the lfe channel,(bin=6)
+ for (bin = 2; bin < 7; bin++) {
+ if (!(is_lfe && (bin == 6)))
+ lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin);
+ fastleak = bndpsd[bin] - fgain;
+ slowleak = bndpsd[bin] - sgain;
+ excite[bin] = fastleak - lowcomp;
+
+ if (!(is_lfe && (bin == 6))) {
+ if (bndpsd[bin] <= bndpsd[bin+1]) {
+ begin = bin + 1 ;
+ break;
+ }
+ }
+ }
+
+ for (bin = begin; bin < min(bndend, 22); bin++) {
+ if (!(is_lfe && (bin == 6)))
+ lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin);
+ fastleak -= fdecay ;
+ fastleak = max(fastleak, bndpsd[bin] - fgain);
+ slowleak -= sdecay ;
+ slowleak = max(slowleak, bndpsd[bin] - sgain);
+ excite[bin] = max(fastleak - lowcomp, slowleak);
+ }
+ begin = 22;
+ }
+ else /* For coupling channel */
+ begin = bndstrt;
+
+ for (bin = begin; bin < bndend; bin++) {
+ fastleak -= fdecay;
+ fastleak = max(fastleak, bndpsd[bin] - fgain);
+ slowleak -= sdecay;
+ slowleak = max(slowleak, bndpsd[bin] - sgain);
+ excite[bin] = max(fastleak, slowleak) ;
+ }
+}
+
+
+/**
+ *
+ **/
+
+static void ba_compute_mask(int16_t start, int16_t end, uint16_t fscod,
+ uint16_t deltbae, uint16_t deltnseg, uint16_t deltoffst[], uint16_t deltba[],
+ uint16_t deltlen[], int16_t excite[], int16_t mask[])
+{
+ int bin,k;
+ int16_t bndstrt;
+ int16_t bndend;
+ int16_t delta;
+
+ bndstrt = masktab[start];
+ bndend = masktab[end - 1] + 1;
+
+ /* Compute the masking curve */
+
+ for (bin = bndstrt; bin < bndend; bin++) {
+ if (bndpsd[bin] < dbknee) {
+ excite[bin] += ((dbknee - bndpsd[bin]) >> 2);
+ }
+ mask[bin] = max(excite[bin], hth[fscod][bin]);
+ }
+
+ /* Perform delta bit modulation if necessary */
+ if ((deltbae == DELTA_BIT_REUSE) || (deltbae == DELTA_BIT_NEW)) {
+ int16_t band = 0;
+ int16_t seg = 0;
+
+ for (seg = 0; seg < deltnseg+1; seg++) {
+ band += deltoffst[seg];
+
+ if (deltba[seg] >= 4) {
+ delta = (deltba[seg] - 3) << 7;
+ } else {
+ delta = (deltba[seg] - 4) << 7;
+ }
+
+ for (k = 0; k < deltlen[seg]; k++) {
+ mask[band] += delta;
+ band++;
+ }
+ }
+ }
+}
+
+
+/**
+ *
+ **/
+
+static void ba_compute_bap(int16_t start, int16_t end, int16_t snroffset,
+ int16_t psd[], int16_t mask[], int16_t bap[])
+{
+ int i,j,k;
+ int16_t lastbin = 0;
+ int16_t address = 0;
+
+ /* Compute the bit allocation pointer for each bin */
+ i = start;
+ j = masktab[start];
+
+ do {
+ lastbin = min(bndtab[j] + bndsz[j], end);
+ mask[j] -= snroffset;
+ mask[j] -= floor;
+
+ if (mask[j] < 0)
+ mask[j] = 0;
+
+ mask[j] &= 0x1fe0;
+ mask[j] += floor;
+ for (k = i; k < lastbin; k++) {
+ address = (psd[i] - mask[j]) >> 5;
+ address = min(63, max(0, address));
+ bap[i] = baptab[address];
+ i++;
+ }
+ j++;
+ } while (end > lastbin);
+}
+
+
+/**
+ *
+ **/
+
+static int16_t calc_lowcomp (int16_t a, int16_t b0, int16_t b1, int16_t bin)
+{
+
+ if (bin < 7) {
+ if ((b0 + 256) == b1)
+ a = 384;
+ else if (b0 > b1)
+ a = max(0, a - 64);
+ } else if (bin < 20) {
+ if ((b0 + 256) == b1)
+ a = 320;
+ else if (b0 > b1)
+ a = max(0, a - 64) ;
+ } else
+ a = max(0, a - 128);
+
+ return(a);
+}
+
diff --git a/src/libac3/bit_allocate.h b/src/libac3/bit_allocate.h
new file mode 100644
index 000000000..a6a3c7703
--- /dev/null
+++ b/src/libac3/bit_allocate.h
@@ -0,0 +1,24 @@
+/*
+ * bit_allocate.h
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+void bit_allocate(uint16_t fscod, bsi_t *bsi, audblk_t *audblk);
diff --git a/src/libac3/bitstream.c b/src/libac3/bitstream.c
new file mode 100644
index 000000000..78ac0eca7
--- /dev/null
+++ b/src/libac3/bitstream.c
@@ -0,0 +1,79 @@
+/*
+ * bitstream.c
+ *
+ * Copyright (C) Aaron Holtzman - Dec 1999
+ *
+ * This file is part of ac3dec, a free AC-3 audio decoder
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+
+#include <bswap.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ac3.h"
+#include "ac3_internal.h"
+#include "bitstream.h"
+
+
+uint32_t ac3bits_left = 0;
+uint64_t ac3current_word;
+uint64_t *buffer_start = 0;
+
+
+static inline uint64_t getdword (void)
+{
+ return be2me_64 (*buffer_start++);
+}
+
+
+static inline void bitstream_fill_current (void)
+{
+ //ac3current_word = bswap_64 (*buffer_start++);
+ ac3current_word = getdword ();
+}
+
+
+uint32_t bitstream_get_bh (uint32_t num_bits)
+{
+ uint32_t result;
+
+ num_bits -= ac3bits_left;
+ result = (ac3current_word << (64 - ac3bits_left)) >> (64 - ac3bits_left);
+
+ bitstream_fill_current();
+
+ if(num_bits != 0)
+ result = (result << num_bits) | (ac3current_word >> (64 - num_bits));
+
+ ac3bits_left = 64 - num_bits;
+
+ return result;
+}
+
+
+void bitstream_init (uint8_t *start)
+{
+ //initialize the start of the buffer
+ buffer_start = (uint64_t *) start;
+ ac3bits_left = 0;
+}
diff --git a/src/libac3/bitstream.h b/src/libac3/bitstream.h
new file mode 100644
index 000000000..392c7401c
--- /dev/null
+++ b/src/libac3/bitstream.h
@@ -0,0 +1,46 @@
+/*
+ * bitstream.h
+ *
+ * Copyright (C) Aaron Holtzman - Dec 1999
+ *
+ * This file is part of ac3dec, a free AC-3 audio decoder
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#include <inttypes.h>
+
+extern uint32_t ac3bits_left;
+extern uint64_t ac3current_word;
+
+void bitstream_init(uint8_t *start);
+inline uint32_t bitstream_get_bh(uint32_t num_bits);
+
+static inline uint32_t bitstream_get (uint32_t num_bits)
+{
+ uint32_t result;
+
+ if (num_bits < ac3bits_left) {
+ result = (ac3current_word << (64 - ac3bits_left)) >> (64 - num_bits);
+ ac3bits_left -= num_bits;
+ return result;
+ }
+
+ return bitstream_get_bh (num_bits);
+}
+
+
diff --git a/src/libac3/bswap.h b/src/libac3/bswap.h
new file mode 100644
index 000000000..0fc325d64
--- /dev/null
+++ b/src/libac3/bswap.h
@@ -0,0 +1,60 @@
+#ifndef __BSWAP_H__
+#define __BSWAP_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_BYTESWAP_H
+#include <byteswap.h>
+#else
+
+#include <inttypes.h>
+
+#ifdef WORDS_BIGENDIAN
+// FIXME these need to actually swap ;)
+#define bswap_16(x) (x)
+#define bswap_32(x) (x)
+#define bswap_64(x) (x)
+#else
+// This is wrong, 'cannot take address of ...'
+#define bswap_16(x) ((((uint8_t*)&x)[2] << 8) \
+ | (((uint8_t*)&x)[3]))
+
+// code from bits/byteswap.h (C) 1997, 1998 Free Software Foundation, Inc.
+#define bswap_32(x) \
+ ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
+ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
+
+#define bswap_64(x) \
+ (__extension__ \
+ ({ union { __extension__ uint64_t __ll; \
+ uint32_t __l[2]; } __w, __r; \
+ __w.__ll = (x); \
+ __r.__l[0] = bswap_32 (__w.__l[1]); \
+ __r.__l[1] = bswap_32 (__w.__l[0]); \
+ __r.__ll; }))
+#endif
+
+#endif
+
+// be2me ... BigEndian to MachineEndian
+// le2me ... LittleEndian to MachineEndian
+
+#ifdef WORDS_BIGENDIAN
+#define be2me_16(x) (x)
+#define be2me_32(x) (x)
+#define be2me_64(x) (x)
+#define le2me_16(x) bswap_16(x)
+#define le2me_32(x) bswap_32(x)
+#define le2me_64(x) bswap_64(x)
+#else
+#define be2me_16(x) bswap_16(x)
+#define be2me_32(x) bswap_32(x)
+#define be2me_64(x) bswap_64(x)
+#define le2me_16(x) (x)
+#define le2me_32(x) (x)
+#define le2me_64(x) (x)
+#endif
+
+#endif
diff --git a/src/libac3/cmplx.h b/src/libac3/cmplx.h
new file mode 100644
index 000000000..a357fab38
--- /dev/null
+++ b/src/libac3/cmplx.h
@@ -0,0 +1,9 @@
+#ifndef __COMPLEX_H__
+#define __COMPLEX_H__
+
+typedef struct complex {
+ float re;
+ float im;
+} complex_t;
+
+#endif
diff --git a/src/libac3/coeff.c b/src/libac3/coeff.c
new file mode 100644
index 000000000..6c95f74a5
--- /dev/null
+++ b/src/libac3/coeff.c
@@ -0,0 +1,437 @@
+/*
+ * coeff.c
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "ac3.h"
+#include "ac3_internal.h"
+
+
+#include "bitstream.h"
+#include "dither.h"
+#include "coeff.h"
+
+//
+//Lookup tables of 0.15 two's complement quantization values
+//
+#define Q0 ((-2 << 15) / 3.0)
+#define Q1 (0)
+#define Q2 ((2 << 15) / 3.0)
+
+static const float q_1_0[ 32 ] =
+{
+ Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,
+ Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,
+ Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,
+ 0,0,0,0,0
+};
+
+static const float q_1_1[ 32 ] =
+{
+ Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2,
+ Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2,
+ Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2,
+ 0,0,0,0,0
+};
+
+static const float q_1_2[ 32 ] =
+{
+ Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2,
+ Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2,
+ Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2,
+ 0,0,0,0,0
+};
+
+#undef Q0
+#undef Q1
+#undef Q2
+
+#define Q0 ((-4 << 15) / 5.0)
+#define Q1 ((-2 << 15) / 5.0)
+#define Q2 (0)
+#define Q3 ((2 << 15) / 5.0)
+#define Q4 ((4 << 15) / 5.0)
+
+static const float q_2_0[ 128 ] =
+{
+ Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,
+ Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,
+ Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,
+ Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,
+ Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,
+ Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,
+ Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,
+ Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,
+ Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,
+ Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,
+ 0,0,0
+};
+
+static const float q_2_1[ 128 ] =
+{
+ Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,
+ Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,
+ Q4,Q4,Q4,Q4,Q4,Q0,Q0,Q0,Q0,Q0,
+ Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,
+ Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
+ Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,
+ Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,
+ Q4,Q4,Q4,Q4,Q4,Q0,Q0,Q0,Q0,Q0,
+ Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,
+ Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4,
+ Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,
+ Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,
+ Q4,Q4,Q4,Q4,Q4,0,0,0
+ };
+
+static const float q_2_2[ 128 ] =
+ {
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,
+ Q0,Q1,Q2,Q3,Q4,0,0,0
+};
+
+#undef Q0
+#undef Q1
+#undef Q2
+#undef Q3
+#undef Q4
+
+static const float q_3[7] =
+{
+ (-6 << 15)/7.0, (-4 << 15)/7.0, (-2 << 15)/7.0, 0.0,
+ ( 2 << 15)/7.0, ( 4 << 15)/7.0, ( 6 << 15)/7.0
+};
+
+#define Q0 ((-10 << 15) / 11.0)
+#define Q1 ((-8 << 15) / 11.0)
+#define Q2 ((-6 << 15) / 11.0)
+#define Q3 ((-4 << 15) / 11.0)
+#define Q4 ((-2 << 15) / 11.0)
+#define Q5 (0)
+#define Q6 ((2 << 15) / 11.0)
+#define Q7 ((4 << 15) / 11.0)
+#define Q8 ((6 << 15) / 11.0)
+#define Q9 ((8 << 15) / 11.0)
+#define QA ((10 << 15) / 11.0)
+
+static const float q_4_0[ 128 ] =
+{
+ Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0,
+ Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1,
+ Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2,
+ Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3,
+ Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4,
+ Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5,
+ Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6,
+ Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7,
+ Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8,
+ Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9,
+ QA, QA, QA, QA, QA, QA, QA, QA, QA, QA, QA,
+ 0, 0, 0, 0, 0, 0, 0
+ };
+
+static const float q_4_1[ 128 ] =
+{
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA,
+ 0, 0, 0, 0, 0, 0, 0
+};
+
+#undef Q0
+#undef Q1
+#undef Q2
+#undef Q3
+#undef Q4
+#undef Q5
+#undef Q6
+#undef Q7
+#undef Q8
+#undef Q9
+#undef QA
+
+static const float q_5[15] =
+{
+ (-14 << 15)/15.0,(-12 << 15)/15.0,(-10 << 15)/15.0,
+ ( -8 << 15)/15.0,( -6 << 15)/15.0,( -4 << 15)/15.0,
+ ( -2 << 15)/15.0, 0.0 ,( 2 << 15)/15.0,
+ ( 4 << 15)/15.0,( 6 << 15)/15.0,( 8 << 15)/15.0,
+ ( 10 << 15)/15.0,( 12 << 15)/15.0,( 14 << 15)/15.0
+};
+
+//
+// Scale factors for convert_to_float
+//
+
+static const uint32_t u32_scale_factors[25] =
+{
+ 0x38000000, //2 ^ -(0 + 15)
+ 0x37800000, //2 ^ -(1 + 15)
+ 0x37000000, //2 ^ -(2 + 15)
+ 0x36800000, //2 ^ -(3 + 15)
+ 0x36000000, //2 ^ -(4 + 15)
+ 0x35800000, //2 ^ -(5 + 15)
+ 0x35000000, //2 ^ -(6 + 15)
+ 0x34800000, //2 ^ -(7 + 15)
+ 0x34000000, //2 ^ -(8 + 15)
+ 0x33800000, //2 ^ -(9 + 15)
+ 0x33000000, //2 ^ -(10 + 15)
+ 0x32800000, //2 ^ -(11 + 15)
+ 0x32000000, //2 ^ -(12 + 15)
+ 0x31800000, //2 ^ -(13 + 15)
+ 0x31000000, //2 ^ -(14 + 15)
+ 0x30800000, //2 ^ -(15 + 15)
+ 0x30000000, //2 ^ -(16 + 15)
+ 0x2f800000, //2 ^ -(17 + 15)
+ 0x2f000000, //2 ^ -(18 + 15)
+ 0x2e800000, //2 ^ -(19 + 15)
+ 0x2e000000, //2 ^ -(20 + 15)
+ 0x2d800000, //2 ^ -(21 + 15)
+ 0x2d000000, //2 ^ -(22 + 15)
+ 0x2c800000, //2 ^ -(23 + 15)
+ 0x2c000000 //2 ^ -(24 + 15)
+};
+
+static float *scale_factor = (float*)u32_scale_factors;
+
+//These store the persistent state of the packed mantissas
+static float q_1[2];
+static float q_2[2];
+static float q_4[1];
+static int32_t q_1_pointer;
+static int32_t q_2_pointer;
+static int32_t q_4_pointer;
+static float __inline__
+coeff_get_float(uint16_t bap, uint16_t dithflag, uint16_t exp);
+
+//Conversion from bap to number of bits in the mantissas
+//zeros account for cases 0,1,2,4 which are special cased
+static uint16_t qnttztab[16] =
+{
+ 0, 0, 0, 3,
+ 0, 4, 5, 6,
+ 7, 8, 9, 10,
+ 11, 12, 14, 16
+};
+
+static void coeff_reset(void);
+static float coeff_get_float(uint16_t bap, uint16_t dithflag, uint16_t exp);
+static void coeff_uncouple_ch(float samples[],bsi_t *bsi,audblk_t *audblk,uint32_t ch);
+
+void coeff_unpack(bsi_t *bsi, audblk_t *audblk, stream_samples_t samples)
+{
+ uint16_t i,j;
+ uint32_t done_cpl = 0;
+
+ coeff_reset();
+
+ for(i=0; i< bsi->nfchans; i++) {
+ for(j=0; j < audblk->endmant[i]; j++)
+ samples[i][j] = coeff_get_float(audblk->fbw_bap[i][j], audblk->dithflag[i], audblk->fbw_exp[i][j]);
+
+ if(audblk->cplinu && audblk->chincpl[i] && !(done_cpl)) {
+ // ncplmant is equal to 12 * ncplsubnd
+ // Don't dither coupling channel until channel
+ // separation so that interchannel noise is uncorrelated
+ for(j=audblk->cplstrtmant; j < audblk->cplendmant; j++)
+ audblk->cpl_flt[j] = coeff_get_float(audblk->cpl_bap[j],0, audblk->cpl_exp[j]);
+ done_cpl = 1;
+ }
+ }
+
+ //uncouple the channel if necessary
+ if(audblk->cplinu) {
+ for(i=0; i< bsi->nfchans; i++) {
+ if(audblk->chincpl[i])
+ coeff_uncouple_ch(samples[i],bsi,audblk,i);
+ }
+
+ }
+
+ if(bsi->lfeon) {
+ // There are always 7 mantissas for lfe, no dither for lfe
+ for(j=0; j < 7 ; j++)
+ samples[5][j] = coeff_get_float(audblk->lfe_bap[j], 0, audblk->lfe_exp[j]);
+ }
+}
+
+
+/**
+ * Fetch a float from the bitstream
+ **/
+
+static float inline coeff_get_float (uint16_t bap, uint16_t dithflag, uint16_t exp)
+{
+ uint16_t dummy = 0;
+
+ //If the bap is 0-5 then we have special cases to take care of
+ switch(bap) {
+ case 0:
+ if(dithflag)
+ return (dither_gen() * scale_factor[exp]);
+ return 0.0;
+
+ case 1:
+ if (q_1_pointer >= 0)
+ return(q_1[q_1_pointer--] * scale_factor[exp]);
+
+ if ((dummy = bitstream_get (5)) > 26)
+ goto error;
+
+ q_1[1] = q_1_1[dummy];
+ q_1[0] = q_1_2[dummy];
+ q_1_pointer = 1;
+
+ return (q_1_0[dummy] * scale_factor[exp]);
+
+ case 2:
+ if(q_2_pointer >= 0)
+ return (q_2[q_2_pointer--] * scale_factor[exp]);
+
+ if ((dummy = bitstream_get (7)) > 124)
+ goto error;
+
+ q_2[1] = q_2_1[dummy];
+ q_2[0] = q_2_2[dummy];
+ q_2_pointer = 1;
+
+ return (q_2_0[dummy] * scale_factor[exp]);
+
+ case 3:
+ if ((dummy = bitstream_get (3)) > 6)
+ goto error;
+
+ return (q_3[dummy] * scale_factor[exp]);
+
+ case 4:
+ if(q_4_pointer >= 0)
+ return (q_4[q_4_pointer--] * scale_factor[exp]);
+
+ if ((dummy = bitstream_get (7)) > 120)
+ goto error;
+
+ q_4[0] = q_4_1[dummy];
+ q_4_pointer = 0;
+
+ return (q_4_0[dummy] * scale_factor[exp]);
+
+ case 5:
+ if ((dummy = bitstream_get (4)) > 14)
+ goto error;
+
+ return (q_5[dummy] * scale_factor[exp]);
+
+ default:
+ dummy = bitstream_get(qnttztab[bap]);
+ dummy <<= 16 - qnttztab[bap];
+ return ((int16_t)dummy * scale_factor[exp]);
+ }
+
+error:
+#ifdef FAST_ERROR
+ HANDLE_ERROR ();
+#else
+ if(!error_flag)
+ fprintf(stderr,"** Invalid mantissa - skipping frame **\n");
+ error_flag = 1;
+
+ return 0.0;
+#endif
+}
+
+
+/**
+ * Reset the mantissa state
+ **/
+
+static void coeff_reset(void)
+{
+ q_1_pointer = q_2_pointer = q_4_pointer = -1;
+}
+
+
+/**
+ * Uncouple the coupling channel into a fbw channel
+ **/
+
+static void coeff_uncouple_ch (float samples[],bsi_t *bsi,audblk_t *audblk,uint32_t ch)
+{
+ uint32_t bnd = 0;
+ uint32_t sub_bnd = 0;
+ uint32_t i,j;
+ float cpl_coord = 1.0;
+ uint32_t cpl_exp_tmp;
+ uint32_t cpl_mant_tmp;
+
+ for (i=audblk->cplstrtmant;i<audblk->cplendmant;) {
+ if (!audblk->cplbndstrc[sub_bnd++]) {
+ cpl_exp_tmp = audblk->cplcoexp[ch][bnd] + 3 * audblk->mstrcplco[ch];
+ if (audblk->cplcoexp[ch][bnd] == 15)
+ cpl_mant_tmp = (audblk->cplcomant[ch][bnd]) << 11;
+ else
+ cpl_mant_tmp = ((0x10) | audblk->cplcomant[ch][bnd]) << 10;
+
+ cpl_coord = (cpl_mant_tmp * scale_factor[cpl_exp_tmp]) * 8.0f;
+
+ //Invert the phase for the right channel if necessary
+ if(bsi->acmod == 0x2 && audblk->phsflginu && ch == 1 && audblk->phsflg[bnd])
+ cpl_coord *= -1;
+
+ bnd++;
+ }
+
+ for(j=0;j < 12; j++) {
+ // Get new dither values for each channel if necessary,
+ // so the channels are uncorrelated
+ if(audblk->dithflag[ch] && !audblk->cpl_bap[i])
+ samples[i] = cpl_coord * (dither_gen() * scale_factor[audblk->cpl_exp[i]]);
+ else
+ samples[i] = cpl_coord * audblk->cpl_flt[i];
+
+ i++;
+ }
+ }
+}
diff --git a/src/libac3/coeff.h b/src/libac3/coeff.h
new file mode 100644
index 000000000..dc822a9bd
--- /dev/null
+++ b/src/libac3/coeff.h
@@ -0,0 +1,24 @@
+/*
+ * coeff.h
+ *
+ * Copyright (C) Aaron Holtzman - Feb 2000
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+void coeff_unpack(bsi_t *bsi, audblk_t *audblk,stream_samples_t samples);
diff --git a/src/libac3/crc.c b/src/libac3/crc.c
new file mode 100644
index 000000000..c8ee478b6
--- /dev/null
+++ b/src/libac3/crc.c
@@ -0,0 +1,100 @@
+/*
+ * crc.c
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "ac3.h"
+#include "ac3_internal.h"
+
+#include <sys/time.h>
+
+#include "crc.h"
+
+static const uint16_t crc_lut[256] =
+{
+ 0x0000,0x8005,0x800f,0x000a,0x801b,0x001e,0x0014,0x8011,
+ 0x8033,0x0036,0x003c,0x8039,0x0028,0x802d,0x8027,0x0022,
+ 0x8063,0x0066,0x006c,0x8069,0x0078,0x807d,0x8077,0x0072,
+ 0x0050,0x8055,0x805f,0x005a,0x804b,0x004e,0x0044,0x8041,
+ 0x80c3,0x00c6,0x00cc,0x80c9,0x00d8,0x80dd,0x80d7,0x00d2,
+ 0x00f0,0x80f5,0x80ff,0x00fa,0x80eb,0x00ee,0x00e4,0x80e1,
+ 0x00a0,0x80a5,0x80af,0x00aa,0x80bb,0x00be,0x00b4,0x80b1,
+ 0x8093,0x0096,0x009c,0x8099,0x0088,0x808d,0x8087,0x0082,
+ 0x8183,0x0186,0x018c,0x8189,0x0198,0x819d,0x8197,0x0192,
+ 0x01b0,0x81b5,0x81bf,0x01ba,0x81ab,0x01ae,0x01a4,0x81a1,
+ 0x01e0,0x81e5,0x81ef,0x01ea,0x81fb,0x01fe,0x01f4,0x81f1,
+ 0x81d3,0x01d6,0x01dc,0x81d9,0x01c8,0x81cd,0x81c7,0x01c2,
+ 0x0140,0x8145,0x814f,0x014a,0x815b,0x015e,0x0154,0x8151,
+ 0x8173,0x0176,0x017c,0x8179,0x0168,0x816d,0x8167,0x0162,
+ 0x8123,0x0126,0x012c,0x8129,0x0138,0x813d,0x8137,0x0132,
+ 0x0110,0x8115,0x811f,0x011a,0x810b,0x010e,0x0104,0x8101,
+ 0x8303,0x0306,0x030c,0x8309,0x0318,0x831d,0x8317,0x0312,
+ 0x0330,0x8335,0x833f,0x033a,0x832b,0x032e,0x0324,0x8321,
+ 0x0360,0x8365,0x836f,0x036a,0x837b,0x037e,0x0374,0x8371,
+ 0x8353,0x0356,0x035c,0x8359,0x0348,0x834d,0x8347,0x0342,
+ 0x03c0,0x83c5,0x83cf,0x03ca,0x83db,0x03de,0x03d4,0x83d1,
+ 0x83f3,0x03f6,0x03fc,0x83f9,0x03e8,0x83ed,0x83e7,0x03e2,
+ 0x83a3,0x03a6,0x03ac,0x83a9,0x03b8,0x83bd,0x83b7,0x03b2,
+ 0x0390,0x8395,0x839f,0x039a,0x838b,0x038e,0x0384,0x8381,
+ 0x0280,0x8285,0x828f,0x028a,0x829b,0x029e,0x0294,0x8291,
+ 0x82b3,0x02b6,0x02bc,0x82b9,0x02a8,0x82ad,0x82a7,0x02a2,
+ 0x82e3,0x02e6,0x02ec,0x82e9,0x02f8,0x82fd,0x82f7,0x02f2,
+ 0x02d0,0x82d5,0x82df,0x02da,0x82cb,0x02ce,0x02c4,0x82c1,
+ 0x8243,0x0246,0x024c,0x8249,0x0258,0x825d,0x8257,0x0252,
+ 0x0270,0x8275,0x827f,0x027a,0x826b,0x026e,0x0264,0x8261,
+ 0x0220,0x8225,0x822f,0x022a,0x823b,0x023e,0x0234,0x8231,
+ 0x8213,0x0216,0x021c,0x8219,0x0208,0x820d,0x8207,0x0202
+};
+
+static uint16_t state;
+
+
+void crc_init(void)
+{
+ state = 0;
+}
+
+
+inline void crc_process_byte (uint8_t data)
+{
+ state = crc_lut[data ^ (state>>8)] ^ (state<<8);
+}
+
+
+void crc_process_frame (uint8_t *data,uint32_t num_bytes)
+{
+ uint32_t i;
+
+ for(i=0; i<num_bytes; i++)
+ crc_process_byte (data[i]);
+}
+
+
+int crc_validate(void)
+{
+ return (state == 0);
+}
diff --git a/src/libac3/crc.h b/src/libac3/crc.h
new file mode 100644
index 000000000..16489656c
--- /dev/null
+++ b/src/libac3/crc.h
@@ -0,0 +1,27 @@
+/*
+ * crc.h
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+int crc_validate(void);
+void crc_init(void);
+void crc_process_byte(uint8_t data);
+void crc_process_frame(uint8_t *data,uint32_t num_bytes);
diff --git a/src/libac3/decode.c b/src/libac3/decode.c
new file mode 100644
index 000000000..cca544933
--- /dev/null
+++ b/src/libac3/decode.c
@@ -0,0 +1,314 @@
+/*
+ * decode.c
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include "ac3.h"
+#include "ac3_internal.h"
+#include "bitstream.h"
+#include "downmix.h"
+#include "srfft.h"
+#include "imdct.h"
+#include "exponent.h"
+#include "coeff.h"
+#include "bit_allocate.h"
+#include "parse.h"
+#include "crc.h"
+#include "rematrix.h"
+#include "sanity_check.h"
+
+#include "audio_out.h"
+#include "attributes.h"
+
+
+//our global config structure
+ac3_config_t ac3_config;
+#ifdef FAST_ERROR
+jmp_buf error_jmp_mark;
+#else
+uint32_t error_flag = 0;
+#endif
+
+static audblk_t audblk;
+static bsi_t bsi;
+static syncinfo_t syncinfo;
+static uint32_t frame_count = 0;
+static uint32_t is_output_initialized = 0;
+
+//the floating point samples for one audblk
+static stream_samples_t samples;
+
+//the integer samples for the entire frame (with enough space for 2 ch out)
+//if this size change, be sure to change the size when muting
+static int16_t s16_samples[2 * 6 * 256] __attribute__ ((aligned(16)));
+
+/* output buffer for spdiv output */
+static int16_t s16_samples_out[4 * 6 * 256] __attribute__ ((aligned(16)));
+
+static ao_functions_t ac3_output;
+
+// downmix stuff
+static float cmixlev_lut[4] = { 0.707, 0.595, 0.500, 0.707 };
+static float smixlev_lut[4] = { 0.707, 0.500, 0.0 , 0.500 };
+static dm_par_t dm_par;
+
+//Storage for the syncframe
+#define BUFFER_MAX_SIZE 4096
+static uint8_t buffer[BUFFER_MAX_SIZE];
+static uint32_t buffer_size = 0;;
+
+static uint32_t decode_buffer_syncframe (syncinfo_t *syncinfo, uint8_t **start, uint8_t *end)
+{
+ uint8_t *cur = *start;
+ uint16_t syncword = syncinfo->syncword;
+ uint32_t ret = 0;
+
+ //
+ // Find an ac3 sync frame.
+ //
+ while (syncword != 0x0b77) {
+ if (cur >= end)
+ goto done;
+ syncword = (syncword << 8) + *cur++;
+ }
+
+ //need the next 3 bytes to decide how big the frame is
+ while (buffer_size < 3) {
+ if(cur >= end)
+ goto done;
+ buffer[buffer_size++] = *cur++;
+ }
+
+ parse_syncinfo (syncinfo,buffer);
+
+ while (buffer_size < syncinfo->frame_size * 2 - 2) {
+ if(cur >= end)
+ goto done;
+
+ buffer[buffer_size++] = *cur++;
+ }
+
+#if 0
+ // Check the crc over the entire frame
+ crc_init();
+ crc_process_frame (buffer, syncinfo->frame_size * 2 - 2);
+
+ if (!crc_validate()) {
+#ifndef FAST_ERROR
+ error_flag = 1;
+#endif
+ fprintf(stderr,"** CRC failed - skipping frame **\n");
+ goto done;
+ }
+#endif
+
+ //
+ //if we got to this point, we found a valid ac3 frame to decode
+ //
+
+ if ((ac3_config.flags & AO_MODE_AC3) == 0) {
+ bitstream_init (buffer);
+ //get rid of the syncinfo struct as we already parsed it
+ bitstream_get (24);
+ }
+
+ //reset the syncword for next time
+ syncword = 0xffff;
+ buffer_size = 0;
+ ret = 1;
+
+done:
+ syncinfo->syncword = syncword;
+ *start = cur;
+ return ret;
+}
+
+
+void inline decode_mute (void)
+{
+ //mute the frame
+ memset (s16_samples, 0, sizeof(int16_t) * 256 * 2 * 6);
+#ifndef FAST_ERROR
+ error_flag = 0;
+#endif
+}
+
+
+void ac3_init(ac3_config_t *config ,ao_functions_t *foo)
+{
+ memcpy(&ac3_config,config,sizeof(ac3_config_t));
+ ac3_output = *foo;
+
+ imdct_init ();
+ /* downmix_init (); */
+ sanity_check_init (&syncinfo,&bsi,&audblk);
+ memset(s16_samples_out,0,4 * 6 * 256);
+
+}
+
+void ac3_reset ()
+{
+ printf ("ac3_reset\n");
+#ifndef FAST_ERROR
+ error_flag = 0;
+#endif
+
+ frame_count = 0;
+ is_output_initialized = 0;
+
+ buffer_size = 0;
+ syncinfo.syncword = 0;
+ imdct_init();
+ sanity_check_init(&syncinfo,&bsi,&audblk);
+
+}
+
+size_t ac3_decode_data (uint8_t *data_start, uint8_t *data_end, uint32_t pts_)
+{
+ uint32_t i;
+
+#ifdef FAST_ERROR
+ if (setjmp (error_jmp_mark) < 0) {
+ imdct_init ();
+ sanity_check_init(&syncinfo,&bsi,&audblk);
+ return 0;
+ }
+#endif
+
+ while (decode_buffer_syncframe (&syncinfo, &data_start, data_end)) {
+
+#ifndef FAST_ERROR
+ if (error_flag)
+ goto error;
+#endif
+
+ if ((ac3_config.flags & AO_MODE_AC3) == 0) {
+ parse_bsi (&bsi);
+
+ // compute downmix parameters
+ // downmix to two channels for now
+ dm_par.clev = 0.0; dm_par.slev = 0.0; dm_par.unit = 1.0;
+ if (bsi.acmod & 0x1) // have center
+ dm_par.clev = cmixlev_lut[bsi.cmixlev];
+
+ if (bsi.acmod & 0x4) // have surround channels
+ dm_par.slev = smixlev_lut[bsi.surmixlev];
+
+ dm_par.unit /= 1.0 + dm_par.clev + dm_par.slev;
+ dm_par.clev *= dm_par.unit;
+ dm_par.slev *= dm_par.unit;
+
+ for(i=0; i < 6; i++) {
+ //Initialize freq/time sample storage
+ memset (samples, 0, sizeof(float) * 256 * (bsi.nfchans + bsi.lfeon));
+
+ // Extract most of the audblk info from the bitstream
+ // (minus the mantissas
+ parse_audblk (&bsi,&audblk);
+
+ // Take the differential exponent data and turn it into
+ // absolute exponents
+ exponent_unpack (&bsi,&audblk);
+#ifndef FAST_ERROR
+ if (error_flag)
+ goto error;
+#endif
+
+ // Figure out how many bits per mantissa
+ bit_allocate (syncinfo.fscod,&bsi,&audblk);
+
+ // Extract the mantissas from the stream and
+ // generate floating point frequency coefficients
+ coeff_unpack (&bsi,&audblk,samples);
+#ifndef FAST_ERROR
+ if (error_flag)
+ goto error;
+#endif
+
+ if (bsi.acmod == 0x2)
+ rematrix (&audblk,samples);
+
+ // Convert the frequency samples into time samples
+ imdct (&bsi,&audblk,samples, &s16_samples[i * 2 * 256], &dm_par);
+
+ // Downmix into the requested number of channels
+ // and convert floating point to int16_t
+ // downmix(&bsi,samples,&s16_samples[i * 2 * 256]);
+
+ if (sanity_check(&syncinfo,&bsi,&audblk) < 0)
+ sanity_check_init (&syncinfo,&bsi,&audblk);
+
+ continue;
+ }
+ }
+ else {
+ s16_samples_out[0] = 0xf872; //spdif syncword
+ s16_samples_out[1] = 0x4e1f; // .............
+ s16_samples_out[2] = 0x0001; // AC3 data
+ s16_samples_out[3] = syncinfo.frame_size * 16;
+ s16_samples_out[4] = 0x0b77; // AC3 syncwork
+
+ // ac3 seems to be swabbed data
+ swab(buffer,&s16_samples_out[5], syncinfo.frame_size * 2 );
+
+ }
+
+ if (!is_output_initialized) {
+ ac3_output.open (16, syncinfo.sampling_rate,
+ (ac3_config.flags & AO_MODE_AC3) ? AO_MODE_AC3 : AO_MODE_STEREO);
+ is_output_initialized = 1;
+ }
+
+ if ((ac3_config.flags & AO_MODE_AC3) == 0) {
+ ac3_output.write_audio_data(s16_samples, 256*6, pts_);
+ }
+ else {
+ ac3_output.write_audio_data(s16_samples_out, 6 * 256, pts_);
+ }
+
+ pts_ = 0;
+
+#ifndef FAST_ERROR
+error:
+
+ //find a new frame
+ decode_mute (); //RMB CHECK
+#endif
+ }
+#ifdef FAST_ERROR
+ decode_mute ();
+#endif
+
+ return 0;
+}
+
diff --git a/src/libac3/decode.h b/src/libac3/decode.h
new file mode 100644
index 000000000..bb84a1105
--- /dev/null
+++ b/src/libac3/decode.h
@@ -0,0 +1,22 @@
+/*
+ * decode.h
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
diff --git a/src/libac3/dither.c b/src/libac3/dither.c
new file mode 100644
index 000000000..07fa2f596
--- /dev/null
+++ b/src/libac3/dither.c
@@ -0,0 +1,117 @@
+/*
+ * dither.c
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "ac3.h"
+#include "ac3_internal.h"
+
+
+#include "dither.h"
+
+
+const uint16_t dither_lut[256] =
+{
+ 0x0000, 0xa011, 0xe033, 0x4022, 0x6077, 0xc066, 0x8044, 0x2055,
+ 0xc0ee, 0x60ff, 0x20dd, 0x80cc, 0xa099, 0x0088, 0x40aa, 0xe0bb,
+ 0x21cd, 0x81dc, 0xc1fe, 0x61ef, 0x41ba, 0xe1ab, 0xa189, 0x0198,
+ 0xe123, 0x4132, 0x0110, 0xa101, 0x8154, 0x2145, 0x6167, 0xc176,
+ 0x439a, 0xe38b, 0xa3a9, 0x03b8, 0x23ed, 0x83fc, 0xc3de, 0x63cf,
+ 0x8374, 0x2365, 0x6347, 0xc356, 0xe303, 0x4312, 0x0330, 0xa321,
+ 0x6257, 0xc246, 0x8264, 0x2275, 0x0220, 0xa231, 0xe213, 0x4202,
+ 0xa2b9, 0x02a8, 0x428a, 0xe29b, 0xc2ce, 0x62df, 0x22fd, 0x82ec,
+ 0x8734, 0x2725, 0x6707, 0xc716, 0xe743, 0x4752, 0x0770, 0xa761,
+ 0x47da, 0xe7cb, 0xa7e9, 0x07f8, 0x27ad, 0x87bc, 0xc79e, 0x678f,
+ 0xa6f9, 0x06e8, 0x46ca, 0xe6db, 0xc68e, 0x669f, 0x26bd, 0x86ac,
+ 0x6617, 0xc606, 0x8624, 0x2635, 0x0660, 0xa671, 0xe653, 0x4642,
+ 0xc4ae, 0x64bf, 0x249d, 0x848c, 0xa4d9, 0x04c8, 0x44ea, 0xe4fb,
+ 0x0440, 0xa451, 0xe473, 0x4462, 0x6437, 0xc426, 0x8404, 0x2415,
+ 0xe563, 0x4572, 0x0550, 0xa541, 0x8514, 0x2505, 0x6527, 0xc536,
+ 0x258d, 0x859c, 0xc5be, 0x65af, 0x45fa, 0xe5eb, 0xa5c9, 0x05d8,
+ 0xae79, 0x0e68, 0x4e4a, 0xee5b, 0xce0e, 0x6e1f, 0x2e3d, 0x8e2c,
+ 0x6e97, 0xce86, 0x8ea4, 0x2eb5, 0x0ee0, 0xaef1, 0xeed3, 0x4ec2,
+ 0x8fb4, 0x2fa5, 0x6f87, 0xcf96, 0xefc3, 0x4fd2, 0x0ff0, 0xafe1,
+ 0x4f5a, 0xef4b, 0xaf69, 0x0f78, 0x2f2d, 0x8f3c, 0xcf1e, 0x6f0f,
+ 0xede3, 0x4df2, 0x0dd0, 0xadc1, 0x8d94, 0x2d85, 0x6da7, 0xcdb6,
+ 0x2d0d, 0x8d1c, 0xcd3e, 0x6d2f, 0x4d7a, 0xed6b, 0xad49, 0x0d58,
+ 0xcc2e, 0x6c3f, 0x2c1d, 0x8c0c, 0xac59, 0x0c48, 0x4c6a, 0xec7b,
+ 0x0cc0, 0xacd1, 0xecf3, 0x4ce2, 0x6cb7, 0xcca6, 0x8c84, 0x2c95,
+ 0x294d, 0x895c, 0xc97e, 0x696f, 0x493a, 0xe92b, 0xa909, 0x0918,
+ 0xe9a3, 0x49b2, 0x0990, 0xa981, 0x89d4, 0x29c5, 0x69e7, 0xc9f6,
+ 0x0880, 0xa891, 0xe8b3, 0x48a2, 0x68f7, 0xc8e6, 0x88c4, 0x28d5,
+ 0xc86e, 0x687f, 0x285d, 0x884c, 0xa819, 0x0808, 0x482a, 0xe83b,
+ 0x6ad7, 0xcac6, 0x8ae4, 0x2af5, 0x0aa0, 0xaab1, 0xea93, 0x4a82,
+ 0xaa39, 0x0a28, 0x4a0a, 0xea1b, 0xca4e, 0x6a5f, 0x2a7d, 0x8a6c,
+ 0x4b1a, 0xeb0b, 0xab29, 0x0b38, 0x2b6d, 0x8b7c, 0xcb5e, 0x6b4f,
+ 0x8bf4, 0x2be5, 0x6bc7, 0xcbd6, 0xeb83, 0x4b92, 0x0bb0, 0xaba1
+};
+
+uint16_t lfsr_state = 1;
+
+//
+// see dither_gen (inline-able) in dither.h
+//
+
+#if 0
+
+//
+// this is the old dither_gen with is much slower than the new inlined
+// lut version and is still here because it's easier to understand.
+//
+
+/*
+ * Generate eight bits of pseudo-entropy using a 16 bit linear
+ * feedback shift register (LFSR). The primitive polynomial used
+ * is 1 + x^4 + x^14 + x^16.
+ *
+ * The distribution is uniform, over the range [-0.707,0.707]
+ *
+ */
+
+uint16_t dither_gen(void)
+{
+ int i;
+ uint32_t state;
+
+ //explicitly bring the state into a local var as gcc > 3.0?
+ //doesn't know how to optimize out the stores
+ state = lfsr_state;
+
+ //Generate eight pseudo random bits
+ for(i=0;i<8;i++) {
+ state <<= 1;
+
+ if(state & 0x10000)
+ state ^= 0xa011;
+ }
+
+ lfsr_state = state;
+
+ return (((((int32_t)state<<8)>>8) * (int32_t) (0.707106 * 256.0))>>16);
+}
+
+#endif
diff --git a/src/libac3/dither.h b/src/libac3/dither.h
new file mode 100644
index 000000000..abb9f518e
--- /dev/null
+++ b/src/libac3/dither.h
@@ -0,0 +1,37 @@
+/*
+ * dither.h
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+extern uint16_t lfsr_state;
+extern const uint16_t dither_lut[256];
+
+static inline uint16_t dither_gen(void)
+{
+ int16_t state;
+
+ state = dither_lut[lfsr_state >> 8] ^ (lfsr_state << 8);
+
+ lfsr_state = (uint16_t) state;
+
+ return ((state * (int32_t) (0.707106 * 256.0))>>8);
+}
diff --git a/src/libac3/downmix.c b/src/libac3/downmix.c
new file mode 100644
index 000000000..df71d5e3d
--- /dev/null
+++ b/src/libac3/downmix.c
@@ -0,0 +1,158 @@
+/*
+ * imdct.c
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "ac3.h"
+#include "ac3_internal.h"
+
+#include "downmix.h"
+
+void downmix_3f_2r_to_2ch (float *samples, dm_par_t *dm_par)
+{
+ int i;
+ float *left, *right, *center, *left_sur, *right_sur;
+ float left_tmp, right_tmp;
+
+ left = samples;
+ right = samples + 256 * 2;
+ center = samples + 256;
+ left_sur = samples + 256 * 3;
+ right_sur = samples + 256 * 4;
+
+ for (i=0; i < 256; i++) {
+ left_tmp = dm_par->unit * *left + dm_par->clev * *center + dm_par->slev * *left_sur++;
+ right_tmp= dm_par->unit * *right++ + dm_par->clev * *center + dm_par->slev * *right_sur++;
+ *left++ = left_tmp;
+ *center++ = right_tmp;
+ }
+}
+
+
+void downmix_2f_2r_to_2ch (float *samples, dm_par_t *dm_par)
+{
+ int i;
+ float *left, *right, *left_sur, *right_sur;
+ float left_tmp, right_tmp;
+
+ left = &samples[0];
+ right = &samples[256];
+ left_sur = &samples[512];
+ right_sur = &samples[768];
+
+ for (i = 0; i < 256; i++) {
+ left_tmp = dm_par->unit * *left + dm_par->slev * *left_sur++;
+ right_tmp= dm_par->unit * *right + dm_par->slev * *right_sur++;
+ *left++ = left_tmp;
+ *right++ = right_tmp;
+ }
+}
+
+
+void downmix_3f_1r_to_2ch (float *samples, dm_par_t *dm_par)
+{
+ int i;
+ float *left, *right, *center, *right_sur;
+ float left_tmp, right_tmp;
+
+ left = &samples[0];
+ right = &samples[512];
+ center = &samples[256];
+ right_sur = &samples[768];
+
+ for (i = 0; i < 256; i++) {
+ left_tmp = dm_par->unit * *left + dm_par->clev * *center - dm_par->slev * *right_sur;
+ right_tmp= dm_par->unit * *right++ + dm_par->clev * *center + dm_par->slev * *right_sur++;
+ *left++ = left_tmp;
+ *center++ = right_tmp;
+ }
+}
+
+
+void downmix_2f_1r_to_2ch (float *samples, dm_par_t *dm_par)
+{
+ int i;
+ float *left, *right, *right_sur;
+ float left_tmp, right_tmp;
+
+ left = &samples[0];
+ right = &samples[256];
+ right_sur = &samples[512];
+
+ for (i = 0; i < 256; i++) {
+ left_tmp = dm_par->unit * *left - dm_par->slev * *right_sur;
+ right_tmp= dm_par->unit * *right + dm_par->slev * *right_sur++;
+ *left++ = left_tmp;
+ *right++ = right_tmp;
+ }
+}
+
+
+void downmix_3f_0r_to_2ch (float *samples, dm_par_t *dm_par)
+{
+ int i;
+ float *left, *right, *center;
+ float left_tmp, right_tmp;
+
+ left = &samples[0];
+ center = &samples[256];
+ right = &samples[512];
+
+ for (i = 0; i < 256; i++) {
+ left_tmp = dm_par->unit * *left + dm_par->clev * *center;
+ right_tmp= dm_par->unit * *right++ + dm_par->clev * *center;
+ *left++ = left_tmp;
+ *center++ = right_tmp;
+ }
+}
+
+void stream_sample_2ch_to_s16 (int16_t *s16_samples, float *left, float *right)
+{
+ int i;
+
+ for (i=0; i < 256; i++) {
+ *s16_samples++ = (int16_t) *left++;
+ *s16_samples++ = (int16_t) *right++;
+ }
+}
+
+
+void stream_sample_1ch_to_s16 (int16_t *s16_samples, float *center)
+{
+ int i;
+ float tmp;
+
+ for (i=0; i < 256; i++) {
+ *s16_samples++ = tmp = (int16_t) (0.7071f * *center++);
+ *s16_samples++ = tmp;
+ }
+}
+
+
diff --git a/src/libac3/downmix.h b/src/libac3/downmix.h
new file mode 100644
index 000000000..7e6dea014
--- /dev/null
+++ b/src/libac3/downmix.h
@@ -0,0 +1,43 @@
+/*
+ *
+ * downmix.h
+ *
+ * Copyright (C) Aaron Holtzman - Sept 1999
+ *
+ * Originally based on code by Yeqing Deng.
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+typedef struct dm_par_s {
+ float unit;
+ float clev;
+ float slev;
+} dm_par_t;
+
+void downmix_3f_2r_to_2ch (float *samples, dm_par_t * dm_par);
+void downmix_3f_1r_to_2ch (float *samples, dm_par_t * dm_par);
+void downmix_2f_2r_to_2ch (float *samples, dm_par_t * dm_par);
+void downmix_2f_1r_to_2ch (float *samples, dm_par_t * dm_par);
+void downmix_3f_0r_to_2ch (float *samples, dm_par_t * dm_par);
+
+void stream_sample_2ch_to_s16 (int16_t *s16_samples, float *left, float *right);
+void stream_sample_1ch_to_s16 (int16_t *s16_samples, float *center);
+
+
diff --git a/src/libac3/exponent.c b/src/libac3/exponent.c
new file mode 100644
index 000000000..ebb35abd7
--- /dev/null
+++ b/src/libac3/exponent.c
@@ -0,0 +1,138 @@
+/*
+ * exponent.c
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "ac3.h"
+#include "ac3_internal.h"
+
+
+#include "exponent.h"
+
+
+static inline void exp_unpack_ch(uint16_t type,uint16_t expstr,uint16_t ngrps,uint16_t initial_exp, uint16_t exps[], uint16_t *dest);
+
+
+/**
+ *
+ **/
+
+void exponent_unpack( bsi_t *bsi, audblk_t *audblk)
+{
+ uint16_t i;
+
+ for(i=0; i< bsi->nfchans; i++)
+ exp_unpack_ch(UNPACK_FBW, audblk->chexpstr[i], audblk->nchgrps[i], audblk->exps[i][0], &audblk->exps[i][1], audblk->fbw_exp[i]);
+
+ if(audblk->cplinu)
+ exp_unpack_ch(UNPACK_CPL, audblk->cplexpstr, audblk->ncplgrps, audblk->cplabsexp << 1, audblk->cplexps, &audblk->cpl_exp[audblk->cplstrtmant]);
+
+ if(bsi->lfeon)
+ exp_unpack_ch(UNPACK_LFE, audblk->lfeexpstr, 2, audblk->lfeexps[0], &audblk->lfeexps[1], audblk->lfe_exp);
+}
+
+
+/**
+ *
+ **/
+
+static inline void exp_unpack_ch(uint16_t type,uint16_t expstr,uint16_t ngrps,uint16_t initial_exp,
+ uint16_t exps[], uint16_t *dest)
+{
+ uint16_t i,j;
+ int16_t exp_acc;
+ int16_t exp_1,exp_2,exp_3;
+
+ if (expstr == EXP_REUSE)
+ return;
+
+ /* Handle the initial absolute exponent */
+ exp_acc = initial_exp;
+ j = 0;
+
+ /* In the case of a fbw channel then the initial absolute values is
+ * also an exponent */
+ if(type != UNPACK_CPL)
+ dest[j++] = exp_acc;
+
+ /* Loop through the groups and fill the dest array appropriately */
+ for(i=0; i< ngrps; i++) {
+ if(exps[i] > 124)
+ goto error;
+
+ exp_1 = exps[i] / 25;
+ exp_2 = (exps[i] - (exp_1 * 25)) / 5;
+ exp_3 = exps[i] - (exp_1 * 25) - (exp_2 * 5) ;
+
+ exp_acc += (exp_1 - 2);
+
+ switch(expstr) {
+ case EXP_D45:
+ dest[j++] = exp_acc;
+ dest[j++] = exp_acc;
+ case EXP_D25:
+ dest[j++] = exp_acc;
+ case EXP_D15:
+ dest[j++] = exp_acc;
+ }
+
+ exp_acc += (exp_2 - 2);
+
+ switch(expstr) {
+ case EXP_D45:
+ dest[j++] = exp_acc;
+ dest[j++] = exp_acc;
+ case EXP_D25:
+ dest[j++] = exp_acc;
+ case EXP_D15:
+ dest[j++] = exp_acc;
+ }
+
+ exp_acc += (exp_3 - 2);
+
+ switch(expstr) {
+ case EXP_D45:
+ dest[j++] = exp_acc;
+ dest[j++] = exp_acc;
+ case EXP_D25:
+ dest[j++] = exp_acc;
+ case EXP_D15:
+ dest[j++] = exp_acc;
+ }
+ }
+
+ return;
+error:
+#ifdef FAST_ERROR
+ HANDLE_ERROR ();
+#else
+ if (!error_flag)
+ fprintf (stderr,"** Invalid exponent - skipping frame **\n");
+ error_flag = 1;
+#endif
+}
+
diff --git a/src/libac3/exponent.h b/src/libac3/exponent.h
new file mode 100644
index 000000000..06c59db03
--- /dev/null
+++ b/src/libac3/exponent.h
@@ -0,0 +1,28 @@
+/*
+ * exponent.h
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define UNPACK_FBW 1
+#define UNPACK_CPL 2
+#define UNPACK_LFE 4
+
+void exponent_unpack( bsi_t *bsi, audblk_t *audblk);
diff --git a/src/libac3/imdct.c b/src/libac3/imdct.c
new file mode 100644
index 000000000..a055f3399
--- /dev/null
+++ b/src/libac3/imdct.c
@@ -0,0 +1,661 @@
+/*
+ * imdct.c
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include "ac3.h"
+#include "ac3_internal.h"
+
+#include "downmix.h"
+#include "imdct.h"
+#include "srfft.h"
+
+#define N 512
+
+/* static complex_t buf[128]; */
+//static complex_t buf[128] __attribute__((aligned(16)));
+complex_t buf[128] __attribute__((aligned(16)));
+
+/* Delay buffer for time domain interleaving */
+static float delay[6][256];
+static float delay1[6][256];
+
+/* Twiddle factors for IMDCT */
+static float xcos1[128] __attribute__((aligned(16)));
+static float xsin1[128] __attribute__((aligned(16)));
+
+/* more twiddle factors for IMDCT */
+static float xcos2[64];
+static float xsin2[64];
+
+/* Windowing function for Modified DCT - Thank you acroread */
+//static float window[] = {
+float window[] = {
+ 0.00014, 0.00024, 0.00037, 0.00051, 0.00067, 0.00086, 0.00107, 0.00130,
+ 0.00157, 0.00187, 0.00220, 0.00256, 0.00297, 0.00341, 0.00390, 0.00443,
+ 0.00501, 0.00564, 0.00632, 0.00706, 0.00785, 0.00871, 0.00962, 0.01061,
+ 0.01166, 0.01279, 0.01399, 0.01526, 0.01662, 0.01806, 0.01959, 0.02121,
+ 0.02292, 0.02472, 0.02662, 0.02863, 0.03073, 0.03294, 0.03527, 0.03770,
+ 0.04025, 0.04292, 0.04571, 0.04862, 0.05165, 0.05481, 0.05810, 0.06153,
+ 0.06508, 0.06878, 0.07261, 0.07658, 0.08069, 0.08495, 0.08935, 0.09389,
+ 0.09859, 0.10343, 0.10842, 0.11356, 0.11885, 0.12429, 0.12988, 0.13563,
+ 0.14152, 0.14757, 0.15376, 0.16011, 0.16661, 0.17325, 0.18005, 0.18699,
+ 0.19407, 0.20130, 0.20867, 0.21618, 0.22382, 0.23161, 0.23952, 0.24757,
+ 0.25574, 0.26404, 0.27246, 0.28100, 0.28965, 0.29841, 0.30729, 0.31626,
+ 0.32533, 0.33450, 0.34376, 0.35311, 0.36253, 0.37204, 0.38161, 0.39126,
+ 0.40096, 0.41072, 0.42054, 0.43040, 0.44030, 0.45023, 0.46020, 0.47019,
+ 0.48020, 0.49022, 0.50025, 0.51028, 0.52031, 0.53033, 0.54033, 0.55031,
+ 0.56026, 0.57019, 0.58007, 0.58991, 0.59970, 0.60944, 0.61912, 0.62873,
+ 0.63827, 0.64774, 0.65713, 0.66643, 0.67564, 0.68476, 0.69377, 0.70269,
+ 0.71150, 0.72019, 0.72877, 0.73723, 0.74557, 0.75378, 0.76186, 0.76981,
+ 0.77762, 0.78530, 0.79283, 0.80022, 0.80747, 0.81457, 0.82151, 0.82831,
+ 0.83496, 0.84145, 0.84779, 0.85398, 0.86001, 0.86588, 0.87160, 0.87716,
+ 0.88257, 0.88782, 0.89291, 0.89785, 0.90264, 0.90728, 0.91176, 0.91610,
+ 0.92028, 0.92432, 0.92822, 0.93197, 0.93558, 0.93906, 0.94240, 0.94560,
+ 0.94867, 0.95162, 0.95444, 0.95713, 0.95971, 0.96217, 0.96451, 0.96674,
+ 0.96887, 0.97089, 0.97281, 0.97463, 0.97635, 0.97799, 0.97953, 0.98099,
+ 0.98236, 0.98366, 0.98488, 0.98602, 0.98710, 0.98811, 0.98905, 0.98994,
+ 0.99076, 0.99153, 0.99225, 0.99291, 0.99353, 0.99411, 0.99464, 0.99513,
+ 0.99558, 0.99600, 0.99639, 0.99674, 0.99706, 0.99736, 0.99763, 0.99788,
+ 0.99811, 0.99831, 0.99850, 0.99867, 0.99882, 0.99895, 0.99908, 0.99919,
+ 0.99929, 0.99938, 0.99946, 0.99953, 0.99959, 0.99965, 0.99969, 0.99974,
+ 0.99978, 0.99981, 0.99984, 0.99986, 0.99988, 0.99990, 0.99992, 0.99993,
+ 0.99994, 0.99995, 0.99996, 0.99997, 0.99998, 0.99998, 0.99998, 0.99999,
+ 0.99999, 0.99999, 0.99999, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000,
+ 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000, 1.00000
+};
+
+//static const int pm128[128] =
+const int pm128[128] =
+{
+ 0, 16, 32, 48, 64, 80, 96, 112, 8, 40, 72, 104, 24, 56, 88, 120,
+ 4, 20, 36, 52, 68, 84, 100, 116, 12, 28, 44, 60, 76, 92, 108, 124,
+ 2, 18, 34, 50, 66, 82, 98, 114, 10, 42, 74, 106, 26, 58, 90, 122,
+ 6, 22, 38, 54, 70, 86, 102, 118, 14, 46, 78, 110, 30, 62, 94, 126,
+ 1, 17, 33, 49, 65, 81, 97, 113, 9, 41, 73, 105, 25, 57, 89, 121,
+ 5, 21, 37, 53, 69, 85, 101, 117, 13, 29, 45, 61, 77, 93, 109, 125,
+ 3, 19, 35, 51, 67, 83, 99, 115, 11, 43, 75, 107, 27, 59, 91, 123,
+ 7, 23, 39, 55, 71, 87, 103, 119, 15, 31, 47, 63, 79, 95, 111, 127
+};
+
+static const int pm64[64] =
+{
+ 0, 8, 16, 24, 32, 40, 48, 56,
+ 4, 20, 36, 52, 12, 28, 44, 60,
+ 2, 10, 18, 26, 34, 42, 50, 58,
+ 6, 14, 22, 30, 38, 46, 54, 62,
+ 1, 9, 17, 25, 33, 41, 49, 57,
+ 5, 21, 37, 53, 13, 29, 45, 61,
+ 3, 11, 19, 27, 35, 43, 51, 59,
+ 7, 23, 39, 55, 15, 31, 47, 63
+};
+
+
+void imdct_init (void)
+ {
+ int i;
+ float scale = 255.99609372;
+
+ /* Twiddle factors to turn IFFT into IMDCT */
+
+ for (i=0; i < 128; i++) {
+ xcos1[i] = cos(2.0f * M_PI * (8*i+1)/(8*N)) * scale;
+ xsin1[i] = sin(2.0f * M_PI * (8*i+1)/(8*N)) * scale;
+ }
+
+ // More twiddle factors to turn IFFT into IMDCT */
+ for (i=0; i < 64; i++) {
+ xcos2[i] = cos(2.0f * M_PI * (8*i+1)/(4*N)) * scale;
+ xsin2[i] = sin(2.0f * M_PI * (8*i+1)/(4*N)) * scale;
+ }
+}
+
+
+void imdct_do_256 (float data[],float delay[])
+{
+ int i, j, k;
+ int p, q;
+
+ float tmp_a_i;
+ float tmp_a_r;
+
+ float *data_ptr;
+ float *delay_ptr;
+ float *window_ptr;
+
+ complex_t *buf1, *buf2;
+
+ buf1 = &buf[0];
+ buf2 = &buf[64];
+
+// Pre IFFT complex multiply plus IFFT complex conjugate
+ for (k=0; k<64; k++) {
+ /* X1[k] = X[2*k] */
+ /* X2[k] = X[2*k+1] */
+
+ j = pm64[k];
+ p = 2 * (128-2*j-1);
+ q = 2 * (2 * j);
+
+ /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
+ buf1[k].re = data[p] * xcos2[j] - data[q] * xsin2[j];
+ buf1[k].im = -1.0f * (data[q] * xcos2[j] + data[p] * xsin2[j]);
+ /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
+ buf2[k].re = data[p + 1] * xcos2[j] - data[q + 1] * xsin2[j];
+ buf2[k].im = -1.0f * ( data[q + 1] * xcos2[j] + data[p + 1] * xsin2[j]);
+ }
+
+ fft_64p(&buf1[0]);
+ fft_64p(&buf2[0]);
+
+#ifdef DEBUG
+ //DEBUG FFT
+#if 0
+ printf ("Post FFT, buf1\n");
+ for (i=0; i < 64; i++)
+ printf("%d %f %f\n", i, buf_1[i].re, buf_1[i].im);
+ printf ("Post FFT, buf2\n");
+ for (i=0; i < 64; i++)
+ printf("%d %f %f\n", i, buf_2[i].re, buf_2[i].im);
+#endif
+#endif
+
+
+ // Post IFFT complex multiply
+ for( i=0; i < 64; i++) {
+ tmp_a_r = buf1[i].re;
+ tmp_a_i = -buf1[i].im;
+ buf1[i].re =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
+ buf1[i].im =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
+ tmp_a_r = buf2[i].re;
+ tmp_a_i = -buf2[i].im;
+ buf2[i].re =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
+ buf2[i].im =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
+ }
+
+ data_ptr = data;
+ delay_ptr = delay;
+ window_ptr = window;
+
+ /* Window and convert to real valued signal */
+ for(i=0; i< 64; i++) {
+ *data_ptr++ = -buf1[i].im * *window_ptr++ + *delay_ptr++;
+ *data_ptr++ = buf1[64-i-1].re * *window_ptr++ + *delay_ptr++;
+ }
+
+ for(i=0; i< 64; i++) {
+ *data_ptr++ = -buf1[i].re * *window_ptr++ + *delay_ptr++;
+ *data_ptr++ = buf1[64-i-1].im * *window_ptr++ + *delay_ptr++;
+ }
+
+ delay_ptr = delay;
+
+ for(i=0; i< 64; i++) {
+ *delay_ptr++ = -buf2[i].re * *--window_ptr;
+ *delay_ptr++ = buf2[64-i-1].im * *--window_ptr;
+ }
+
+ for(i=0; i< 64; i++) {
+ *delay_ptr++ = buf2[i].im * *--window_ptr;
+ *delay_ptr++ = -buf2[64-i-1].re * *--window_ptr;
+ }
+}
+
+
+/**
+ *
+ **/
+
+void imdct_do_256_nol (float data[], float delay[])
+{
+ int i, j, k;
+ int p, q;
+
+ float tmp_a_i;
+ float tmp_a_r;
+
+ float *data_ptr;
+ float *delay_ptr;
+ float *window_ptr;
+
+ complex_t *buf1, *buf2;
+
+ buf1 = &buf[0];
+ buf2 = &buf[64];
+
+ /* Pre IFFT complex multiply plus IFFT cmplx conjugate */
+ for(k=0; k<64; k++) {
+ /* X1[k] = X[2*k] */
+ /* X2[k] = X[2*k+1] */
+ j = pm64[k];
+ p = 2 * (128-2*j-1);
+ q = 2 * (2 * j);
+
+ /* Z1[k] = (X1[128-2*k-1] + j * X1[2*k]) * (xcos2[k] + j * xsin2[k]); */
+ buf1[k].re = data[p] * xcos2[j] - data[q] * xsin2[j];
+ buf1[k].im = -1.0f * (data[q] * xcos2[j] + data[p] * xsin2[j]);
+ /* Z2[k] = (X2[128-2*k-1] + j * X2[2*k]) * (xcos2[k] + j * xsin2[k]); */
+ buf2[k].re = data[p + 1] * xcos2[j] - data[q + 1] * xsin2[j];
+ buf2[k].im = -1.0f * ( data[q + 1] * xcos2[j] + data[p + 1] * xsin2[j]);
+ }
+
+
+ fft_64p(&buf1[0]);
+ fft_64p(&buf2[0]);
+
+#ifdef DEBUG
+ //DEBUG FFT
+#if 0
+ printf("Post FFT, buf1\n");
+ for (i=0; i < 64; i++)
+ printf("%d %f %f\n", i, buf_1[i].re, buf_1[i].im);
+ printf("Post FFT, buf2\n");
+ for (i=0; i < 64; i++)
+ printf("%d %f %f\n", i, buf_2[i].re, buf_2[i].im);
+#endif
+#endif
+
+ /* Post IFFT complex multiply */
+ for( i=0; i < 64; i++) {
+ /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */
+ tmp_a_r = buf1[i].re;
+ tmp_a_i = -buf1[i].im;
+ buf1[i].re =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
+ buf1[i].im =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
+ /* y2[n] = z2[n] * (xcos2[n] + j * xsin2[n]) ; */
+ tmp_a_r = buf2[i].re;
+ tmp_a_i = -buf2[i].im;
+ buf2[i].re =(tmp_a_r * xcos2[i]) - (tmp_a_i * xsin2[i]);
+ buf2[i].im =(tmp_a_r * xsin2[i]) + (tmp_a_i * xcos2[i]);
+ }
+
+ data_ptr = data;
+ delay_ptr = delay;
+ window_ptr = window;
+
+ /* Window and convert to real valued signal, no overlap */
+ for(i=0; i< 64; i++) {
+ *data_ptr++ = -buf1[i].im * *window_ptr++;
+ *data_ptr++ = buf1[64-i-1].re * *window_ptr++;
+ }
+
+ for(i=0; i< 64; i++) {
+ *data_ptr++ = -buf1[i].re * *window_ptr++ + *delay_ptr++;
+ *data_ptr++ = buf1[64-i-1].im * *window_ptr++ + *delay_ptr++;
+ }
+
+ delay_ptr = delay;
+
+ for(i=0; i< 64; i++) {
+ *delay_ptr++ = -buf2[i].re * *--window_ptr;
+ *delay_ptr++ = buf2[64-i-1].im * *--window_ptr;
+ }
+
+ for(i=0; i< 64; i++) {
+ *delay_ptr++ = buf2[i].im * *--window_ptr;
+ *delay_ptr++ = -buf2[64-i-1].re * *--window_ptr;
+ }
+}
+
+//FIXME remove - for timing code
+///#include <sys/time.h>
+//FIXME remove
+
+
+void imdct_do_512 (float data[], float delay[])
+{
+ int i, j;
+ float tmp_a_r, tmp_a_i;
+ float *data_ptr;
+ float *delay_ptr;
+ float *window_ptr;
+
+// 512 IMDCT with source and dest data in 'data'
+// Pre IFFT complex multiply plus IFFT complex conjugate
+
+ for( i=0; i < 128; i++) {
+ j = pm128[i];
+ //a = (data[256-2*j-1] - data[2*j]) * (xcos1[j] + xsin1[j]);
+ //c = data[2*j] * xcos1[j];
+ //b = data[256-2*j-1] * xsin1[j];
+ //buf1[i].re = a - b + c;
+ //buf1[i].im = b + c;
+ buf[i].re = (data[256-2*j-1] * xcos1[j]) - (data[2*j] * xsin1[j]);
+ buf[i].im = -1.0 * (data[2*j] * xcos1[j] + data[256-2*j-1] * xsin1[j]);
+ }
+
+ fft_128p (&buf[0]);
+
+// Post IFFT complex multiply plus IFFT complex conjugate
+ for (i=0; i < 128; i++) {
+ tmp_a_r = buf[i].re;
+ tmp_a_i = buf[i].im;
+ //a = (tmp_a_r - tmp_a_i) * (xcos1[j] + xsin1[j]);
+ //b = tmp_a_r * xsin1[j];
+ //c = tmp_a_i * xcos1[j];
+ //buf[j].re = a - b + c;
+ //buf[j].im = b + c;
+ buf[i].re =(tmp_a_r * xcos1[i]) + (tmp_a_i * xsin1[i]);
+ buf[i].im =(tmp_a_r * xsin1[i]) - (tmp_a_i * xcos1[i]);
+ }
+
+ data_ptr = data;
+ delay_ptr = delay;
+ window_ptr = window;
+
+// Window and convert to real valued signal
+ for (i=0; i< 64; i++) {
+ *data_ptr++ = -buf[64+i].im * *window_ptr++ + *delay_ptr++;
+ *data_ptr++ = buf[64-i-1].re * *window_ptr++ + *delay_ptr++;
+ }
+
+ for(i=0; i< 64; i++) {
+ *data_ptr++ = -buf[i].re * *window_ptr++ + *delay_ptr++;
+ *data_ptr++ = buf[128-i-1].im * *window_ptr++ + *delay_ptr++;
+ }
+
+// The trailing edge of the window goes into the delay line
+ delay_ptr = delay;
+
+ for(i=0; i< 64; i++) {
+ *delay_ptr++ = -buf[64+i].re * *--window_ptr;
+ *delay_ptr++ = buf[64-i-1].im * *--window_ptr;
+ }
+
+ for(i=0; i<64; i++) {
+ *delay_ptr++ = buf[i].im * *--window_ptr;
+ *delay_ptr++ = -buf[128-i-1].re * *--window_ptr;
+ }
+}
+
+
+void imdct_do_512_nol (float data[], float delay[])
+{
+ int i, j;
+
+ float tmp_a_i;
+ float tmp_a_r;
+
+ float *data_ptr;
+ float *delay_ptr;
+ float *window_ptr;
+
+ //
+ // 512 IMDCT with source and dest data in 'data'
+ //
+
+ // Pre IFFT complex multiply plus IFFT cmplx conjugate
+
+ for( i=0; i < 128; i++) {
+ /* z[i] = (X[256-2*i-1] + j * X[2*i]) * (xcos1[i] + j * xsin1[i]) */
+ j = pm128[i];
+ //a = (data[256-2*j-1] - data[2*j]) * (xcos1[j] + xsin1[j]);
+ //c = data[2*j] * xcos1[j];
+ //b = data[256-2*j-1] * xsin1[j];
+ //buf1[i].re = a - b + c;
+
+ //buf1[i].im = b + c;
+ buf[i].re = (data[256-2*j-1] * xcos1[j]) - (data[2*j] * xsin1[j]);
+ buf[i].im = -1.0 * (data[2*j] * xcos1[j] + data[256-2*j-1] * xsin1[j]);
+ }
+
+ fft_128p (&buf[0]);
+
+ /* Post IFFT complex multiply plus IFFT complex conjugate*/
+ for (i=0; i < 128; i++) {
+ /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */
+ /* int j1 = i; */
+ tmp_a_r = buf[i].re;
+ tmp_a_i = buf[i].im;
+ //a = (tmp_a_r - tmp_a_i) * (xcos1[j] + xsin1[j]);
+ //b = tmp_a_r * xsin1[j];
+ //c = tmp_a_i * xcos1[j];
+ //buf[j].re = a - b + c;
+ //buf[j].im = b + c;
+ buf[i].re =(tmp_a_r * xcos1[i]) + (tmp_a_i * xsin1[i]);
+ buf[i].im =(tmp_a_r * xsin1[i]) - (tmp_a_i * xcos1[i]);
+ }
+
+ data_ptr = data;
+ delay_ptr = delay;
+ window_ptr = window;
+
+ /* Window and convert to real valued signal, no overlap here*/
+ for (i=0; i< 64; i++) {
+ *data_ptr++ = -buf[64+i].im * *window_ptr++;
+ *data_ptr++ = buf[64-i-1].re * *window_ptr++;
+ }
+
+ for(i=0; i< 64; i++) {
+ *data_ptr++ = -buf[i].re * *window_ptr++;
+ *data_ptr++ = buf[128-i-1].im * *window_ptr++;
+ }
+
+ /* The trailing edge of the window goes into the delay line */
+ delay_ptr = delay;
+
+ for(i=0; i< 64; i++) {
+ *delay_ptr++ = -buf[64+i].re * *--window_ptr;
+ *delay_ptr++ = buf[64-i-1].im * *--window_ptr;
+ }
+
+ for(i=0; i<64; i++) {
+ *delay_ptr++ = buf[i].im * *--window_ptr;
+ *delay_ptr++ = -buf[128-i-1].re * *--window_ptr;
+ }
+}
+
+void imdct (bsi_t *bsi,audblk_t *audblk, stream_samples_t samples, int16_t *s16_samples, dm_par_t* dm_par)
+{
+ int i;
+ int doable = 0;
+ float *center=NULL, *left, *right, *left_sur, *right_sur;
+ float *delay_left, *delay_right;
+ float *delay1_left, *delay1_right, *delay1_center, *delay1_sr, *delay1_sl;
+ float right_tmp, left_tmp;
+ void (*do_imdct)(float data[], float deley[]);
+
+ // test if dm in frequency is doable
+ if (!(doable = audblk->blksw[0]))
+ do_imdct = imdct_do_512;
+ else
+ do_imdct = imdct_do_256;
+
+ // downmix in the frequency domain if all the channels
+ // use the same imdct
+ for (i=0; i < bsi->nfchans; i++) {
+ if (doable != audblk->blksw[i]) {
+ do_imdct = NULL;
+ break;
+ }
+ }
+
+ if (do_imdct) {
+ //dowmix first and imdct
+ switch(bsi->acmod) {
+ case 7: // 3/2
+ downmix_3f_2r_to_2ch (samples[0], dm_par);
+ break;
+ case 6: // 2/2
+ downmix_2f_2r_to_2ch (samples[0], dm_par);
+ break;
+ case 5: // 3/1
+ downmix_3f_1r_to_2ch (samples[0], dm_par);
+ break;
+ case 4: // 2/1
+ downmix_2f_1r_to_2ch (samples[0], dm_par);
+ break;
+ case 3: // 3/0
+ downmix_3f_0r_to_2ch (samples[0], dm_par);
+ break;
+ case 2:
+ break;
+ default: // 1/0
+ if (bsi->acmod == 1)
+ center = samples[0];
+ else if (bsi->acmod == 0)
+ center = samples[ac3_config.dual_mono_ch_sel];
+ do_imdct(center, delay[0]); // no downmix
+
+ stream_sample_1ch_to_s16 (s16_samples, center);
+
+ return;
+ //goto done;
+ break;
+ }
+
+ do_imdct (samples[0], delay[0]);
+ do_imdct (samples[1], delay[1]);
+ stream_sample_2ch_to_s16(s16_samples, samples[0], samples[1]);
+
+ } else { //imdct and then dowmix
+ // delay and samples should be saved and mixed
+ //fprintf(stderr, "time domain downmix\n");
+ for (i=0; i<bsi->nfchans; i++) {
+ if (audblk->blksw[i])
+ imdct_do_256_nol (samples[i],delay1[i]);
+ else
+ imdct_do_512_nol (samples[i],delay1[i]);
+ }
+
+ // mix the sample, overlap
+ switch(bsi->acmod) {
+ case 7: // 3/2
+ left = samples[0];
+ center = samples[1];
+ right = samples[2];
+ left_sur = samples[3];
+ right_sur = samples[4];
+ delay_left = delay[0];
+ delay_right = delay[1];
+ delay1_left = delay1[0];
+ delay1_center = delay1[1];
+ delay1_right = delay1[2];
+ delay1_sl = delay1[3];
+ delay1_sr = delay1[4];
+
+ for (i = 0; i < 256; i++) {
+ left_tmp = dm_par->unit * *left++ + dm_par->clev * *center + dm_par->slev * *left_sur++;
+ right_tmp= dm_par->unit * *right++ + dm_par->clev * *center++ + dm_par->slev * *right_sur++;
+ *s16_samples++ = (int16_t)(left_tmp + *delay_left);
+ *s16_samples++ = (int16_t)(right_tmp + *delay_right);
+ *delay_left++ = dm_par->unit * *delay1_left++ + dm_par->clev * *delay1_center + dm_par->slev * *delay1_sl++;
+ *delay_right++ = dm_par->unit * *delay1_right++ + dm_par->clev * *center++ + dm_par->slev * *delay1_sr++;
+ }
+ break;
+ case 6: // 2/2
+ left = samples[0];
+ right = samples[1];
+ left_sur = samples[2];
+ right_sur = samples[3];
+ delay_left = delay[0];
+ delay_right = delay[1];
+ delay1_left = delay1[0];
+ delay1_right = delay1[1];
+ delay1_sl = delay1[2];
+ delay1_sr = delay1[3];
+
+ for (i = 0; i < 256; i++) {
+ left_tmp = dm_par->unit * *left++ + dm_par->slev * *left_sur++;
+ right_tmp= dm_par->unit * *right++ + dm_par->slev * *right_sur++;
+ *s16_samples++ = (int16_t)(left_tmp + *delay_left);
+ *s16_samples++ = (int16_t)(right_tmp + *delay_right);
+ *delay_left++ = dm_par->unit * *delay1_left++ + dm_par->slev * *delay1_sl++;
+ *delay_right++ = dm_par->unit * *delay1_right++ + dm_par->slev * *delay1_sr++;
+ }
+ break;
+ case 5: // 3/1
+ left = samples[0];
+ center = samples[1];
+ right = samples[2];
+ right_sur = samples[3];
+ delay_left = delay[0];
+ delay_right = delay[1];
+ delay1_left = delay1[0];
+ delay1_center = delay1[1];
+ delay1_right = delay1[2];
+ delay1_sl = delay1[3];
+
+ for (i = 0; i < 256; i++) {
+ left_tmp = dm_par->unit * *left++ + dm_par->clev * *center - dm_par->slev * *right_sur;
+ right_tmp= dm_par->unit * *right++ + dm_par->clev * *center++ + dm_par->slev * *right_sur++;
+ *s16_samples++ = (int16_t)(left_tmp + *delay_left);
+ *s16_samples++ = (int16_t)(right_tmp + *delay_right);
+ *delay_left++ = dm_par->unit * *delay1_left++ + dm_par->clev * *delay1_center + dm_par->slev * *delay1_sl;
+ *delay_right++ = dm_par->unit * *delay1_right++ + dm_par->clev * *center++ + dm_par->slev * *delay1_sl++;
+ }
+ break;
+ case 4: // 2/1
+ left = samples[0];
+ right = samples[1];
+ right_sur = samples[2];
+ delay_left = delay[0];
+ delay_right = delay[1];
+ delay1_left = delay1[0];
+ delay1_right = delay1[1];
+ delay1_sl = delay1[2];
+
+ for (i = 0; i < 256; i++) {
+ left_tmp = dm_par->unit * *left++ - dm_par->slev * *right_sur;
+ right_tmp= dm_par->unit * *right++ + dm_par->slev * *right_sur++;
+ *s16_samples++ = (int16_t)(left_tmp + *delay_left);
+ *s16_samples++ = (int16_t)(right_tmp + *delay_right);
+ *delay_left++ = dm_par->unit * *delay1_left++ + dm_par->slev * *delay1_sl;
+ *delay_right++ = dm_par->unit * *delay1_right++ + dm_par->slev * *delay1_sl++;
+ }
+ break;
+ case 3: // 3/0
+ left = samples[0];
+ center = samples[1];
+ right = samples[2];
+ delay_left = delay[0];
+ delay_right = delay[1];
+ delay1_left = delay1[0];
+ delay1_center = delay1[1];
+ delay1_right = delay1[2];
+
+ for (i = 0; i < 256; i++) {
+ left_tmp = dm_par->unit * *left++ + dm_par->clev * *center;
+ right_tmp= dm_par->unit * *right++ + dm_par->clev * *center++;
+ *s16_samples++ = (int16_t)(left_tmp + *delay_left);
+ *s16_samples++ = (int16_t)(right_tmp + *delay_right);
+ *delay_left++ = dm_par->unit * *delay1_left++ + dm_par->clev * *delay1_center;
+ *delay_right++ = dm_par->unit * *delay1_right++ + dm_par->clev * *center++;
+ }
+ break;
+ case 2: // copy to output
+ for (i = 0; i < 256; i++) {
+ *s16_samples++ = (int16_t)samples[0][i];
+ *s16_samples++ = (int16_t)samples[1][i];
+ }
+ break;
+ }
+ }
+}
+
diff --git a/src/libac3/imdct.h b/src/libac3/imdct.h
new file mode 100644
index 000000000..8a4479375
--- /dev/null
+++ b/src/libac3/imdct.h
@@ -0,0 +1,36 @@
+/*
+ * imdct.h
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+#include "cmplx.h"
+
+void imdct_init(void);
+
+void imdct (bsi_t *bsi,audblk_t *audblk, stream_samples_t samples,
+ int16_t *s16_samples, dm_par_t *dm_par);
+
+void fft_64p (complex_t *);
+void imdct_do_512 (float data[],float delay[]);
+void imdct_do_512_nol (float data[], float delay[]);
+void imdct_do_256 (float data[],float delay[]);
+
diff --git a/src/libac3/parse.c b/src/libac3/parse.c
new file mode 100644
index 000000000..47ed3b407
--- /dev/null
+++ b/src/libac3/parse.c
@@ -0,0 +1,484 @@
+/*
+ * parse.c
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "ac3.h"
+#include "ac3_internal.h"
+
+
+#include "bitstream.h"
+#include "crc.h"
+#include "parse.h"
+
+/* Misc LUT */
+static const uint16_t nfchans[8] = {2,1,2,3,3,4,4,5};
+
+struct frmsize_s
+{
+ uint16_t bit_rate;
+ uint16_t frm_size[3];
+};
+
+static const struct frmsize_s frmsizecod_tbl[64] =
+{
+ { 32 ,{64 ,69 ,96 } },
+ { 32 ,{64 ,70 ,96 } },
+ { 40 ,{80 ,87 ,120 } },
+ { 40 ,{80 ,88 ,120 } },
+ { 48 ,{96 ,104 ,144 } },
+ { 48 ,{96 ,105 ,144 } },
+ { 56 ,{112 ,121 ,168 } },
+ { 56 ,{112 ,122 ,168 } },
+ { 64 ,{128 ,139 ,192 } },
+ { 64 ,{128 ,140 ,192 } },
+ { 80 ,{160 ,174 ,240 } },
+ { 80 ,{160 ,175 ,240 } },
+ { 96 ,{192 ,208 ,288 } },
+ { 96 ,{192 ,209 ,288 } },
+ { 112 ,{224 ,243 ,336 } },
+ { 112 ,{224 ,244 ,336 } },
+ { 128 ,{256 ,278 ,384 } },
+ { 128 ,{256 ,279 ,384 } },
+ { 160 ,{320 ,348 ,480 } },
+ { 160 ,{320 ,349 ,480 } },
+ { 192 ,{384 ,417 ,576 } },
+ { 192 ,{384 ,418 ,576 } },
+ { 224 ,{448 ,487 ,672 } },
+ { 224 ,{448 ,488 ,672 } },
+ { 256 ,{512 ,557 ,768 } },
+ { 256 ,{512 ,558 ,768 } },
+ { 320 ,{640 ,696 ,960 } },
+ { 320 ,{640 ,697 ,960 } },
+ { 384 ,{768 ,835 ,1152 } },
+ { 384 ,{768 ,836 ,1152 } },
+ { 448 ,{896 ,975 ,1344 } },
+ { 448 ,{896 ,976 ,1344 } },
+ { 512 ,{1024 ,1114 ,1536 } },
+ { 512 ,{1024 ,1115 ,1536 } },
+ { 576 ,{1152 ,1253 ,1728 } },
+ { 576 ,{1152 ,1254 ,1728 } },
+ { 640 ,{1280 ,1393 ,1920 } },
+ { 640 ,{1280 ,1394 ,1920 } }
+};
+
+/* Parse a syncinfo structure, minus the sync word */
+void parse_syncinfo(syncinfo_t *syncinfo, uint8_t *data)
+{
+ //
+ // We need to read in the entire syncinfo struct (0x0b77 + 24 bits)
+ // in order to determine how big the frame is
+ //
+
+ // Get the sampling rate
+ syncinfo->fscod = (data[2] >> 6) & 0x3;
+
+ if(syncinfo->fscod == 3) {
+ //invalid sampling rate code
+#ifndef FAST_ERROR
+ error_flag = 1;
+#endif
+ return;
+ }
+ else if(syncinfo->fscod == 2)
+ syncinfo->sampling_rate = 32000;
+ else if(syncinfo->fscod == 1)
+ syncinfo->sampling_rate = 44100;
+ else
+ syncinfo->sampling_rate = 48000;
+
+ // Get the frame size code
+ syncinfo->frmsizecod = data[2] & 0x3f;
+
+ // Calculate the frame size and bitrate
+ syncinfo->frame_size =
+ frmsizecod_tbl[syncinfo->frmsizecod].frm_size[syncinfo->fscod];
+ syncinfo->bit_rate = frmsizecod_tbl[syncinfo->frmsizecod].bit_rate;
+
+}
+
+
+/**
+ * This routine fills a bsi struct from the AC3 stream
+ **/
+
+void parse_bsi(bsi_t *bsi)
+{
+ /* Check the AC-3 version number */
+ bsi->bsid = bitstream_get(5);
+
+ /* Get the audio service provided by the steram */
+ bsi->bsmod = bitstream_get(3);
+
+ /* Get the audio coding mode (ie how many channels)*/
+ bsi->acmod = bitstream_get(3);
+ /* Predecode the number of full bandwidth channels as we use this
+ * number a lot */
+ bsi->nfchans = nfchans[bsi->acmod];
+
+ /* If it is in use, get the centre channel mix level */
+ if ((bsi->acmod & 0x1) && (bsi->acmod != 0x1))
+ bsi->cmixlev = bitstream_get(2);
+
+ /* If it is in use, get the surround channel mix level */
+ if (bsi->acmod & 0x4)
+ bsi->surmixlev = bitstream_get(2);
+
+ /* Get the dolby surround mode if in 2/0 mode */
+ if(bsi->acmod == 0x2)
+ bsi->dsurmod= bitstream_get(2);
+
+ /* Is the low frequency effects channel on? */
+ bsi->lfeon = bitstream_get(1);
+
+ /* Get the dialogue normalization level */
+ bsi->dialnorm = bitstream_get(5);
+
+ /* Does compression gain exist? */
+ if ((bsi->compre = bitstream_get(1))) {
+ /* Get compression gain */
+ bsi->compr = bitstream_get(8);
+ }
+
+ /* Does language code exist? */
+ if ((bsi->langcode = bitstream_get(1))) {
+ /* Get langauge code */
+ bsi->langcod = bitstream_get(8);
+ }
+
+ /* Does audio production info exist? */
+ if ((bsi->audprodie = bitstream_get(1))) {
+ /* Get mix level */
+ bsi->mixlevel = bitstream_get(5);
+
+ /* Get room type */
+ bsi->roomtyp = bitstream_get(2);
+ }
+
+ /* If we're in dual mono mode then get some extra info */
+ if (!bsi->acmod) {
+ /* Get the dialogue normalization level two */
+ bsi->dialnorm2 = bitstream_get(5);
+
+ /* Does compression gain two exist? */
+ if ((bsi->compr2e = bitstream_get(1))) {
+ /* Get compression gain two */
+ bsi->compr2 = bitstream_get(8);
+ }
+
+ /* Does language code two exist? */
+ if ((bsi->langcod2e = bitstream_get(1))) {
+ /* Get langauge code two */
+ bsi->langcod2 = bitstream_get(8);
+ }
+
+ /* Does audio production info two exist? */
+ if ((bsi->audprodi2e = bitstream_get(1))) {
+ /* Get mix level two */
+ bsi->mixlevel2 = bitstream_get(5);
+
+ /* Get room type two */
+ bsi->roomtyp2 = bitstream_get(2);
+ }
+ }
+
+ /* Get the copyright bit */
+ bsi->copyrightb = bitstream_get(1);
+
+ /* Get the original bit */
+ bsi->origbs = bitstream_get(1);
+
+ /* Does timecode one exist? */
+ if ((bsi->timecod1e = bitstream_get(1)))
+ bsi->timecod1 = bitstream_get(14);
+
+ /* Does timecode two exist? */
+ if ((bsi->timecod2e = bitstream_get(1)))
+ bsi->timecod2 = bitstream_get(14);
+
+ /* Does addition info exist? */
+ if ((bsi->addbsie = bitstream_get(1))) {
+ uint32_t i;
+
+ /* Get how much info is there */
+ bsi->addbsil = bitstream_get(6);
+
+ /* Get the additional info */
+ for(i=0;i<(bsi->addbsil + 1);i++)
+ bsi->addbsi[i] = bitstream_get(8);
+ }
+
+}
+
+
+/* More pain inducing parsing */
+void parse_audblk(bsi_t *bsi,audblk_t *audblk)
+{
+ int i,j;
+
+ for (i=0; i < bsi->nfchans; i++) {
+ /* Is this channel an interleaved 256 + 256 block ? */
+ audblk->blksw[i] = bitstream_get(1);
+ }
+
+ for (i=0;i < bsi->nfchans; i++) {
+ /* Should we dither this channel? */
+ audblk->dithflag[i] = bitstream_get(1);
+ }
+
+ /* Does dynamic range control exist? */
+ if ((audblk->dynrnge = bitstream_get(1))) {
+ /* Get dynamic range info */
+ audblk->dynrng = bitstream_get(8);
+ }
+
+ /* If we're in dual mono mode then get the second channel DR info */
+ if (bsi->acmod == 0) {
+ /* Does dynamic range control two exist? */
+ if ((audblk->dynrng2e = bitstream_get(1))) {
+ /* Get dynamic range info */
+ audblk->dynrng2 = bitstream_get(8);
+ }
+ }
+
+ /* Does coupling strategy exist? */
+ if ((audblk->cplstre = bitstream_get(1))) {
+ /* Is coupling turned on? */
+ if ((audblk->cplinu = bitstream_get(1))) {
+ for(i=0;i < bsi->nfchans; i++)
+ audblk->chincpl[i] = bitstream_get(1);
+ if(bsi->acmod == 0x2)
+ audblk->phsflginu = bitstream_get(1);
+ audblk->cplbegf = bitstream_get(4);
+ audblk->cplendf = bitstream_get(4);
+ audblk->ncplsubnd = (audblk->cplendf + 2) - audblk->cplbegf + 1;
+
+ /* Calculate the start and end bins of the coupling channel */
+ audblk->cplstrtmant = (audblk->cplbegf * 12) + 37 ;
+ audblk->cplendmant = ((audblk->cplendf + 3) * 12) + 37;
+
+ /* The number of combined subbands is ncplsubnd minus each combined
+ * band */
+ audblk->ncplbnd = audblk->ncplsubnd;
+
+ for(i=1; i< audblk->ncplsubnd; i++) {
+ audblk->cplbndstrc[i] = bitstream_get(1);
+ audblk->ncplbnd -= audblk->cplbndstrc[i];
+ }
+ }
+ }
+
+ if(audblk->cplinu) {
+ /* Loop through all the channels and get their coupling co-ords */
+ for(i=0;i < bsi->nfchans;i++) {
+ if(!audblk->chincpl[i])
+ continue;
+
+ /* Is there new coupling co-ordinate info? */
+ if ((audblk->cplcoe[i] = bitstream_get(1))) {
+ audblk->mstrcplco[i] = bitstream_get(2);
+ for(j=0;j < audblk->ncplbnd; j++) {
+ audblk->cplcoexp[i][j] = bitstream_get(4);
+ audblk->cplcomant[i][j] = bitstream_get(4);
+ }
+ }
+ }
+
+ /* If we're in dual mono mode, there's going to be some phase info */
+ if( (bsi->acmod == 0x2) && audblk->phsflginu &&
+ (audblk->cplcoe[0] || audblk->cplcoe[1])) {
+ for(j=0;j < audblk->ncplbnd; j++)
+ audblk->phsflg[j] = bitstream_get(1);
+
+ }
+ }
+
+ /* If we're in dual mono mode, there may be a rematrix strategy */
+ if(bsi->acmod == 0x2) {
+ if ((audblk->rematstr = bitstream_get(1))) {
+ if (!audblk->cplinu) {
+ for(i = 0; i < 4; i++)
+ audblk->rematflg[i] = bitstream_get(1);
+ }
+ if((audblk->cplbegf > 2) && audblk->cplinu) {
+ for(i = 0; i < 4; i++)
+ audblk->rematflg[i] = bitstream_get(1);
+ }
+ if((audblk->cplbegf <= 2) && audblk->cplinu) {
+ for(i = 0; i < 3; i++)
+ audblk->rematflg[i] = bitstream_get(1);
+ }
+ if((audblk->cplbegf == 0) && audblk->cplinu)
+ for(i = 0; i < 2; i++)
+ audblk->rematflg[i] = bitstream_get(1);
+
+ }
+ }
+
+ if (audblk->cplinu) {
+ /* Get the coupling channel exponent strategy */
+ audblk->cplexpstr = bitstream_get(2);
+ audblk->ncplgrps = (audblk->cplendmant - audblk->cplstrtmant) /
+ (((audblk->cplexpstr-1)>=0)?(3 << (audblk->cplexpstr-1)):(3 >> (-(audblk->cplexpstr-1))));
+ }
+
+ for(i = 0; i < bsi->nfchans; i++)
+ audblk->chexpstr[i] = bitstream_get(2);
+
+ /* Get the exponent strategy for lfe channel */
+ if(bsi->lfeon)
+ audblk->lfeexpstr = bitstream_get(1);
+
+ /* Determine the bandwidths of all the fbw channels */
+ for(i = 0; i < bsi->nfchans; i++) {
+ uint16_t grp_size;
+
+ if(audblk->chexpstr[i] != EXP_REUSE) {
+ if (audblk->cplinu && audblk->chincpl[i]) {
+ audblk->endmant[i] = audblk->cplstrtmant;
+ } else {
+ audblk->chbwcod[i] = bitstream_get(6);
+ audblk->endmant[i] = ((audblk->chbwcod[i] + 12) * 3) + 37;
+ }
+
+ /* Calculate the number of exponent groups to fetch */
+ grp_size = 3 * (1 << (audblk->chexpstr[i] - 1));
+ audblk->nchgrps[i] = (audblk->endmant[i] - 1 + (grp_size - 3)) / grp_size;
+ }
+ }
+
+ /* Get the coupling exponents if they exist */
+ if(audblk->cplinu && (audblk->cplexpstr != EXP_REUSE)) {
+ audblk->cplabsexp = bitstream_get(4);
+ for(i=0;i< audblk->ncplgrps;i++)
+ audblk->cplexps[i] = bitstream_get(7);
+ }
+
+ /* Get the fwb channel exponents */
+ for(i=0;i < bsi->nfchans; i++) {
+ if(audblk->chexpstr[i] != EXP_REUSE) {
+ audblk->exps[i][0] = bitstream_get(4);
+ for(j=1;j<=audblk->nchgrps[i];j++)
+ audblk->exps[i][j] = bitstream_get(7);
+ audblk->gainrng[i] = bitstream_get(2);
+ }
+ }
+
+ /* Get the lfe channel exponents */
+ if(bsi->lfeon && (audblk->lfeexpstr != EXP_REUSE)) {
+ audblk->lfeexps[0] = bitstream_get(4);
+ audblk->lfeexps[1] = bitstream_get(7);
+ audblk->lfeexps[2] = bitstream_get(7);
+ }
+
+ /* Get the parametric bit allocation parameters */
+ audblk->baie = bitstream_get(1);
+
+ if(audblk->baie) {
+ audblk->sdcycod = bitstream_get(2);
+ audblk->fdcycod = bitstream_get(2);
+ audblk->sgaincod = bitstream_get(2);
+ audblk->dbpbcod = bitstream_get(2);
+ audblk->floorcod = bitstream_get(3);
+ }
+
+ /* Get the SNR off set info if it exists */
+ audblk->snroffste = bitstream_get(1);
+
+ if(audblk->snroffste) {
+ audblk->csnroffst = bitstream_get(6);
+
+ if(audblk->cplinu) {
+ audblk->cplfsnroffst = bitstream_get(4);
+ audblk->cplfgaincod = bitstream_get(3);
+ }
+
+ for(i = 0;i < bsi->nfchans; i++) {
+ audblk->fsnroffst[i] = bitstream_get(4);
+ audblk->fgaincod[i] = bitstream_get(3);
+ }
+ if(bsi->lfeon) {
+
+ audblk->lfefsnroffst = bitstream_get(4);
+ audblk->lfefgaincod = bitstream_get(3);
+ }
+ }
+
+ /* Get coupling leakage info if it exists */
+ if(audblk->cplinu) {
+ audblk->cplleake = bitstream_get(1);
+
+ if(audblk->cplleake) {
+ audblk->cplfleak = bitstream_get(3);
+ audblk->cplsleak = bitstream_get(3);
+ }
+ }
+
+ /* Get the delta bit alloaction info */
+ audblk->deltbaie = bitstream_get(1);
+
+ if(audblk->deltbaie) {
+ if(audblk->cplinu)
+ audblk->cpldeltbae = bitstream_get(2);
+
+ for(i = 0;i < bsi->nfchans; i++)
+ audblk->deltbae[i] = bitstream_get(2);
+
+ if (audblk->cplinu && (audblk->cpldeltbae == DELTA_BIT_NEW)) {
+ audblk->cpldeltnseg = bitstream_get(3);
+ for(i = 0;i < audblk->cpldeltnseg + 1; i++) {
+ audblk->cpldeltoffst[i] = bitstream_get(5);
+ audblk->cpldeltlen[i] = bitstream_get(4);
+ audblk->cpldeltba[i] = bitstream_get(3);
+ }
+ }
+
+ for(i = 0;i < bsi->nfchans; i++) {
+ if (audblk->deltbae[i] == DELTA_BIT_NEW) {
+ audblk->deltnseg[i] = bitstream_get(3);
+ for(j = 0; j < audblk->deltnseg[i] + 1; j++) {
+ audblk->deltoffst[i][j] = bitstream_get(5);
+ audblk->deltlen[i][j] = bitstream_get(4);
+ audblk->deltba[i][j] = bitstream_get(3);
+ }
+ }
+ }
+ }
+
+ /* Check to see if there's any dummy info to get */
+ if((audblk->skiple = bitstream_get(1))) {
+ uint16_t skip_data;
+
+ audblk->skipl = bitstream_get(9);
+
+ for (i = 0; i < audblk->skipl; i++) {
+ skip_data = bitstream_get(8);
+ }
+ }
+
+}
diff --git a/src/libac3/parse.h b/src/libac3/parse.h
new file mode 100644
index 000000000..6264fea1d
--- /dev/null
+++ b/src/libac3/parse.h
@@ -0,0 +1,26 @@
+/*
+ * parse.h
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+void parse_syncinfo(syncinfo_t *syncinfo,uint8_t *data);
+void parse_audblk(bsi_t *bsi,audblk_t *audblk);
+void parse_bsi(bsi_t *bsi);
diff --git a/src/libac3/rematrix.c b/src/libac3/rematrix.c
new file mode 100644
index 000000000..95ce0117c
--- /dev/null
+++ b/src/libac3/rematrix.c
@@ -0,0 +1,95 @@
+/*
+ * rematrix.c
+ *
+ * Copyright (C) Aaron Holtzman - July 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "ac3.h"
+#include "ac3_internal.h"
+
+
+#include "rematrix.h"
+
+
+struct rematrix_band_s
+{
+ uint32_t start;
+ uint32_t end;
+} rematrix_band[] = {
+ {13, 24},
+ {25, 36},
+ {37, 60},
+ {61, 252}
+};
+
+
+/**
+ *
+ **/
+
+inline uint32_t min (uint32_t a, uint32_t b)
+{
+ return (a < b) ? a : b;
+}
+
+
+/**
+ * This routine simply does stereo remartixing for the 2 channel
+ * stereo mode
+ **/
+
+void rematrix (audblk_t *audblk, stream_samples_t samples)
+{
+ uint32_t num_bands;
+ uint32_t start;
+ uint32_t end;
+ int i,j;
+
+ if (!audblk->cplinu || audblk->cplbegf > 2)
+ num_bands = 4;
+ else if (audblk->cplbegf > 0)
+ num_bands = 3;
+ else
+ num_bands = 2;
+
+ for (i=0; i < num_bands; i++) {
+ if (!audblk->rematflg[i])
+ continue;
+
+ start = rematrix_band[i].start;
+ end = min (rematrix_band[i].end ,12 * audblk->cplbegf + 36);
+
+ for (j=start;j < end; j++) {
+ float left,right;
+
+ left = samples[0][j] + samples[1][j];
+ right = samples[0][j] - samples[1][j];
+ samples[0][j] = left;
+ samples[1][j] = right;
+ }
+ }
+}
diff --git a/src/libac3/rematrix.h b/src/libac3/rematrix.h
new file mode 100644
index 000000000..0be6528f6
--- /dev/null
+++ b/src/libac3/rematrix.h
@@ -0,0 +1,25 @@
+/*
+ * rematrix.h
+ *
+ * Copyright (C) Aaron Holtzman - July 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+void rematrix(audblk_t *audblk, stream_samples_t samples);
diff --git a/src/libac3/sanity_check.c b/src/libac3/sanity_check.c
new file mode 100644
index 000000000..ef0af0bd2
--- /dev/null
+++ b/src/libac3/sanity_check.c
@@ -0,0 +1,128 @@
+/*
+ * sanity_check.c
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "ac3.h"
+#include "ac3_internal.h"
+#include "sanity_check.h"
+
+
+/**
+ *
+ **/
+
+void sanity_check_init(syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk)
+{
+ syncinfo->magic = AC3_MAGIC_NUMBER;
+ bsi->magic = AC3_MAGIC_NUMBER;
+ audblk->magic1 = AC3_MAGIC_NUMBER;
+ audblk->magic2 = AC3_MAGIC_NUMBER;
+ audblk->magic3 = AC3_MAGIC_NUMBER;
+}
+
+
+/**
+ *
+ **/
+
+int sanity_check(syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk)
+{
+ int i;
+
+ if(syncinfo->magic != AC3_MAGIC_NUMBER) {
+ fprintf(stderr,"\n** Sanity check failed -- syncinfo magic number **");
+ return -1;
+ }
+
+ if(bsi->magic != AC3_MAGIC_NUMBER) {
+ fprintf(stderr,"\n** Sanity check failed -- bsi magic number **");
+ return -1;
+ }
+
+ if(audblk->magic1 != AC3_MAGIC_NUMBER) {
+ fprintf(stderr,"\n** Sanity check failed -- audblk magic number 1 **");
+ return -1;
+ }
+
+ if(audblk->magic2 != AC3_MAGIC_NUMBER) {
+ fprintf(stderr,"\n** Sanity check failed -- audblk magic number 2 **");
+ return -1;
+ }
+
+ if(audblk->magic3 != AC3_MAGIC_NUMBER) {
+ fprintf(stderr,"\n** Sanity check failed -- audblk magic number 3 **");
+ return -1;
+ }
+
+ for(i = 0;i < 5 ; i++) {
+ if (audblk->fbw_exp[i][255] !=0 || audblk->fbw_exp[i][254] !=0 ||
+ audblk->fbw_exp[i][253] !=0) {
+ fprintf(stderr,"\n** Sanity check failed -- fbw_exp out of bounds **");
+ return -1;
+ }
+
+ if (audblk->fbw_bap[i][255] !=0 || audblk->fbw_bap[i][254] !=0 ||
+ audblk->fbw_bap[i][253] !=0) {
+ fprintf(stderr,"\n** Sanity check failed -- fbw_bap out of bounds **");
+ return -1;
+ }
+
+ }
+
+ if (audblk->cpl_exp[255] !=0 || audblk->cpl_exp[254] !=0 ||
+ audblk->cpl_exp[253] !=0) {
+ fprintf(stderr,"\n** Sanity check failed -- cpl_exp out of bounds **");
+ return -1;
+ }
+
+ if (audblk->cpl_bap[255] !=0 || audblk->cpl_bap[254] !=0 ||
+ audblk->cpl_bap[253] !=0) {
+ fprintf(stderr,"\n** Sanity check failed -- cpl_bap out of bounds **");
+ return -1;
+ }
+
+ if (audblk->cpl_flt[255] !=0 || audblk->cpl_flt[254] !=0 ||
+ audblk->cpl_flt[253] !=0) {
+ fprintf(stderr,"\n** Sanity check failed -- cpl_mant out of bounds **");
+ return -1;
+ }
+
+ if ((audblk->cplinu == 1) && (audblk->cplbegf > (audblk->cplendf+2))) {
+ fprintf(stderr,"\n** Sanity check failed -- cpl params inconsistent **");
+ return -1;
+ }
+
+ for(i=0; i < bsi->nfchans; i++) {
+ if((audblk->chincpl[i] == 0) && (audblk->chbwcod[i] > 60)) {
+ fprintf(stderr,"\n** Sanity check failed -- chbwcod too big **");
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/libac3/sanity_check.h b/src/libac3/sanity_check.h
new file mode 100644
index 000000000..ead9399c9
--- /dev/null
+++ b/src/libac3/sanity_check.h
@@ -0,0 +1,27 @@
+/*
+ * sanity_check.h
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of ac3dec, a free Dolby AC-3 stream decoder.
+ *
+ * ac3dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * ac3dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#define AC3_MAGIC_NUMBER 0xdeadbeef
+
+void sanity_check_init (syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk);
+int sanity_check (syncinfo_t *syncinfo, bsi_t *bsi, audblk_t *audblk);
diff --git a/src/libac3/srfft.c b/src/libac3/srfft.c
new file mode 100644
index 000000000..308fc2ccc
--- /dev/null
+++ b/src/libac3/srfft.c
@@ -0,0 +1,309 @@
+/*
+ * srfft.c
+ *
+ * Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - April 2000
+ *
+ * 64 and 128 point split radix fft for ac3dec
+ *
+ * The algorithm is desribed in the book:
+ * "Computational Frameworks of the Fast Fourier Transform".
+ *
+ * The ideas and the the organization of code borrowed from djbfft written by
+ * D. J. Bernstein <djb@cr.py.to>. djbff can be found at
+ * http://cr.yp.to/djbfft.html.
+ *
+ * srfft.c is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * srfft.c is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+
+#include "srfft.h"
+#include "srfftp.h"
+
+void fft_8 (complex_t *x);
+
+void fft_4(complex_t *x)
+{
+ /* delta_p = 1 here */
+ /* x[k] = sum_{i=0..3} x[i] * w^{i*k}, w=e^{-2*pi/4}
+ */
+
+ register float yt_r, yt_i, yb_r, yb_i, u_r, u_i, vi_r, vi_i;
+
+ yt_r = x[0].re;
+ yb_r = yt_r - x[2].re;
+ yt_r += x[2].re;
+
+ u_r = x[1].re;
+ vi_i = x[3].re - u_r;
+ u_r += x[3].re;
+
+ u_i = x[1].im;
+ vi_r = u_i - x[3].im;
+ u_i += x[3].im;
+
+ yt_i = yt_r;
+ yt_i += u_r;
+ x[0].re = yt_i;
+ yt_r -= u_r;
+ x[2].re = yt_r;
+ yt_i = yb_r;
+ yt_i += vi_r;
+ x[1].re = yt_i;
+ yb_r -= vi_r;
+ x[3].re = yb_r;
+
+ yt_i = x[0].im;
+ yb_i = yt_i - x[2].im;
+ yt_i += x[2].im;
+
+ yt_r = yt_i;
+ yt_r += u_i;
+ x[0].im = yt_r;
+ yt_i -= u_i;
+ x[2].im = yt_i;
+ yt_r = yb_i;
+ yt_r += vi_i;
+ x[1].im = yt_r;
+ yb_i -= vi_i;
+ x[3].im = yb_i;
+}
+
+
+void fft_8 (complex_t *x)
+{
+ /* delta_p = diag{1, sqrt(i)} here */
+ /* x[k] = sum_{i=0..7} x[i] * w^{i*k}, w=e^{-2*pi/8}
+ */
+ register float wT1_r, wT1_i, wB1_r, wB1_i, wT2_r, wT2_i, wB2_r, wB2_i;
+
+ wT1_r = x[1].re;
+ wT1_i = x[1].im;
+ wB1_r = x[3].re;
+ wB1_i = x[3].im;
+
+ x[1] = x[2];
+ x[2] = x[4];
+ x[3] = x[6];
+ fft_4(&x[0]);
+
+
+ /* x[0] x[4] */
+ wT2_r = x[5].re;
+ wT2_r += x[7].re;
+ wT2_r += wT1_r;
+ wT2_r += wB1_r;
+ wT2_i = wT2_r;
+ wT2_r += x[0].re;
+ wT2_i = x[0].re - wT2_i;
+ x[0].re = wT2_r;
+ x[4].re = wT2_i;
+
+ wT2_i = x[5].im;
+ wT2_i += x[7].im;
+ wT2_i += wT1_i;
+ wT2_i += wB1_i;
+ wT2_r = wT2_i;
+ wT2_r += x[0].im;
+ wT2_i = x[0].im - wT2_i;
+ x[0].im = wT2_r;
+ x[4].im = wT2_i;
+
+ /* x[2] x[6] */
+ wT2_r = x[5].im;
+ wT2_r -= x[7].im;
+ wT2_r += wT1_i;
+ wT2_r -= wB1_i;
+ wT2_i = wT2_r;
+ wT2_r += x[2].re;
+ wT2_i = x[2].re - wT2_i;
+ x[2].re = wT2_r;
+ x[6].re = wT2_i;
+
+ wT2_i = x[5].re;
+ wT2_i -= x[7].re;
+ wT2_i += wT1_r;
+ wT2_i -= wB1_r;
+ wT2_r = wT2_i;
+ wT2_r += x[2].im;
+ wT2_i = x[2].im - wT2_i;
+ x[2].im = wT2_i;
+ x[6].im = wT2_r;
+
+
+ /* x[1] x[5] */
+ wT2_r = wT1_r;
+ wT2_r += wB1_i;
+ wT2_r -= x[5].re;
+ wT2_r -= x[7].im;
+ wT2_i = wT1_i;
+ wT2_i -= wB1_r;
+ wT2_i -= x[5].im;
+ wT2_i += x[7].re;
+
+ wB2_r = wT2_r;
+ wB2_r += wT2_i;
+ wT2_i -= wT2_r;
+ wB2_r *= HSQRT2;
+ wT2_i *= HSQRT2;
+ wT2_r = wB2_r;
+ wB2_r += x[1].re;
+ wT2_r = x[1].re - wT2_r;
+
+ wB2_i = x[5].re;
+ x[1].re = wB2_r;
+ x[5].re = wT2_r;
+
+ wT2_r = wT2_i;
+ wT2_r += x[1].im;
+ wT2_i = x[1].im - wT2_i;
+ wB2_r = x[5].im;
+ x[1].im = wT2_r;
+ x[5].im = wT2_i;
+
+ /* x[3] x[7] */
+ wT1_r -= wB1_i;
+ wT1_i += wB1_r;
+ wB1_r = wB2_i - x[7].im;
+ wB1_i = wB2_r + x[7].re;
+ wT1_r -= wB1_r;
+ wT1_i -= wB1_i;
+ wB1_r = wT1_r + wT1_i;
+ wB1_r *= HSQRT2;
+ wT1_i -= wT1_r;
+ wT1_i *= HSQRT2;
+ wB2_r = x[3].re;
+ wB2_i = wB2_r + wT1_i;
+ wB2_r -= wT1_i;
+ x[3].re = wB2_i;
+ x[7].re = wB2_r;
+ wB2_i = x[3].im;
+ wB2_r = wB2_i + wB1_r;
+ wB2_i -= wB1_r;
+ x[3].im = wB2_i;
+ x[7].im = wB2_r;
+}
+
+
+void fft_asmb(int k, complex_t *x, complex_t *wTB,
+ const complex_t *d, const complex_t *d_3)
+{
+ register complex_t *x2k, *x3k, *x4k, *wB;
+ register float a_r, a_i, a1_r, a1_i, u_r, u_i, v_r, v_i;
+
+ x2k = x + 2 * k;
+ x3k = x2k + 2 * k;
+ x4k = x3k + 2 * k;
+ wB = wTB + 2 * k;
+
+ TRANSZERO(x[0],x2k[0],x3k[0],x4k[0]);
+ TRANS(x[1],x2k[1],x3k[1],x4k[1],wTB[1],wB[1],d[1],d_3[1]);
+
+ --k;
+ for(;;) {
+ TRANS(x[2],x2k[2],x3k[2],x4k[2],wTB[2],wB[2],d[2],d_3[2]);
+ TRANS(x[3],x2k[3],x3k[3],x4k[3],wTB[3],wB[3],d[3],d_3[3]);
+ if (!--k) break;
+ x += 2;
+ x2k += 2;
+ x3k += 2;
+ x4k += 2;
+ d += 2;
+ d_3 += 2;
+ wTB += 2;
+ wB += 2;
+ }
+
+}
+
+void fft_asmb16(complex_t *x, complex_t *wTB)
+{
+ register float a_r, a_i, a1_r, a1_i, u_r, u_i, v_r, v_i;
+ int k = 2;
+
+ /* transform x[0], x[8], x[4], x[12] */
+ TRANSZERO(x[0],x[4],x[8],x[12]);
+
+ /* transform x[1], x[9], x[5], x[13] */
+ TRANS(x[1],x[5],x[9],x[13],wTB[1],wTB[5],delta16[1],delta16_3[1]);
+
+ /* transform x[2], x[10], x[6], x[14] */
+ TRANSHALF_16(x[2],x[6],x[10],x[14]);
+
+ /* transform x[3], x[11], x[7], x[15] */
+ TRANS(x[3],x[7],x[11],x[15],wTB[3],wTB[7],delta16[3],delta16_3[3]);
+
+}
+
+
+void fft_64p (complex_t *a)
+{
+ fft_8(&a[0]); fft_4(&a[8]); fft_4(&a[12]);
+ fft_asmb16(&a[0], &a[8]);
+
+ fft_8(&a[16]), fft_8(&a[24]);
+ fft_asmb(4, &a[0], &a[16],&delta32[0], &delta32_3[0]);
+
+ fft_8(&a[32]); fft_4(&a[40]); fft_4(&a[44]);
+ fft_asmb16(&a[32], &a[40]);
+
+ fft_8(&a[48]); fft_4(&a[56]); fft_4(&a[60]);
+ fft_asmb16(&a[48], &a[56]);
+
+ fft_asmb(8, &a[0], &a[32],&delta64[0], &delta64_3[0]);
+}
+
+
+void fft_128p (complex_t *a)
+{
+ fft_8(&a[0]); fft_4(&a[8]); fft_4(&a[12]);
+ fft_asmb16(&a[0], &a[8]);
+
+ fft_8(&a[16]), fft_8(&a[24]);
+ fft_asmb(4, &a[0], &a[16],&delta32[0], &delta32_3[0]);
+
+ fft_8(&a[32]); fft_4(&a[40]); fft_4(&a[44]);
+ fft_asmb16(&a[32], &a[40]);
+
+ fft_8(&a[48]); fft_4(&a[56]); fft_4(&a[60]);
+ fft_asmb16(&a[48], &a[56]);
+
+ fft_asmb(8, &a[0], &a[32],&delta64[0], &delta64_3[0]);
+
+ fft_8(&a[64]); fft_4(&a[72]); fft_4(&a[76]);
+ /* fft_16(&a[64]); */
+ fft_asmb16(&a[64], &a[72]);
+
+ fft_8(&a[80]); fft_8(&a[88]);
+
+ /* fft_32(&a[64]); */
+ fft_asmb(4, &a[64], &a[80],&delta32[0], &delta32_3[0]);
+
+ fft_8(&a[96]); fft_4(&a[104]), fft_4(&a[108]);
+ /* fft_16(&a[96]); */
+ fft_asmb16(&a[96], &a[104]);
+
+ fft_8(&a[112]), fft_8(&a[120]);
+ /* fft_32(&a[96]); */
+ fft_asmb(4, &a[96], &a[112], &delta32[0], &delta32_3[0]);
+
+ /* fft_128(&a[0]); */
+ fft_asmb(16, &a[0], &a[64], &delta128[0], &delta128_3[0]);
+}
diff --git a/src/libac3/srfft.h b/src/libac3/srfft.h
new file mode 100644
index 000000000..ca85deda1
--- /dev/null
+++ b/src/libac3/srfft.h
@@ -0,0 +1,39 @@
+/*
+ * srfft.h
+ *
+ * Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - April 2000
+ *
+ * 64 and 128 point split radix fft for ac3dec
+ *
+ * The algorithm is desribed in the book:
+ * "Computational Frameworks of the Fast Fourier Transform".
+ *
+ * The ideas and the the organization of code borrowed from djbfft written by
+ * D. J. Bernstein <djb@cr.py.to>. djbff can be found at
+ * http://cr.yp.to/djbfft.html.
+ *
+ * srfft.h is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * srfft.h is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef SRFFT_H__
+#define SRFFT_H__
+
+#include "cmplx.h"
+
+void fft_64p (complex_t *x);
+void fft_128p (complex_t *x);
+
+#endif /* SRFFT_H__ */
diff --git a/src/libac3/srfftp.h b/src/libac3/srfftp.h
new file mode 100644
index 000000000..6f4471530
--- /dev/null
+++ b/src/libac3/srfftp.h
@@ -0,0 +1,305 @@
+
+/*
+ * srfftp.h
+ *
+ * Copyright (C) Yuqing Deng <Yuqing_Deng@brown.edu> - April 2000
+ *
+ * 64 and 128 point split radix fft for ac3dec
+ *
+ * The algorithm is desribed in the book:
+ * "Computational Frameworks of the Fast Fourier Transform".
+ *
+ * The ideas and the the organization of code borrowed from djbfft written by
+ * D. J. Bernstein <djb@cr.py.to>. djbff can be found at
+ * http://cr.yp.to/djbfft.html.
+ *
+ * srfftp.h is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * srfftp.h is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef SRFFTP_H__
+#define SRFFTP_H__
+
+#include "cmplx.h"
+
+static complex_t delta16[4] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.92387953251129, -0.38268343236509},
+ {0.70710678118655, -0.70710678118655},
+ {0.38268343236509, -0.92387953251129}};
+
+static complex_t delta16_3[4] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.38268343236509, -0.92387953251129},
+ {-0.70710678118655, -0.70710678118655},
+ {-0.92387953251129, 0.38268343236509}};
+
+static complex_t delta32[8] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.98078528040323, -0.19509032201613},
+ {0.92387953251129, -0.38268343236509},
+ {0.83146961230255, -0.55557023301960},
+ {0.70710678118655, -0.70710678118655},
+ {0.55557023301960, -0.83146961230255},
+ {0.38268343236509, -0.92387953251129},
+ {0.19509032201613, -0.98078528040323}};
+
+static complex_t delta32_3[8] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.83146961230255, -0.55557023301960},
+ {0.38268343236509, -0.92387953251129},
+ {-0.19509032201613, -0.98078528040323},
+ {-0.70710678118655, -0.70710678118655},
+ {-0.98078528040323, -0.19509032201613},
+ {-0.92387953251129, 0.38268343236509},
+ {-0.55557023301960, 0.83146961230255}};
+
+static complex_t delta64[16] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.99518472667220, -0.09801714032956},
+ {0.98078528040323, -0.19509032201613},
+ {0.95694033573221, -0.29028467725446},
+ {0.92387953251129, -0.38268343236509},
+ {0.88192126434836, -0.47139673682600},
+ {0.83146961230255, -0.55557023301960},
+ {0.77301045336274, -0.63439328416365},
+ {0.70710678118655, -0.70710678118655},
+ {0.63439328416365, -0.77301045336274},
+ {0.55557023301960, -0.83146961230255},
+ {0.47139673682600, -0.88192126434835},
+ {0.38268343236509, -0.92387953251129},
+ {0.29028467725446, -0.95694033573221},
+ {0.19509032201613, -0.98078528040323},
+ {0.09801714032956, -0.99518472667220}};
+
+static complex_t delta64_3[16] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.95694033573221, -0.29028467725446},
+ {0.83146961230255, -0.55557023301960},
+ {0.63439328416365, -0.77301045336274},
+ {0.38268343236509, -0.92387953251129},
+ {0.09801714032956, -0.99518472667220},
+ {-0.19509032201613, -0.98078528040323},
+ {-0.47139673682600, -0.88192126434836},
+ {-0.70710678118655, -0.70710678118655},
+ {-0.88192126434835, -0.47139673682600},
+ {-0.98078528040323, -0.19509032201613},
+ {-0.99518472667220, 0.09801714032956},
+ {-0.92387953251129, 0.38268343236509},
+ {-0.77301045336274, 0.63439328416365},
+ {-0.55557023301960, 0.83146961230255},
+ {-0.29028467725446, 0.95694033573221}};
+
+static complex_t delta128[32] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.99879545620517, -0.04906767432742},
+ {0.99518472667220, -0.09801714032956},
+ {0.98917650996478, -0.14673047445536},
+ {0.98078528040323, -0.19509032201613},
+ {0.97003125319454, -0.24298017990326},
+ {0.95694033573221, -0.29028467725446},
+ {0.94154406518302, -0.33688985339222},
+ {0.92387953251129, -0.38268343236509},
+ {0.90398929312344, -0.42755509343028},
+ {0.88192126434836, -0.47139673682600},
+ {0.85772861000027, -0.51410274419322},
+ {0.83146961230255, -0.55557023301960},
+ {0.80320753148064, -0.59569930449243},
+ {0.77301045336274, -0.63439328416365},
+ {0.74095112535496, -0.67155895484702},
+ {0.70710678118655, -0.70710678118655},
+ {0.67155895484702, -0.74095112535496},
+ {0.63439328416365, -0.77301045336274},
+ {0.59569930449243, -0.80320753148064},
+ {0.55557023301960, -0.83146961230255},
+ {0.51410274419322, -0.85772861000027},
+ {0.47139673682600, -0.88192126434835},
+ {0.42755509343028, -0.90398929312344},
+ {0.38268343236509, -0.92387953251129},
+ {0.33688985339222, -0.94154406518302},
+ {0.29028467725446, -0.95694033573221},
+ {0.24298017990326, -0.97003125319454},
+ {0.19509032201613, -0.98078528040323},
+ {0.14673047445536, -0.98917650996478},
+ {0.09801714032956, -0.99518472667220},
+ {0.04906767432742, -0.99879545620517}};
+
+static complex_t delta128_3[32] =
+ { {1.00000000000000, 0.00000000000000},
+ {0.98917650996478, -0.14673047445536},
+ {0.95694033573221, -0.29028467725446},
+ {0.90398929312344, -0.42755509343028},
+ {0.83146961230255, -0.55557023301960},
+ {0.74095112535496, -0.67155895484702},
+ {0.63439328416365, -0.77301045336274},
+ {0.51410274419322, -0.85772861000027},
+ {0.38268343236509, -0.92387953251129},
+ {0.24298017990326, -0.97003125319454},
+ {0.09801714032956, -0.99518472667220},
+ {-0.04906767432742, -0.99879545620517},
+ {-0.19509032201613, -0.98078528040323},
+ {-0.33688985339222, -0.94154406518302},
+ {-0.47139673682600, -0.88192126434836},
+ {-0.59569930449243, -0.80320753148065},
+ {-0.70710678118655, -0.70710678118655},
+ {-0.80320753148065, -0.59569930449243},
+ {-0.88192126434835, -0.47139673682600},
+ {-0.94154406518302, -0.33688985339222},
+ {-0.98078528040323, -0.19509032201613},
+ {-0.99879545620517, -0.04906767432742},
+ {-0.99518472667220, 0.09801714032956},
+ {-0.97003125319454, 0.24298017990326},
+ {-0.92387953251129, 0.38268343236509},
+ {-0.85772861000027, 0.51410274419322},
+ {-0.77301045336274, 0.63439328416365},
+ {-0.67155895484702, 0.74095112535496},
+ {-0.55557023301960, 0.83146961230255},
+ {-0.42755509343028, 0.90398929312344},
+ {-0.29028467725446, 0.95694033573221},
+ {-0.14673047445536, 0.98917650996478}};
+
+#define HSQRT2 0.707106781188;
+
+#define TRANSZERO(A0,A4,A8,A12) { \
+ u_r = wTB[0].re; \
+ v_i = u_r - wTB[k*2].re; \
+ u_r += wTB[k*2].re; \
+ u_i = wTB[0].im; \
+ v_r = wTB[k*2].im - u_i; \
+ u_i += wTB[k*2].im; \
+ a_r = A0.re; \
+ a_i = A0.im; \
+ a1_r = a_r; \
+ a1_r += u_r; \
+ A0.re = a1_r; \
+ a_r -= u_r; \
+ A8.re = a_r; \
+ a1_i = a_i; \
+ a1_i += u_i; \
+ A0.im = a1_i; \
+ a_i -= u_i; \
+ A8.im = a_i; \
+ a1_r = A4.re; \
+ a1_i = A4.im; \
+ a_r = a1_r; \
+ a_r -= v_r; \
+ A4.re = a_r; \
+ a1_r += v_r; \
+ A12.re = a1_r; \
+ a_i = a1_i; \
+ a_i -= v_i; \
+ A4.im = a_i; \
+ a1_i += v_i; \
+ A12.im = a1_i; \
+ }
+
+#define TRANSHALF_16(A2,A6,A10,A14) {\
+ u_r = wTB[2].re; \
+ a_r = u_r; \
+ u_i = wTB[2].im; \
+ u_r += u_i; \
+ u_i -= a_r; \
+ a_r = wTB[6].re; \
+ a1_r = a_r; \
+ a_i = wTB[6].im; \
+ a_r = a_i - a_r; \
+ a_i += a1_r; \
+ v_i = u_r - a_r; \
+ u_r += a_r; \
+ v_r = u_i + a_i; \
+ u_i -= a_i; \
+ v_i *= HSQRT2; \
+ v_r *= HSQRT2; \
+ u_r *= HSQRT2; \
+ u_i *= HSQRT2; \
+ a_r = A2.re; \
+ a_i = A2.im; \
+ a1_r = a_r; \
+ a1_r += u_r; \
+ A2.re = a1_r; \
+ a_r -= u_r; \
+ A10.re = a_r; \
+ a1_i = a_i; \
+ a1_i += u_i; \
+ A2.im = a1_i; \
+ a_i -= u_i; \
+ A10.im = a_i; \
+ a1_r = A6.re; \
+ a1_i = A6.im; \
+ a_r = a1_r; \
+ a1_r += v_r; \
+ A6.re = a1_r; \
+ a_r -= v_r; \
+ A14.re = a_r; \
+ a_i = a1_i; \
+ a1_i -= v_i; \
+ A6.im = a1_i; \
+ a_i += v_i; \
+ A14.im = a_i; \
+ }
+
+#define TRANS(A1,A5,A9,A13,WT,WB,D,D3) { \
+ u_r = WT.re; \
+ a_r = u_r; \
+ a_r *= D.im; \
+ u_r *= D.re; \
+ a_i = WT.im; \
+ a1_i = a_i; \
+ a1_i *= D.re; \
+ a_i *= D.im; \
+ u_r -= a_i; \
+ u_i = a_r; \
+ u_i += a1_i; \
+ a_r = WB.re; \
+ a1_r = a_r; \
+ a1_r *= D3.re; \
+ a_r *= D3.im; \
+ a_i = WB.im; \
+ a1_i = a_i; \
+ a_i *= D3.re; \
+ a1_i *= D3.im; \
+ a1_r -= a1_i; \
+ a_r += a_i; \
+ v_i = u_r - a1_r; \
+ u_r += a1_r; \
+ v_r = a_r - u_i; \
+ u_i += a_r; \
+ a_r = A1.re; \
+ a_i = A1.im; \
+ a1_r = a_r; \
+ a1_r += u_r; \
+ A1.re = a1_r; \
+ a_r -= u_r; \
+ A9.re = a_r; \
+ a1_i = a_i; \
+ a1_i += u_i; \
+ A1.im = a1_i; \
+ a_i -= u_i; \
+ A9.im = a_i; \
+ a1_r = A5.re; \
+ a1_i = A5.im; \
+ a_r = a1_r; \
+ a1_r -= v_r; \
+ A5.re = a1_r; \
+ a_r += v_r; \
+ A13.re = a_r; \
+ a_i = a1_i; \
+ a1_i -= v_i; \
+ A5.im = a1_i; \
+ a_i += v_i; \
+ A13.im = a_i; \
+ }
+
+#endif
diff --git a/src/libmpeg2/Makefile.am b/src/libmpeg2/Makefile.am
new file mode 100644
index 000000000..a7031295c
--- /dev/null
+++ b/src/libmpeg2/Makefile.am
@@ -0,0 +1,23 @@
+CFLAGS = @BUILD_LIB_STATIC@ @LIBMPEG2_CFLAGS@ @GLOBAL_CFLAGS@
+
+EXTRA_DIST = idct_mlib.c idct_mlib.h motion_comp_mlib.c
+
+noinst_LTLIBRARIES = libmpeg2.la
+
+#libmpeg2_la_SOURCES = slice.c header.c stats.c idct.c motion_comp.c\
+# decode.c idct_mmx.c motion_comp_mmx.c
+libmpeg2_la_SOURCES = slice.c header.c stats.c idct.c motion_comp.c\
+ decode.c idct_mmx.c motion_comp_mmx.c
+
+noinst_HEADERS = vlc.h mpeg2.h mpeg2_internal.h
+
+debug:
+ $(MAKE) CFLAGS="$(DEBUG_CFLAGS) @BUILD_LIB_STATIC@"
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c
new file mode 100644
index 000000000..77e198fbf
--- /dev/null
+++ b/src/libmpeg2/decode.c
@@ -0,0 +1,323 @@
+/*
+ * decode.c
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h> /* memcpy/memset, try to remove */
+#include <stdlib.h>
+#include <inttypes.h>
+
+/* Xine specific */
+#include "buffer.h"
+#include "video_decoder.h"
+/* */
+
+
+#include "video_out.h"
+#include "mpeg2.h"
+#include "mpeg2_internal.h"
+#include "cpu_accel.h"
+#include "attributes.h"
+
+#ifdef HAVE_MEMALIGN
+/* some systems have memalign() but no declaration for it */
+void * memalign (size_t align, size_t size);
+#else
+/* assume malloc alignment is sufficient */
+#define memalign(align,size) malloc (size)
+#endif
+
+#define BUFFER_SIZE (224 * 1024)
+
+mpeg2_config_t config;
+
+void mpeg2_init (mpeg2dec_t * mpeg2dec, uint32_t mm_accel,
+ vo_instance_t * output)
+{
+ static int do_init = 1;
+
+ if (do_init) {
+ do_init = 0;
+ config.flags = mm_accel;
+ idct_init ();
+ motion_comp_init ();
+ }
+
+ mpeg2dec->chunk_buffer = memalign (16, BUFFER_SIZE + 4);
+ mpeg2dec->picture = memalign (16, sizeof (picture_t));
+
+ mpeg2dec->shift = 0xffffff00;
+ mpeg2dec->is_sequence_needed = 1;
+ mpeg2dec->drop_flag = 0;
+ mpeg2dec->drop_frame = 0;
+ mpeg2dec->in_slice = 0;
+ mpeg2dec->output = output;
+ mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;
+ mpeg2dec->code = 0xb4;
+
+ memset (mpeg2dec->picture, 0, sizeof (picture_t));
+
+ /* initialize supstructures */
+ header_state_init (mpeg2dec->picture);
+}
+
+static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
+ uint8_t * buffer, uint32_t pts)
+{
+ picture_t * picture;
+ int is_frame_done;
+
+ /* wait for sequence_header_code */
+ if (mpeg2dec->is_sequence_needed && (code != 0xb3))
+ return 0;
+
+ stats_header (code, buffer);
+
+ picture = mpeg2dec->picture;
+ is_frame_done = mpeg2dec->in_slice && ((!code) || (code >= 0xb0));
+
+ if (is_frame_done) {
+ mpeg2dec->in_slice = 0;
+
+ if (((picture->picture_structure == FRAME_PICTURE) ||
+ (picture->second_field)) &&
+ (!(mpeg2dec->drop_frame))) {
+ vo_draw ((picture->picture_coding_type == B_TYPE) ?
+ picture->current_frame :
+ picture->forward_reference_frame);
+#ifdef ARCH_X86
+ if (config.flags & MM_ACCEL_X86_MMX)
+ emms ();
+#endif
+ }
+ }
+
+ switch (code) {
+ case 0x00: /* picture_start_code */
+ if (header_process_picture_header (picture, buffer)) {
+ fprintf (stderr, "bad picture header\n");
+ exit (1);
+ }
+
+ if (mpeg2dec->pts) {
+ picture->current_frame->PTS = mpeg2dec->pts;
+ mpeg2dec->pts = 0;
+ }
+
+ mpeg2dec->drop_frame =
+ mpeg2dec->drop_flag && (picture->picture_coding_type == B_TYPE);
+ break;
+
+ case 0xb3: /* sequence_header_code */
+ if (header_process_sequence_header (picture, buffer)) {
+ fprintf (stderr, "bad sequence header\n");
+ exit (1);
+ }
+ if (mpeg2dec->is_sequence_needed) {
+ mpeg2dec->is_sequence_needed = 0;
+ if (vo_setup (mpeg2dec->output, picture->coded_picture_width,
+ picture->coded_picture_height)) {
+ fprintf (stderr, "display setup failed\n");
+ exit (1);
+ }
+ picture->forward_reference_frame =
+ vo_get_frame (mpeg2dec->output,
+ VO_PREDICTION_FLAG | VO_BOTH_FIELDS);
+ picture->backward_reference_frame =
+ vo_get_frame (mpeg2dec->output,
+ VO_PREDICTION_FLAG | VO_BOTH_FIELDS);
+ }
+ mpeg2dec->frame_rate_code = picture->frame_rate_code; /* FIXME */
+ break;
+
+ case 0xb5: /* extension_start_code */
+ if (header_process_extension (picture, buffer)) {
+ fprintf (stderr, "bad extension\n");
+ exit (1);
+ }
+ break;
+
+ default:
+ if (code >= 0xb9)
+ fprintf (stderr, "stream not demultiplexed ?\n");
+
+ if (code >= 0xb0)
+ break;
+
+ if (!(mpeg2dec->in_slice)) {
+ mpeg2dec->in_slice = 1;
+
+ if (picture->second_field)
+ vo_field (picture->current_frame, picture->picture_structure);
+ /*
+ else {
+ if (picture->picture_coding_type == B_TYPE)
+ picture->current_frame =
+ vo_get_frame (mpeg2dec->output,
+ picture->picture_structure);
+ else {
+ picture->current_frame =
+ vo_get_frame (mpeg2dec->output,
+ (VO_PREDICTION_FLAG |
+ picture->picture_structure));
+ picture->forward_reference_frame =
+ picture->backward_reference_frame;
+ picture->backward_reference_frame = picture->current_frame;
+ }
+ }*/
+ }
+
+ if (!(mpeg2dec->drop_frame)) {
+ slice_process (picture, code, buffer);
+
+#ifdef ARCH_X86
+ if (config.flags & MM_ACCEL_X86_MMX)
+ emms ();
+#endif
+ }
+ }
+
+ return is_frame_done;
+}
+
+static inline uint8_t * copy_chunk (mpeg2dec_t * mpeg2dec,
+ uint8_t * current, uint8_t * end)
+{
+ uint32_t shift;
+ uint8_t * chunk_ptr;
+ uint8_t * limit;
+ uint8_t byte;
+
+ shift = mpeg2dec->shift;
+ chunk_ptr = mpeg2dec->chunk_ptr;
+ limit = current + (mpeg2dec->chunk_buffer + BUFFER_SIZE - chunk_ptr);
+ if (limit > end)
+ limit = end;
+
+ while (1) {
+ byte = *current++;
+ if (shift != 0x00000100) {
+ shift = (shift | byte) << 8;
+ *chunk_ptr++ = byte;
+ if (current < limit)
+ continue;
+ if (current == end) {
+ mpeg2dec->chunk_ptr = chunk_ptr;
+ mpeg2dec->shift = shift;
+ return NULL;
+ } else {
+ /* we filled the chunk buffer without finding a start code */
+ mpeg2dec->code = 0xb4; /* sequence_error_code */
+ mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;
+ return current;
+ }
+ }
+ mpeg2dec->code = byte;
+ mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer;
+ mpeg2dec->shift = 0xffffff00;
+ return current;
+ }
+}
+
+int mpeg2_decode_data (mpeg2dec_t * mpeg2dec, uint8_t * current,
+ uint8_t * end, uint32_t pts)
+{
+ int ret;
+ uint8_t code;
+
+ ret = 0;
+
+ mpeg2dec->pts = pts;
+ while (current != end) {
+ code = mpeg2dec->code;
+ current = copy_chunk (mpeg2dec, current, end);
+ if (current == NULL)
+ return ret;
+ ret += parse_chunk (mpeg2dec, code, mpeg2dec->chunk_buffer, pts);
+ }
+ return ret;
+}
+
+void mpeg2_close (mpeg2dec_t * mpeg2dec)
+{
+ static uint8_t finalizer[] = {0,0,1,0};
+
+ mpeg2_decode_data (mpeg2dec, finalizer, finalizer+4, mpeg2dec->pts);
+
+ if (! (mpeg2dec->is_sequence_needed))
+ vo_draw (mpeg2dec->picture->backward_reference_frame);
+
+ free (mpeg2dec->chunk_buffer);
+ free (mpeg2dec->picture);
+}
+
+void mpeg2_drop (mpeg2dec_t * mpeg2dec, int flag)
+{
+ mpeg2dec->drop_flag = flag;
+}
+
+/*
+ * xine specific stuff
+ */
+
+int mpeg2dec_get_version () {
+ return 1;
+}
+
+int mpeg2dec_can_handle (int buf_type) {
+ return (buf_type == BUF_VIDEO_MPEG) ;
+}
+
+
+static mpeg2dec_t gMpeg2;
+
+void mpeg2dec_init (vo_instance_t *video_out) {
+ uint32_t mmacc = mm_accel();
+
+ mpeg2_init (&gMpeg2, mmacc, video_out);
+}
+
+void mpeg2dec_decode_data (buf_element_t *buf) {
+ mpeg2_decode_data (&gMpeg2, buf->content, buf->content + buf->size,
+ buf->PTS);
+}
+
+void mpeg2dec_release_img_buffers () {
+ // decode_free_image_buffers (&gMpeg2);
+}
+
+void mpeg2dec_close () {
+ mpeg2_close (&gMpeg2);
+}
+
+static video_decoder_t vd_mpeg2dec = {
+ mpeg2dec_get_version,
+ mpeg2dec_can_handle,
+ mpeg2dec_init,
+ mpeg2dec_decode_data,
+ mpeg2dec_release_img_buffers,
+ mpeg2dec_close
+};
+
+video_decoder_t *init_video_decoder_mpeg2dec () {
+ return &vd_mpeg2dec;
+}
diff --git a/src/libmpeg2/header.c b/src/libmpeg2/header.c
new file mode 100644
index 000000000..e021b2f8e
--- /dev/null
+++ b/src/libmpeg2/header.c
@@ -0,0 +1,235 @@
+/*
+ * slice.c
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+#include "attributes.h"
+
+/* default intra quant matrix, in zig-zag order */
+static uint8_t default_intra_quantizer_matrix[64] ATTR_ALIGN(16) = {
+ 8,
+ 16, 16,
+ 19, 16, 19,
+ 22, 22, 22, 22,
+ 22, 22, 26, 24, 26,
+ 27, 27, 27, 26, 26, 26,
+ 26, 27, 27, 27, 29, 29, 29,
+ 34, 34, 34, 29, 29, 29, 27, 27,
+ 29, 29, 32, 32, 34, 34, 37,
+ 38, 37, 35, 35, 34, 35,
+ 38, 38, 40, 40, 40,
+ 48, 48, 46, 46,
+ 56, 56, 58,
+ 69, 69,
+ 83
+};
+
+uint8_t scan_norm[64] ATTR_ALIGN(16) =
+{
+ /* Zig-Zag scan pattern */
+ 0, 1, 8,16, 9, 2, 3,10,
+ 17,24,32,25,18,11, 4, 5,
+ 12,19,26,33,40,48,41,34,
+ 27,20,13, 6, 7,14,21,28,
+ 35,42,49,56,57,50,43,36,
+ 29,22,15,23,30,37,44,51,
+ 58,59,52,45,38,31,39,46,
+ 53,60,61,54,47,55,62,63
+};
+
+uint8_t scan_alt[64] ATTR_ALIGN(16) =
+{
+ /* Alternate scan pattern */
+ 0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49,
+ 41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43,
+ 51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45,
+ 53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63
+};
+
+void header_state_init (picture_t * picture)
+{
+ picture->scan = scan_norm;
+}
+
+int header_process_sequence_header (picture_t * picture, uint8_t * buffer)
+{
+ int width, height;
+ int i;
+
+ if ((buffer[6] & 0x20) != 0x20)
+ return 1; /* missing marker_bit */
+
+ height = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
+
+ width = ((height >> 12) + 15) & ~15;
+ height = ((height & 0xfff) + 15) & ~15;
+
+ if ((width > 768) || (height > 576))
+ return 1; /* size restrictions for MP@ML or MPEG1 */
+
+ picture->coded_picture_width = width;
+ picture->coded_picture_height = height;
+
+ /* this is not used by the decoder */
+ picture->aspect_ratio_information = buffer[3] >> 4;
+ picture->frame_rate_code = buffer[3] & 15;
+ picture->bitrate = (buffer[4]<<10)|(buffer[5]<<2)|(buffer[6]>>6);
+
+ if (buffer[7] & 2) {
+ for (i = 0; i < 64; i++)
+ picture->intra_quantizer_matrix[scan_norm[i]] =
+ (buffer[i+7] << 7) | (buffer[i+8] >> 1);
+ buffer += 64;
+ } else {
+ for (i = 0; i < 64; i++)
+ picture->intra_quantizer_matrix[scan_norm[i]] =
+ default_intra_quantizer_matrix [i];
+ }
+
+ if (buffer[7] & 1) {
+ for (i = 0; i < 64; i++)
+ picture->non_intra_quantizer_matrix[scan_norm[i]] =
+ buffer[i+8];
+ } else {
+ for (i = 0; i < 64; i++)
+ picture->non_intra_quantizer_matrix[i] = 16;
+ }
+
+ /* MPEG1 - for testing only */
+ picture->mpeg1 = 1;
+ picture->intra_dc_precision = 0;
+ picture->frame_pred_frame_dct = 1;
+ picture->q_scale_type = 0;
+ picture->concealment_motion_vectors = 0;
+ /* picture->alternate_scan = 0; */
+ picture->picture_structure = FRAME_PICTURE;
+ /* picture->second_field = 0; */
+
+ return 0;
+}
+
+static int header_process_sequence_extension (picture_t * picture,
+ uint8_t * buffer)
+{
+ /* check chroma format, size extensions, marker bit */
+ if (((buffer[1] & 0x07) != 0x02) || (buffer[2] & 0xe0) ||
+ ((buffer[3] & 0x01) != 0x01))
+ return 1;
+
+ /* this is not used by the decoder */
+ picture->progressive_sequence = (buffer[1] >> 3) & 1;
+
+ if (picture->progressive_sequence)
+ picture->coded_picture_height =
+ (picture->coded_picture_height + 31) & ~31;
+
+ /* MPEG1 - for testing only */
+ picture->mpeg1 = 0;
+
+ return 0;
+}
+
+static int header_process_quant_matrix_extension (picture_t * picture,
+ uint8_t * buffer)
+{
+ int i;
+
+ if (buffer[0] & 8) {
+ for (i = 0; i < 64; i++)
+ picture->intra_quantizer_matrix[scan_norm[i]] =
+ (buffer[i] << 5) | (buffer[i+1] >> 3);
+ buffer += 64;
+ }
+
+ if (buffer[0] & 4) {
+ for (i = 0; i < 64; i++)
+ picture->non_intra_quantizer_matrix[scan_norm[i]] =
+ (buffer[i] << 6) | (buffer[i+1] >> 2);
+ }
+
+ return 0;
+}
+
+static int header_process_picture_coding_extension (picture_t * picture, uint8_t * buffer)
+{
+ /* pre subtract 1 for use later in compute_motion_vector */
+ picture->f_motion.f_code[0] = (buffer[0] & 15) - 1;
+ picture->f_motion.f_code[1] = (buffer[1] >> 4) - 1;
+ picture->b_motion.f_code[0] = (buffer[1] & 15) - 1;
+ picture->b_motion.f_code[1] = (buffer[2] >> 4) - 1;
+
+ picture->intra_dc_precision = (buffer[2] >> 2) & 3;
+ picture->picture_structure = buffer[2] & 3;
+ picture->frame_pred_frame_dct = (buffer[3] >> 6) & 1;
+ picture->concealment_motion_vectors = (buffer[3] >> 5) & 1;
+ picture->q_scale_type = (buffer[3] >> 4) & 1;
+ picture->intra_vlc_format = (buffer[3] >> 3) & 1;
+
+ if (buffer[3] & 4) /* alternate_scan */
+ picture->scan = scan_alt;
+ else
+ picture->scan = scan_norm;
+
+ /* these are not used by the decoder */
+ picture->top_field_first = buffer[3] >> 7;
+ picture->repeat_first_field = (buffer[3] >> 1) & 1;
+ picture->progressive_frame = buffer[4] >> 7;
+
+ return 0;
+}
+
+int header_process_extension (picture_t * picture, uint8_t * buffer)
+{
+ switch (buffer[0] & 0xf0) {
+ case 0x10: /* sequence extension */
+ return header_process_sequence_extension (picture, buffer);
+
+ case 0x30: /* quant matrix extension */
+ return header_process_quant_matrix_extension (picture, buffer);
+
+ case 0x80: /* picture coding extension */
+ return header_process_picture_coding_extension (picture, buffer);
+ }
+
+ return 0;
+}
+
+int header_process_picture_header (picture_t *picture, uint8_t * buffer)
+{
+ picture->picture_coding_type = (buffer [1] >> 3) & 7;
+
+ /* forward_f_code and backward_f_code - used in mpeg1 only */
+ picture->f_motion.f_code[1] = (buffer[3] >> 2) & 1;
+ picture->f_motion.f_code[0] =
+ (((buffer[3] << 1) | (buffer[4] >> 7)) & 7) - 1;
+ picture->b_motion.f_code[1] = (buffer[4] >> 6) & 1;
+ picture->b_motion.f_code[0] = ((buffer[4] >> 3) & 7) - 1;
+
+ /* move in header_process_picture_header */
+ picture->second_field =
+ (picture->picture_structure != FRAME_PICTURE) &&
+ !(picture->second_field);
+
+ return 0;
+}
diff --git a/src/libmpeg2/idct.c b/src/libmpeg2/idct.c
new file mode 100644
index 000000000..21d33dc8c
--- /dev/null
+++ b/src/libmpeg2/idct.c
@@ -0,0 +1,290 @@
+/*
+ * idct.c
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * Portions of this code are from the MPEG software simulation group
+ * idct implementation. This code will be replaced with a new
+ * implementation soon.
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**********************************************************/
+/* inverse two dimensional DCT, Chen-Wang algorithm */
+/* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */
+/* 32-bit integer arithmetic (8 bit coefficients) */
+/* 11 mults, 29 adds per DCT */
+/* sE, 18.8.91 */
+/**********************************************************/
+/* coefficients extended to 12 bit for IEEE1180-1990 */
+/* compliance sE, 2.1.94 */
+/**********************************************************/
+
+/* this code assumes >> to be a two's-complement arithmetic */
+/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+#include "xine_internal.h"
+#include "xine.h"
+#include "cpu_accel.h"
+
+#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
+#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
+#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
+#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
+#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
+#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */
+
+/* idct main entry point */
+void (*idct_block_copy) (int16_t * block, uint8_t * dest, int stride);
+void (*idct_block_add) (int16_t * block, uint8_t * dest, int stride);
+
+static void idct_block_copy_c (int16_t *block, uint8_t * dest, int stride);
+static void idct_block_add_c (int16_t *block, uint8_t * dest, int stride);
+
+static uint8_t clip_lut[1024];
+#define CLIP(i) ((clip_lut+384)[ (i)])
+
+void idct_init (void)
+{
+#ifdef ARCH_X86
+ if (config.flags & MM_ACCEL_X86_MMXEXT) {
+ fprintf (stderr, "Using MMXEXT for IDCT transform\n");
+ idct_block_copy = idct_block_copy_mmxext;
+ idct_block_add = idct_block_add_mmxext;
+ idct_mmx_init ();
+ } else if (config.flags & MM_ACCEL_X86_MMX) {
+ fprintf (stderr, "Using MMX for IDCT transform\n");
+ idct_block_copy = idct_block_copy_mmx;
+ idct_block_add = idct_block_add_mmx;
+ idct_mmx_init ();
+ } else
+#endif
+#ifdef LIBMPEG2_MLIB
+ if (config.flags & MM_ACCEL_MLIB) {
+ fprintf (stderr, "Using mlib for IDCT transform\n");
+ idct_block_copy = idct_block_copy_mlib;
+ idct_block_add = idct_block_add_mlib;
+ } else
+#endif
+ {
+ int i;
+
+ fprintf (stderr, "No accelerated IDCT transform found\n");
+ idct_block_copy = idct_block_copy_c;
+ idct_block_add = idct_block_add_c;
+ for (i = -384; i < 640; i++)
+ clip_lut[i+384] = (i < 0) ? 0 : ((i > 255) ? 255 : i);
+ }
+}
+
+/* row (horizontal) IDCT
+ *
+ * 7 pi 1
+ * dst[k] = sum c[l] * src[l] * cos ( -- * ( k + - ) * l )
+ * l=0 8 2
+ *
+ * where: c[0] = 128
+ * c[1..7] = 128*sqrt (2)
+ */
+
+static void inline idct_row (int16_t * block)
+{
+ int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+ x1 = block[4] << 11;
+ x2 = block[6];
+ x3 = block[2];
+ x4 = block[1];
+ x5 = block[7];
+ x6 = block[5];
+ x7 = block[3];
+
+ /* shortcut */
+ if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) {
+ block[0] = block[1] = block[2] = block[3] = block[4] =
+ block[5] = block[6] = block[7] = block[0]<<3;
+ return;
+ }
+
+ x0 = (block[0] << 11) + 128; /* for proper rounding in the fourth stage */
+
+ /* first stage */
+ x8 = W7 * (x4 + x5);
+ x4 = x8 + (W1 - W7) * x4;
+ x5 = x8 - (W1 + W7) * x5;
+ x8 = W3 * (x6 + x7);
+ x6 = x8 - (W3 - W5) * x6;
+ x7 = x8 - (W3 + W5) * x7;
+
+ /* second stage */
+ x8 = x0 + x1;
+ x0 -= x1;
+ x1 = W6 * (x3 + x2);
+ x2 = x1 - (W2 + W6) * x2;
+ x3 = x1 + (W2 - W6) * x3;
+ x1 = x4 + x6;
+ x4 -= x6;
+ x6 = x5 + x7;
+ x5 -= x7;
+
+ /* third stage */
+ x7 = x8 + x3;
+ x8 -= x3;
+ x3 = x0 + x2;
+ x0 -= x2;
+ x2 = (181 * (x4 + x5) + 128) >> 8;
+ x4 = (181 * (x4 - x5) + 128) >> 8;
+
+ /* fourth stage */
+ block[0] = (x7 + x1) >> 8;
+ block[1] = (x3 + x2) >> 8;
+ block[2] = (x0 + x4) >> 8;
+ block[3] = (x8 + x6) >> 8;
+ block[4] = (x8 - x6) >> 8;
+ block[5] = (x0 - x4) >> 8;
+ block[6] = (x3 - x2) >> 8;
+ block[7] = (x7 - x1) >> 8;
+}
+
+/* column (vertical) IDCT
+ *
+ * 7 pi 1
+ * dst[8*k] = sum c[l] * src[8*l] * cos ( -- * ( k + - ) * l )
+ * l=0 8 2
+ *
+ * where: c[0] = 1/1024
+ * c[1..7] = (1/1024)*sqrt (2)
+ */
+
+static void inline idct_col (int16_t *block)
+{
+ int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+ /* shortcut */
+ x1 = block [8*4] << 8;
+ x2 = block [8*6];
+ x3 = block [8*2];
+ x4 = block [8*1];
+ x5 = block [8*7];
+ x6 = block [8*5];
+ x7 = block [8*3];
+
+#if 0
+ if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) {
+ block[8*0] = block[8*1] = block[8*2] = block[8*3] = block[8*4] =
+ block[8*5] = block[8*6] = block[8*7] = (block[8*0] + 32) >> 6;
+ return;
+ }
+#endif
+
+ x0 = (block[8*0] << 8) + 8192;
+
+ /* first stage */
+ x8 = W7 * (x4 + x5) + 4;
+ x4 = (x8 + (W1 - W7) * x4) >> 3;
+ x5 = (x8 - (W1 + W7) * x5) >> 3;
+ x8 = W3 * (x6 + x7) + 4;
+ x6 = (x8 - (W3 - W5) * x6) >> 3;
+ x7 = (x8 - (W3 + W5) * x7) >> 3;
+
+ /* second stage */
+ x8 = x0 + x1;
+ x0 -= x1;
+ x1 = W6 * (x3 + x2) + 4;
+ x2 = (x1 - (W2 + W6) * x2) >> 3;
+ x3 = (x1 + (W2 - W6) * x3) >> 3;
+ x1 = x4 + x6;
+ x4 -= x6;
+ x6 = x5 + x7;
+ x5 -= x7;
+
+ /* third stage */
+ x7 = x8 + x3;
+ x8 -= x3;
+ x3 = x0 + x2;
+ x0 -= x2;
+ x2 = (181 * (x4 + x5) + 128) >> 8;
+ x4 = (181 * (x4 - x5) + 128) >> 8;
+
+ /* fourth stage */
+ block[8*0] = (x7 + x1) >> 14;
+ block[8*1] = (x3 + x2) >> 14;
+ block[8*2] = (x0 + x4) >> 14;
+ block[8*3] = (x8 + x6) >> 14;
+ block[8*4] = (x8 - x6) >> 14;
+ block[8*5] = (x0 - x4) >> 14;
+ block[8*6] = (x3 - x2) >> 14;
+ block[8*7] = (x7 - x1) >> 14;
+}
+
+void idct_block_copy_c (int16_t * block, uint8_t * dest, int stride)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ idct_row (block + 8 * i);
+
+ for (i = 0; i < 8; i++)
+ idct_col (block + i);
+
+ i = 8;
+ do {
+ dest[0] = CLIP (block[0]);
+ dest[1] = CLIP (block[1]);
+ dest[2] = CLIP (block[2]);
+ dest[3] = CLIP (block[3]);
+ dest[4] = CLIP (block[4]);
+ dest[5] = CLIP (block[5]);
+ dest[6] = CLIP (block[6]);
+ dest[7] = CLIP (block[7]);
+
+ dest += stride;
+ block += 8;
+ } while (--i);
+}
+
+void idct_block_add_c (int16_t * block, uint8_t * dest, int stride)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ idct_row (block + 8 * i);
+
+ for (i = 0; i < 8; i++)
+ idct_col (block + i);
+
+ i = 8;
+ do {
+ dest[0] = CLIP (block[0] + dest[0]);
+ dest[1] = CLIP (block[1] + dest[1]);
+ dest[2] = CLIP (block[2] + dest[2]);
+ dest[3] = CLIP (block[3] + dest[3]);
+ dest[4] = CLIP (block[4] + dest[4]);
+ dest[5] = CLIP (block[5] + dest[5]);
+ dest[6] = CLIP (block[6] + dest[6]);
+ dest[7] = CLIP (block[7] + dest[7]);
+
+ dest += stride;
+ block += 8;
+ } while (--i);
+}
diff --git a/src/libmpeg2/idct_mlib.c b/src/libmpeg2/idct_mlib.c
new file mode 100644
index 000000000..876ab574a
--- /dev/null
+++ b/src/libmpeg2/idct_mlib.c
@@ -0,0 +1,47 @@
+/*
+ * idct_mlib.c
+ * Copyright (C) 1999-2001 Håkan Hjort <d95hjort@dtek.chalmers.se>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#ifdef LIBMPEG2_MLIB
+
+#include <inttypes.h>
+#include <mlib_types.h>
+#include <mlib_status.h>
+#include <mlib_sys.h>
+#include <mlib_video.h>
+
+#include "mpeg2_internal.h"
+
+void idct_block_copy_mlib (int16_t * block, uint8_t * dest, int stride)
+{
+ mlib_VideoIDCT8x8_U8_S16 (dest, block, stride);
+}
+
+void idct_block_add_mlib (int16_t * block, uint8_t * dest, int stride)
+{
+ /* Should we use mlib_VideoIDCT_IEEE_S16_S16 here ?? */
+ /* it's ~30% slower. */
+ mlib_VideoIDCT8x8_S16_S16 (block, block);
+ mlib_VideoAddBlock_U8_S16 (dest, block, stride);
+}
+
+#endif
diff --git a/src/libmpeg2/idct_mlib.h b/src/libmpeg2/idct_mlib.h
new file mode 100644
index 000000000..4a5b92919
--- /dev/null
+++ b/src/libmpeg2/idct_mlib.h
@@ -0,0 +1,25 @@
+/*
+ * idct_mlib.h
+ *
+ * Copyright (C) 1999, Håkan Hjort <d95hjort@dtek.chalmers.se>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation,
+ *
+ */
+
+void idct_block_copy_mlib (int16_t * block, uint8_t * dest, int stride);
+void idct_block_add_mlib (int16_t * block, uint8_t * dest, int stride);
diff --git a/src/libmpeg2/idct_mmx.c b/src/libmpeg2/idct_mmx.c
new file mode 100644
index 000000000..927a78996
--- /dev/null
+++ b/src/libmpeg2/idct_mmx.c
@@ -0,0 +1,705 @@
+/*
+ * idct_mmx.c
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#ifdef ARCH_X86
+
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+#include "attributes.h"
+#include "cpu_accel.h"
+
+#define ROW_SHIFT 11
+#define COL_SHIFT 6
+
+#define round(bias) ((int)(((bias)+0.5) * (1<<ROW_SHIFT)))
+#define rounder(bias) {round (bias), round (bias)}
+
+
+#if 0
+/* C row IDCT - its just here to document the MMXEXT and MMX versions */
+static inline void idct_row (int16_t * row, int offset,
+ int16_t * table, int32_t * rounder)
+{
+ int C1, C2, C3, C4, C5, C6, C7;
+ int a0, a1, a2, a3, b0, b1, b2, b3;
+
+ row += offset;
+
+ C1 = table[1];
+ C2 = table[2];
+ C3 = table[3];
+ C4 = table[4];
+ C5 = table[5];
+ C6 = table[6];
+ C7 = table[7];
+
+ a0 = C4*row[0] + C2*row[2] + C4*row[4] + C6*row[6] + *rounder;
+ a1 = C4*row[0] + C6*row[2] - C4*row[4] - C2*row[6] + *rounder;
+ a2 = C4*row[0] - C6*row[2] - C4*row[4] + C2*row[6] + *rounder;
+ a3 = C4*row[0] - C2*row[2] + C4*row[4] - C6*row[6] + *rounder;
+
+ b0 = C1*row[1] + C3*row[3] + C5*row[5] + C7*row[7];
+ b1 = C3*row[1] - C7*row[3] - C1*row[5] - C5*row[7];
+ b2 = C5*row[1] - C1*row[3] + C7*row[5] + C3*row[7];
+ b3 = C7*row[1] - C5*row[3] + C3*row[5] - C1*row[7];
+
+ row[0] = (a0 + b0) >> ROW_SHIFT;
+ row[1] = (a1 + b1) >> ROW_SHIFT;
+ row[2] = (a2 + b2) >> ROW_SHIFT;
+ row[3] = (a3 + b3) >> ROW_SHIFT;
+ row[4] = (a3 - b3) >> ROW_SHIFT;
+ row[5] = (a2 - b2) >> ROW_SHIFT;
+ row[6] = (a1 - b1) >> ROW_SHIFT;
+ row[7] = (a0 - b0) >> ROW_SHIFT;
+}
+#endif
+
+
+/* MMXEXT row IDCT */
+
+#define mmxext_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, -c4, -c2, \
+ c4, c6, c4, c6, \
+ c1, c3, -c1, -c5, \
+ c5, c7, c3, -c7, \
+ c4, -c6, c4, -c6, \
+ -c4, c2, c4, -c2, \
+ c5, -c1, c3, -c1, \
+ c7, c3, c7, -c5 }
+
+static inline void mmxext_row_head (int16_t * row, int offset, int16_t * table)
+{
+ movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0
+
+ movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1
+ movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0
+
+ movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4
+ movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1
+
+ movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4
+ pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2
+
+ pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4
+}
+
+static inline void mmxext_row (int16_t * table, int32_t * rounder)
+{
+ movq_m2r (*(table+8), mm1); // mm1 = -C5 -C1 C3 C1
+ pmaddwd_r2r (mm2, mm4); // mm4 = C4*x0+C6*x2 C4*x4+C6*x6
+
+ pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x4-C6*x6 C4*x0-C6*x2
+ pshufw_r2r (mm6, mm6, 0x4e); // mm6 = x3 x1 x7 x5
+
+ movq_m2r (*(table+12), mm7); // mm7 = -C7 C3 C7 C5
+ pmaddwd_r2r (mm5, mm1); // mm1 = -C1*x5-C5*x7 C1*x1+C3*x3
+
+ paddd_m2r (*rounder, mm3); // mm3 += rounder
+ pmaddwd_r2r (mm6, mm7); // mm7 = C3*x1-C7*x3 C5*x5+C7*x7
+
+ pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x0-C2*x2 -C4*x4+C2*x6
+ paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder
+
+ pmaddwd_m2r (*(table+24), mm5); // mm5 = C3*x5-C1*x7 C5*x1-C1*x3
+ movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder
+
+ pmaddwd_m2r (*(table+28), mm6); // mm6 = C7*x1-C5*x3 C7*x5+C3*x7
+ paddd_r2r (mm7, mm1); // mm1 = b1 b0
+
+ paddd_m2r (*rounder, mm0); // mm0 += rounder
+ psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder
+
+ psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7
+ paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder
+
+ paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder
+ psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0
+
+ paddd_r2r (mm6, mm5); // mm5 = b3 b2
+ movq_r2r (mm0, mm4); // mm4 = a3 a2 + rounder
+
+ paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder
+ psubd_r2r (mm5, mm4); // mm4 = a3-b3 a2-b2 + rounder
+}
+
+static inline void mmxext_row_tail (int16_t * row, int store)
+{
+ psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2
+
+ psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5
+
+ packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0
+
+ packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5
+
+ movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0
+ pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4
+
+ /* slot */
+
+ movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4
+}
+
+static inline void mmxext_row_mid (int16_t * row, int store,
+ int offset, int16_t * table)
+{
+ movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0
+ psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2
+
+ movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1
+ psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5
+
+ packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0
+ movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1
+
+ packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5
+ movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0
+
+ movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0
+ pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4
+
+ movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4
+ movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4
+
+ pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2
+
+ movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4
+ pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4
+}
+
+
+/* MMX row IDCT */
+
+#define mmx_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, c4, c6, \
+ c4, c6, -c4, -c2, \
+ c1, c3, c3, -c7, \
+ c5, c7, -c1, -c5, \
+ c4, -c6, c4, -c2, \
+ -c4, c2, c4, -c6, \
+ c5, -c1, c7, -c5, \
+ c7, c3, c3, -c1 }
+
+static inline void mmx_row_head (int16_t * row, int offset, int16_t * table)
+{
+ movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0
+
+ movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1
+ movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0
+
+ movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4
+ movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1
+
+ punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0
+
+ movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4
+ pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2
+
+ movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1
+ punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4
+}
+
+static inline void mmx_row (int16_t * table, int32_t * rounder)
+{
+ pmaddwd_r2r (mm2, mm4); // mm4 = -C4*x4-C2*x6 C4*x4+C6*x6
+ punpckldq_r2r (mm5, mm5); // mm5 = x3 x1 x3 x1
+
+ pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x0-C2*x2 C4*x0-C6*x2
+ punpckhdq_r2r (mm6, mm6); // mm6 = x7 x5 x7 x5
+
+ movq_m2r (*(table+12), mm7); // mm7 = -C5 -C1 C7 C5
+ pmaddwd_r2r (mm5, mm1); // mm1 = C3*x1-C7*x3 C1*x1+C3*x3
+
+ paddd_m2r (*rounder, mm3); // mm3 += rounder
+ pmaddwd_r2r (mm6, mm7); // mm7 = -C1*x5-C5*x7 C5*x5+C7*x7
+
+ pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x4-C6*x6 -C4*x4+C2*x6
+ paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder
+
+ pmaddwd_m2r (*(table+24), mm5); // mm5 = C7*x1-C5*x3 C5*x1-C1*x3
+ movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder
+
+ pmaddwd_m2r (*(table+28), mm6); // mm6 = C3*x5-C1*x7 C7*x5+C3*x7
+ paddd_r2r (mm7, mm1); // mm1 = b1 b0
+
+ paddd_m2r (*rounder, mm0); // mm0 += rounder
+ psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder
+
+ psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7
+ paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder
+
+ paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder
+ psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0
+
+ paddd_r2r (mm6, mm5); // mm5 = b3 b2
+ movq_r2r (mm0, mm7); // mm7 = a3 a2 + rounder
+
+ paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder
+ psubd_r2r (mm5, mm7); // mm7 = a3-b3 a2-b2 + rounder
+}
+
+static inline void mmx_row_tail (int16_t * row, int store)
+{
+ psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2
+
+ psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5
+
+ packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0
+
+ packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5
+
+ movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0
+ movq_r2r (mm7, mm4); // mm4 = y6 y7 y4 y5
+
+ pslld_i2r (16, mm7); // mm7 = y7 0 y5 0
+
+ psrld_i2r (16, mm4); // mm4 = 0 y6 0 y4
+
+ por_r2r (mm4, mm7); // mm7 = y7 y6 y5 y4
+
+ /* slot */
+
+ movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4
+}
+
+static inline void mmx_row_mid (int16_t * row, int store,
+ int offset, int16_t * table)
+{
+ movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0
+ psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2
+
+ movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1
+ psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5
+
+ packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0
+ movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1
+
+ packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5
+ movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0
+
+ movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0
+ movq_r2r (mm7, mm1); // mm1 = y6 y7 y4 y5
+
+ punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0
+ psrld_i2r (16, mm7); // mm7 = 0 y6 0 y4
+
+ movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4
+ pslld_i2r (16, mm1); // mm1 = y7 0 y5 0
+
+ movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4
+ por_r2r (mm1, mm7); // mm7 = y7 y6 y5 y4
+
+ movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1
+ punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4
+
+ movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4
+ pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2
+}
+
+
+#if 0
+// C column IDCT - its just here to document the MMXEXT and MMX versions
+static inline void idct_col (int16_t * col, int offset)
+{
+/* multiplication - as implemented on mmx */
+#define F(c,x) (((c) * (x)) >> 16)
+
+/* saturation - it helps us handle torture test cases */
+#define S(x) (((x)>32767) ? 32767 : ((x)<-32768) ? -32768 : (x))
+
+ int16_t x0, x1, x2, x3, x4, x5, x6, x7;
+ int16_t y0, y1, y2, y3, y4, y5, y6, y7;
+ int16_t a0, a1, a2, a3, b0, b1, b2, b3;
+ int16_t u04, v04, u26, v26, u17, v17, u35, v35, u12, v12;
+
+ col += offset;
+
+ x0 = col[0*8];
+ x1 = col[1*8];
+ x2 = col[2*8];
+ x3 = col[3*8];
+ x4 = col[4*8];
+ x5 = col[5*8];
+ x6 = col[6*8];
+ x7 = col[7*8];
+
+ u04 = S (x0 + x4);
+ v04 = S (x0 - x4);
+ u26 = S (F (T2, x6) + x2);
+ v26 = S (F (T2, x2) - x6);
+
+ a0 = S (u04 + u26);
+ a1 = S (v04 + v26);
+ a2 = S (v04 - v26);
+ a3 = S (u04 - u26);
+
+ u17 = S (F (T1, x7) + x1);
+ v17 = S (F (T1, x1) - x7);
+ u35 = S (F (T3, x5) + x3);
+ v35 = S (F (T3, x3) - x5);
+
+ b0 = S (u17 + u35);
+ b3 = S (v17 - v35);
+ u12 = S (u17 - u35);
+ v12 = S (v17 + v35);
+ u12 = S (2 * F (C4, u12));
+ v12 = S (2 * F (C4, v12));
+ b1 = S (u12 + v12);
+ b2 = S (u12 - v12);
+
+ y0 = S (a0 + b0) >> COL_SHIFT;
+ y1 = S (a1 + b1) >> COL_SHIFT;
+ y2 = S (a2 + b2) >> COL_SHIFT;
+ y3 = S (a3 + b3) >> COL_SHIFT;
+
+ y4 = S (a3 - b3) >> COL_SHIFT;
+ y5 = S (a2 - b2) >> COL_SHIFT;
+ y6 = S (a1 - b1) >> COL_SHIFT;
+ y7 = S (a0 - b0) >> COL_SHIFT;
+
+ col[0*8] = y0;
+ col[1*8] = y1;
+ col[2*8] = y2;
+ col[3*8] = y3;
+ col[4*8] = y4;
+ col[5*8] = y5;
+ col[6*8] = y6;
+ col[7*8] = y7;
+}
+#endif
+
+
+// MMX column IDCT
+static inline void idct_col (int16_t * col, int offset)
+{
+#define T1 13036
+#define T2 27146
+#define T3 43790
+#define C4 23170
+
+ static short _T1[] ATTR_ALIGN(8) = {T1,T1,T1,T1};
+ static short _T2[] ATTR_ALIGN(8) = {T2,T2,T2,T2};
+ static short _T3[] ATTR_ALIGN(8) = {T3,T3,T3,T3};
+ static short _C4[] ATTR_ALIGN(8) = {C4,C4,C4,C4};
+
+ /* column code adapted from peter gubanov */
+ /* http://www.elecard.com/peter/idct.shtml */
+
+ movq_m2r (*_T1, mm0); // mm0 = T1
+
+ movq_m2r (*(col+offset+1*8), mm1); // mm1 = x1
+ movq_r2r (mm0, mm2); // mm2 = T1
+
+ movq_m2r (*(col+offset+7*8), mm4); // mm4 = x7
+ pmulhw_r2r (mm1, mm0); // mm0 = T1*x1
+
+ movq_m2r (*_T3, mm5); // mm5 = T3
+ pmulhw_r2r (mm4, mm2); // mm2 = T1*x7
+
+ movq_m2r (*(col+offset+5*8), mm6); // mm6 = x5
+ movq_r2r (mm5, mm7); // mm7 = T3-1
+
+ movq_m2r (*(col+offset+3*8), mm3); // mm3 = x3
+ psubsw_r2r (mm4, mm0); // mm0 = v17
+
+ movq_m2r (*_T2, mm4); // mm4 = T2
+ pmulhw_r2r (mm3, mm5); // mm5 = (T3-1)*x3
+
+ paddsw_r2r (mm2, mm1); // mm1 = u17
+ pmulhw_r2r (mm6, mm7); // mm7 = (T3-1)*x5
+
+ /* slot */
+
+ movq_r2r (mm4, mm2); // mm2 = T2
+ paddsw_r2r (mm3, mm5); // mm5 = T3*x3
+
+ pmulhw_m2r (*(col+offset+2*8), mm4);// mm4 = T2*x2
+ paddsw_r2r (mm6, mm7); // mm7 = T3*x5
+
+ psubsw_r2r (mm6, mm5); // mm5 = v35
+ paddsw_r2r (mm3, mm7); // mm7 = u35
+
+ movq_m2r (*(col+offset+6*8), mm3); // mm3 = x6
+ movq_r2r (mm0, mm6); // mm6 = v17
+
+ pmulhw_r2r (mm3, mm2); // mm2 = T2*x6
+ psubsw_r2r (mm5, mm0); // mm0 = b3
+
+ psubsw_r2r (mm3, mm4); // mm4 = v26
+ paddsw_r2r (mm6, mm5); // mm5 = v12
+
+ movq_r2m (mm0, *(col+offset+3*8)); // save b3 in scratch0
+ movq_r2r (mm1, mm6); // mm6 = u17
+
+ paddsw_m2r (*(col+offset+2*8), mm2);// mm2 = u26
+ paddsw_r2r (mm7, mm6); // mm6 = b0
+
+ psubsw_r2r (mm7, mm1); // mm1 = u12
+ movq_r2r (mm1, mm7); // mm7 = u12
+
+ movq_m2r (*(col+offset+0*8), mm3); // mm3 = x0
+ paddsw_r2r (mm5, mm1); // mm1 = u12+v12
+
+ movq_m2r (*_C4, mm0); // mm0 = C4/2
+ psubsw_r2r (mm5, mm7); // mm7 = u12-v12
+
+ movq_r2m (mm6, *(col+offset+5*8)); // save b0 in scratch1
+ pmulhw_r2r (mm0, mm1); // mm1 = b1/2
+
+ movq_r2r (mm4, mm6); // mm6 = v26
+ pmulhw_r2r (mm0, mm7); // mm7 = b2/2
+
+ movq_m2r (*(col+offset+4*8), mm5); // mm5 = x4
+ movq_r2r (mm3, mm0); // mm0 = x0
+
+ psubsw_r2r (mm5, mm3); // mm3 = v04
+ paddsw_r2r (mm5, mm0); // mm0 = u04
+
+ paddsw_r2r (mm3, mm4); // mm4 = a1
+ movq_r2r (mm0, mm5); // mm5 = u04
+
+ psubsw_r2r (mm6, mm3); // mm3 = a2
+ paddsw_r2r (mm2, mm5); // mm5 = a0
+
+ paddsw_r2r (mm1, mm1); // mm1 = b1
+ psubsw_r2r (mm2, mm0); // mm0 = a3
+
+ paddsw_r2r (mm7, mm7); // mm7 = b2
+ movq_r2r (mm3, mm2); // mm2 = a2
+
+ movq_r2r (mm4, mm6); // mm6 = a1
+ paddsw_r2r (mm7, mm3); // mm3 = a2+b2
+
+ psraw_i2r (COL_SHIFT, mm3); // mm3 = y2
+ paddsw_r2r (mm1, mm4); // mm4 = a1+b1
+
+ psraw_i2r (COL_SHIFT, mm4); // mm4 = y1
+ psubsw_r2r (mm1, mm6); // mm6 = a1-b1
+
+ movq_m2r (*(col+offset+5*8), mm1); // mm1 = b0
+ psubsw_r2r (mm7, mm2); // mm2 = a2-b2
+
+ psraw_i2r (COL_SHIFT, mm6); // mm6 = y6
+ movq_r2r (mm5, mm7); // mm7 = a0
+
+ movq_r2m (mm4, *(col+offset+1*8)); // save y1
+ psraw_i2r (COL_SHIFT, mm2); // mm2 = y5
+
+ movq_r2m (mm3, *(col+offset+2*8)); // save y2
+ paddsw_r2r (mm1, mm5); // mm5 = a0+b0
+
+ movq_m2r (*(col+offset+3*8), mm4); // mm4 = b3
+ psubsw_r2r (mm1, mm7); // mm7 = a0-b0
+
+ psraw_i2r (COL_SHIFT, mm5); // mm5 = y0
+ movq_r2r (mm0, mm3); // mm3 = a3
+
+ movq_r2m (mm2, *(col+offset+5*8)); // save y5
+ psubsw_r2r (mm4, mm3); // mm3 = a3-b3
+
+ psraw_i2r (COL_SHIFT, mm7); // mm7 = y7
+ paddsw_r2r (mm0, mm4); // mm4 = a3+b3
+
+ movq_r2m (mm5, *(col+offset+0*8)); // save y0
+ psraw_i2r (COL_SHIFT, mm3); // mm3 = y4
+
+ movq_r2m (mm6, *(col+offset+6*8)); // save y6
+ psraw_i2r (COL_SHIFT, mm4); // mm4 = y3
+
+ movq_r2m (mm7, *(col+offset+7*8)); // save y7
+
+ movq_r2m (mm3, *(col+offset+4*8)); // save y4
+
+ movq_r2m (mm4, *(col+offset+3*8)); // save y3
+}
+
+
+static int32_t rounder0[] ATTR_ALIGN(8) =
+ rounder ((1 << (COL_SHIFT - 1)) - 0.5);
+static int32_t rounder4[] ATTR_ALIGN(8) = rounder (0);
+static int32_t rounder1[] ATTR_ALIGN(8) =
+ rounder (1.25683487303); /* C1*(C1/C4+C1+C7)/2 */
+static int32_t rounder7[] ATTR_ALIGN(8) =
+ rounder (-0.25); /* C1*(C7/C4+C7-C1)/2 */
+static int32_t rounder2[] ATTR_ALIGN(8) =
+ rounder (0.60355339059); /* C2 * (C6+C2)/2 */
+static int32_t rounder6[] ATTR_ALIGN(8) =
+ rounder (-0.25); /* C2 * (C6-C2)/2 */
+static int32_t rounder3[] ATTR_ALIGN(8) =
+ rounder (0.087788325588); /* C3*(-C3/C4+C3+C5)/2 */
+static int32_t rounder5[] ATTR_ALIGN(8) =
+ rounder (-0.441341716183); /* C3*(-C5/C4+C5-C3)/2 */
+
+
+#define declare_idct(idct,table,idct_row_head,idct_row,idct_row_tail,idct_row_mid) \
+static inline void idct (int16_t * block) \
+{ \
+ static int16_t table04[] ATTR_ALIGN(16) = \
+ table (22725, 21407, 19266, 16384, 12873, 8867, 4520); \
+ static int16_t table17[] ATTR_ALIGN(16) = \
+ table (31521, 29692, 26722, 22725, 17855, 12299, 6270); \
+ static int16_t table26[] ATTR_ALIGN(16) = \
+ table (29692, 27969, 25172, 21407, 16819, 11585, 5906); \
+ static int16_t table35[] ATTR_ALIGN(16) = \
+ table (26722, 25172, 22654, 19266, 15137, 10426, 5315); \
+ \
+ idct_row_head (block, 0*8, table04); \
+ idct_row (table04, rounder0); \
+ idct_row_mid (block, 0*8, 4*8, table04); \
+ idct_row (table04, rounder4); \
+ idct_row_mid (block, 4*8, 1*8, table17); \
+ idct_row (table17, rounder1); \
+ idct_row_mid (block, 1*8, 7*8, table17); \
+ idct_row (table17, rounder7); \
+ idct_row_mid (block, 7*8, 2*8, table26); \
+ idct_row (table26, rounder2); \
+ idct_row_mid (block, 2*8, 6*8, table26); \
+ idct_row (table26, rounder6); \
+ idct_row_mid (block, 6*8, 3*8, table35); \
+ idct_row (table35, rounder3); \
+ idct_row_mid (block, 3*8, 5*8, table35); \
+ idct_row (table35, rounder5); \
+ idct_row_tail (block, 5*8); \
+ \
+ idct_col (block, 0); \
+ idct_col (block, 4); \
+}
+
+
+#define COPY_MMX(offset,r0,r1,r2) \
+do { \
+ movq_m2r (*(block+offset), r0); \
+ dest += stride; \
+ movq_m2r (*(block+offset+4), r1); \
+ movq_r2m (r2, *dest); \
+ packuswb_r2r (r1, r0); \
+} while (0)
+
+static void block_copy (int16_t * block, uint8_t * dest, int stride)
+{
+ movq_m2r (*(block+0*8), mm0);
+ movq_m2r (*(block+0*8+4), mm1);
+ movq_m2r (*(block+1*8), mm2);
+ packuswb_r2r (mm1, mm0);
+ movq_m2r (*(block+1*8+4), mm3);
+ movq_r2m (mm0, *dest);
+ packuswb_r2r (mm3, mm2);
+ COPY_MMX (2*8, mm0, mm1, mm2);
+ COPY_MMX (3*8, mm2, mm3, mm0);
+ COPY_MMX (4*8, mm0, mm1, mm2);
+ COPY_MMX (5*8, mm2, mm3, mm0);
+ COPY_MMX (6*8, mm0, mm1, mm2);
+ COPY_MMX (7*8, mm2, mm3, mm0);
+ movq_r2m (mm2, *(dest+stride));
+}
+
+
+#define ADD_MMX(offset,r1,r2,r3,r4) \
+do { \
+ movq_m2r (*(dest+2*stride), r1); \
+ packuswb_r2r (r4, r3); \
+ movq_r2r (r1, r2); \
+ dest += stride; \
+ movq_r2m (r3, *dest); \
+ punpcklbw_r2r (mm0, r1); \
+ paddsw_m2r (*(block+offset), r1); \
+ punpckhbw_r2r (mm0, r2); \
+ paddsw_m2r (*(block+offset+4), r2); \
+} while (0)
+
+static void block_add (int16_t * block, uint8_t * dest, int stride)
+{
+ movq_m2r (*dest, mm1);
+ pxor_r2r (mm0, mm0);
+ movq_m2r (*(dest+stride), mm3);
+ movq_r2r (mm1, mm2);
+ punpcklbw_r2r (mm0, mm1);
+ movq_r2r (mm3, mm4);
+ paddsw_m2r (*(block+0*8), mm1);
+ punpckhbw_r2r (mm0, mm2);
+ paddsw_m2r (*(block+0*8+4), mm2);
+ punpcklbw_r2r (mm0, mm3);
+ paddsw_m2r (*(block+1*8), mm3);
+ packuswb_r2r (mm2, mm1);
+ punpckhbw_r2r (mm0, mm4);
+ movq_r2m (mm1, *dest);
+ paddsw_m2r (*(block+1*8+4), mm4);
+ ADD_MMX (2*8, mm1, mm2, mm3, mm4);
+ ADD_MMX (3*8, mm3, mm4, mm1, mm2);
+ ADD_MMX (4*8, mm1, mm2, mm3, mm4);
+ ADD_MMX (5*8, mm3, mm4, mm1, mm2);
+ ADD_MMX (6*8, mm1, mm2, mm3, mm4);
+ ADD_MMX (7*8, mm3, mm4, mm1, mm2);
+ packuswb_r2r (mm4, mm3);
+ movq_r2m (mm3, *(dest+stride));
+}
+
+
+declare_idct (mmxext_idct, mmxext_table,
+ mmxext_row_head, mmxext_row, mmxext_row_tail, mmxext_row_mid)
+
+void idct_block_copy_mmxext (int16_t * block, uint8_t * dest, int stride)
+{
+ mmxext_idct (block);
+ block_copy (block, dest, stride);
+}
+
+void idct_block_add_mmxext (int16_t * block, uint8_t * dest, int stride)
+{
+ mmxext_idct (block);
+ block_add (block, dest, stride);
+}
+
+
+declare_idct (mmx_idct, mmx_table,
+ mmx_row_head, mmx_row, mmx_row_tail, mmx_row_mid)
+
+void idct_block_copy_mmx (int16_t * block, uint8_t * dest, int stride)
+{
+ mmx_idct (block);
+ block_copy (block, dest, stride);
+}
+
+void idct_block_add_mmx (int16_t * block, uint8_t * dest, int stride)
+{
+ mmx_idct (block);
+ block_add (block, dest, stride);
+}
+
+
+void idct_mmx_init (void)
+{
+ extern uint8_t scan_norm[64];
+ extern uint8_t scan_alt[64];
+ int i, j;
+
+ /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */
+
+ for (i = 0; i < 64; i++) {
+ j = scan_norm[i];
+ scan_norm[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2);
+ j = scan_alt[i];
+ scan_alt[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2);
+ }
+}
+
+#endif
diff --git a/src/libmpeg2/motion_comp.c b/src/libmpeg2/motion_comp.c
new file mode 100644
index 000000000..fd4055265
--- /dev/null
+++ b/src/libmpeg2/motion_comp.c
@@ -0,0 +1,125 @@
+/*
+ * motion_comp.c
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+#include "cpu_accel.h"
+
+mc_functions_t mc_functions;
+
+void motion_comp_init (void)
+{
+
+#ifdef ARCH_X86
+ if (config.flags & MM_ACCEL_X86_MMXEXT) {
+ fprintf (stderr, "Using MMXEXT for motion compensation\n");
+ mc_functions = mc_functions_mmxext;
+ } else if (config.flags & MM_ACCEL_X86_3DNOW) {
+ fprintf (stderr, "Using 3DNOW for motion compensation\n");
+ mc_functions = mc_functions_3dnow;
+ } else if (config.flags & MM_ACCEL_X86_MMX) {
+ fprintf (stderr, "Using MMX for motion compensation\n");
+ mc_functions = mc_functions_mmx;
+ } else
+#endif
+#ifdef LIBMPEG2_MLIB
+ if (config.flags & MM_ACCEL_MLIB) {
+ fprintf (stderr, "Using mlib for motion compensation\n");
+ mc_functions = mc_functions_mlib;
+ } else
+#endif
+ {
+ fprintf (stderr, "No accelerated motion compensation found\n");
+ mc_functions = mc_functions_c;
+ }
+}
+
+#define avg2(a,b) ((a+b+1)>>1)
+#define avg4(a,b,c,d) ((a+b+c+d+2)>>2)
+
+#define predict_(i) (ref[i])
+#define predict_x(i) (avg2 (ref[i], ref[i+1]))
+#define predict_y(i) (avg2 (ref[i], (ref+stride)[i]))
+#define predict_xy(i) (avg4 (ref[i], ref[i+1], (ref+stride)[i], (ref+stride)[i+1]))
+
+#define put(predictor,i) dest[i] = predictor (i)
+#define avg(predictor,i) dest[i] = avg2 (predictor (i), dest[i])
+
+/* mc function template */
+
+#define MC_FUNC(op,xy) \
+static void MC_##op##_##xy##16_c (uint8_t * dest, uint8_t * ref,\
+ int stride, int height) \
+{ \
+ do { \
+ op (predict_##xy, 0); \
+ op (predict_##xy, 1); \
+ op (predict_##xy, 2); \
+ op (predict_##xy, 3); \
+ op (predict_##xy, 4); \
+ op (predict_##xy, 5); \
+ op (predict_##xy, 6); \
+ op (predict_##xy, 7); \
+ op (predict_##xy, 8); \
+ op (predict_##xy, 9); \
+ op (predict_##xy, 10); \
+ op (predict_##xy, 11); \
+ op (predict_##xy, 12); \
+ op (predict_##xy, 13); \
+ op (predict_##xy, 14); \
+ op (predict_##xy, 15); \
+ ref += stride; \
+ dest += stride; \
+ } while (--height); \
+} \
+static void MC_##op##_##xy##8_c (uint8_t * dest, uint8_t * ref, \
+ int stride, int height) \
+{ \
+ do { \
+ op (predict_##xy, 0); \
+ op (predict_##xy, 1); \
+ op (predict_##xy, 2); \
+ op (predict_##xy, 3); \
+ op (predict_##xy, 4); \
+ op (predict_##xy, 5); \
+ op (predict_##xy, 6); \
+ op (predict_##xy, 7); \
+ ref += stride; \
+ dest += stride; \
+ } while (--height); \
+}
+
+/* definitions of the actual mc functions */
+
+MC_FUNC (put,)
+MC_FUNC (avg,)
+MC_FUNC (put,x)
+MC_FUNC (avg,x)
+MC_FUNC (put,y)
+MC_FUNC (avg,y)
+MC_FUNC (put,xy)
+MC_FUNC (avg,xy)
+
+MOTION_COMP_EXTERN (c)
diff --git a/src/libmpeg2/motion_comp_mlib.c b/src/libmpeg2/motion_comp_mlib.c
new file mode 100644
index 000000000..91c0fb5a8
--- /dev/null
+++ b/src/libmpeg2/motion_comp_mlib.c
@@ -0,0 +1,180 @@
+/*
+ * motion_comp_mlib.c
+ * Copyright (C) 2000-2001 Håkan Hjort <d95hjort@dtek.chalmers.se>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#ifdef LIBMPEG2_MLIB
+
+#include <inttypes.h>
+#include <mlib_types.h>
+#include <mlib_status.h>
+#include <mlib_sys.h>
+#include <mlib_video.h>
+
+#include "mpeg2_internal.h"
+
+static void MC_put_16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoCopyRef_U8_U8_16x16 (dest, ref, stride);
+ else
+ mlib_VideoCopyRef_U8_U8_16x8 (dest, ref, stride);
+}
+
+static void MC_put_x16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoInterpX_U8_U8_16x16 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpX_U8_U8_16x8 (dest, ref, stride, stride);
+}
+
+static void MC_put_y16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoInterpY_U8_U8_16x16 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpY_U8_U8_16x8 (dest, ref, stride, stride);
+}
+
+static void MC_put_xy16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoInterpXY_U8_U8_16x16 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpXY_U8_U8_16x8 (dest, ref, stride, stride);
+}
+
+static void MC_put_8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoCopyRef_U8_U8_8x8 (dest, ref, stride);
+ else
+ mlib_VideoCopyRef_U8_U8_8x4 (dest, ref, stride);
+}
+
+static void MC_put_x8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoInterpX_U8_U8_8x8 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpX_U8_U8_8x4 (dest, ref, stride, stride);
+}
+
+static void MC_put_y8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoInterpY_U8_U8_8x8 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpY_U8_U8_8x4 (dest, ref, stride, stride);
+}
+
+static void MC_put_xy8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoInterpXY_U8_U8_8x8 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpXY_U8_U8_8x4 (dest, ref, stride, stride);
+}
+
+static void MC_avg_16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoCopyRefAve_U8_U8_16x16 (dest, ref, stride);
+ else
+ mlib_VideoCopyRefAve_U8_U8_16x8 (dest, ref, stride);
+}
+
+static void MC_avg_x16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoInterpAveX_U8_U8_16x16 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpAveX_U8_U8_16x8 (dest, ref, stride, stride);
+}
+
+static void MC_avg_y16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoInterpAveY_U8_U8_16x16 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpAveY_U8_U8_16x8 (dest, ref, stride, stride);
+}
+
+static void MC_avg_xy16_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 16)
+ mlib_VideoInterpAveXY_U8_U8_16x16 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpAveXY_U8_U8_16x8 (dest, ref, stride, stride);
+}
+
+static void MC_avg_8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoCopyRefAve_U8_U8_8x8 (dest, ref, stride);
+ else
+ mlib_VideoCopyRefAve_U8_U8_8x4 (dest, ref, stride);
+}
+
+static void MC_avg_x8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoInterpAveX_U8_U8_8x8 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpAveX_U8_U8_8x4 (dest, ref, stride, stride);
+}
+
+static void MC_avg_y8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoInterpAveY_U8_U8_8x8 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpAveY_U8_U8_8x4 (dest, ref, stride, stride);
+}
+
+static void MC_avg_xy8_mlib (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ if (height == 8)
+ mlib_VideoInterpAveXY_U8_U8_8x8 (dest, ref, stride, stride);
+ else
+ mlib_VideoInterpAveXY_U8_U8_8x4 (dest, ref, stride, stride);
+}
+
+MOTION_COMP_EXTERN (mlib)
+
+#endif
diff --git a/src/libmpeg2/motion_comp_mmx.c b/src/libmpeg2/motion_comp_mmx.c
new file mode 100644
index 000000000..049546b1f
--- /dev/null
+++ b/src/libmpeg2/motion_comp_mmx.c
@@ -0,0 +1,1017 @@
+/*
+ * motion_comp_mmx.c
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#ifdef ARCH_X86
+
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+#include "attributes.h"
+#include "cpu_accel.h"
+
+#define CPU_MMXEXT 0
+#define CPU_3DNOW 1
+
+
+/* MMX code - needs a rewrite */
+
+
+
+
+
+
+
+/* some rounding constants */
+mmx_t round1 = {0x0001000100010001LL};
+mmx_t round4 = {0x0002000200020002LL};
+
+/*
+ * This code should probably be compiled with loop unrolling
+ * (ie, -funroll-loops in gcc)becuase some of the loops
+ * use a small static number of iterations. This was written
+ * with the assumption the compiler knows best about when
+ * unrolling will help
+ */
+
+static inline void mmx_zero_reg ()
+{
+ /* load 0 into mm0 */
+ pxor_r2r (mm0, mm0);
+}
+
+static inline void mmx_average_2_U8 (uint8_t * dest,
+ uint8_t * src1, uint8_t * src2)
+{
+ /* *dest = (*src1 + *src2 + 1)/ 2; */
+
+ movq_m2r (*src1, mm1); // load 8 src1 bytes
+ movq_r2r (mm1, mm2); // copy 8 src1 bytes
+
+ movq_m2r (*src2, mm3); // load 8 src2 bytes
+ movq_r2r (mm3, mm4); // copy 8 src2 bytes
+
+ punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes
+ punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes
+
+ paddw_r2r (mm3, mm1); // add lows to mm1
+ paddw_m2r (round1, mm1);
+ psraw_i2r (1, mm1); // /2
+
+ paddw_r2r (mm4, mm2); // add highs to mm2
+ paddw_m2r (round1, mm2);
+ psraw_i2r (1, mm2); // /2
+
+ packuswb_r2r (mm2, mm1); // pack (w/ saturation)
+ movq_r2m (mm1, *dest); // store result in dest
+}
+
+static inline void mmx_interp_average_2_U8 (uint8_t * dest,
+ uint8_t * src1, uint8_t * src2)
+{
+ /* *dest = (*dest + (*src1 + *src2 + 1)/ 2 + 1)/ 2; */
+
+ movq_m2r (*dest, mm1); // load 8 dest bytes
+ movq_r2r (mm1, mm2); // copy 8 dest bytes
+
+ movq_m2r (*src1, mm3); // load 8 src1 bytes
+ movq_r2r (mm3, mm4); // copy 8 src1 bytes
+
+ movq_m2r (*src2, mm5); // load 8 src2 bytes
+ movq_r2r (mm5, mm6); // copy 8 src2 bytes
+
+ punpcklbw_r2r (mm0, mm1); // unpack low dest bytes
+ punpckhbw_r2r (mm0, mm2); // unpack high dest bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low src1 bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high src1 bytes
+
+ punpcklbw_r2r (mm0, mm5); // unpack low src2 bytes
+ punpckhbw_r2r (mm0, mm6); // unpack high src2 bytes
+
+ paddw_r2r (mm5, mm3); // add lows
+ paddw_m2r (round1, mm3);
+ psraw_i2r (1, mm3); // /2
+
+ paddw_r2r (mm6, mm4); // add highs
+ paddw_m2r (round1, mm4);
+ psraw_i2r (1, mm4); // /2
+
+ paddw_r2r (mm3, mm1); // add lows
+ paddw_m2r (round1, mm1);
+ psraw_i2r (1, mm1); // /2
+
+ paddw_r2r (mm4, mm2); // add highs
+ paddw_m2r (round1, mm2);
+ psraw_i2r (1, mm2); // /2
+
+ packuswb_r2r (mm2, mm1); // pack (w/ saturation)
+ movq_r2m (mm1, *dest); // store result in dest
+}
+
+static inline void mmx_average_4_U8 (uint8_t * dest,
+ uint8_t * src1, uint8_t * src2,
+ uint8_t * src3, uint8_t * src4)
+{
+ /* *dest = (*src1 + *src2 + *src3 + *src4 + 2)/ 4; */
+
+ movq_m2r (*src1, mm1); // load 8 src1 bytes
+ movq_r2r (mm1, mm2); // copy 8 src1 bytes
+
+ punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes
+ punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes
+
+ movq_m2r (*src2, mm3); // load 8 src2 bytes
+ movq_r2r (mm3, mm4); // copy 8 src2 bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes
+
+ paddw_r2r (mm3, mm1); // add lows
+ paddw_r2r (mm4, mm2); // add highs
+
+ /* now have partials in mm1 and mm2 */
+
+ movq_m2r (*src3, mm3); // load 8 src3 bytes
+ movq_r2r (mm3, mm4); // copy 8 src3 bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low src3 bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high src3 bytes
+
+ paddw_r2r (mm3, mm1); // add lows
+ paddw_r2r (mm4, mm2); // add highs
+
+ movq_m2r (*src4, mm5); // load 8 src4 bytes
+ movq_r2r (mm5, mm6); // copy 8 src4 bytes
+
+ punpcklbw_r2r (mm0, mm5); // unpack low src4 bytes
+ punpckhbw_r2r (mm0, mm6); // unpack high src4 bytes
+
+ paddw_r2r (mm5, mm1); // add lows
+ paddw_r2r (mm6, mm2); // add highs
+
+ /* now have subtotal in mm1 and mm2 */
+
+ paddw_m2r (round4, mm1);
+ psraw_i2r (2, mm1); // /4
+ paddw_m2r (round4, mm2);
+ psraw_i2r (2, mm2); // /4
+
+ packuswb_r2r (mm2, mm1); // pack (w/ saturation)
+ movq_r2m (mm1, *dest); // store result in dest
+}
+
+static inline void mmx_interp_average_4_U8 (uint8_t * dest,
+ uint8_t * src1, uint8_t * src2,
+ uint8_t * src3, uint8_t * src4)
+{
+ /* *dest = (*dest + (*src1 + *src2 + *src3 + *src4 + 2)/ 4 + 1)/ 2; */
+
+ movq_m2r (*src1, mm1); // load 8 src1 bytes
+ movq_r2r (mm1, mm2); // copy 8 src1 bytes
+
+ punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes
+ punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes
+
+ movq_m2r (*src2, mm3); // load 8 src2 bytes
+ movq_r2r (mm3, mm4); // copy 8 src2 bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes
+
+ paddw_r2r (mm3, mm1); // add lows
+ paddw_r2r (mm4, mm2); // add highs
+
+ /* now have partials in mm1 and mm2 */
+
+ movq_m2r (*src3, mm3); // load 8 src3 bytes
+ movq_r2r (mm3, mm4); // copy 8 src3 bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low src3 bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high src3 bytes
+
+ paddw_r2r (mm3, mm1); // add lows
+ paddw_r2r (mm4, mm2); // add highs
+
+ movq_m2r (*src4, mm5); // load 8 src4 bytes
+ movq_r2r (mm5, mm6); // copy 8 src4 bytes
+
+ punpcklbw_r2r (mm0, mm5); // unpack low src4 bytes
+ punpckhbw_r2r (mm0, mm6); // unpack high src4 bytes
+
+ paddw_r2r (mm5, mm1); // add lows
+ paddw_r2r (mm6, mm2); // add highs
+
+ paddw_m2r (round4, mm1);
+ psraw_i2r (2, mm1); // /4
+ paddw_m2r (round4, mm2);
+ psraw_i2r (2, mm2); // /4
+
+ /* now have subtotal/4 in mm1 and mm2 */
+
+ movq_m2r (*dest, mm3); // load 8 dest bytes
+ movq_r2r (mm3, mm4); // copy 8 dest bytes
+
+ punpcklbw_r2r (mm0, mm3); // unpack low dest bytes
+ punpckhbw_r2r (mm0, mm4); // unpack high dest bytes
+
+ paddw_r2r (mm3, mm1); // add lows
+ paddw_r2r (mm4, mm2); // add highs
+
+ paddw_m2r (round1, mm1);
+ psraw_i2r (1, mm1); // /2
+ paddw_m2r (round1, mm2);
+ psraw_i2r (1, mm2); // /2
+
+ /* now have end value in mm1 and mm2 */
+
+ packuswb_r2r (mm2, mm1); // pack (w/ saturation)
+ movq_r2m (mm1,*dest); // store result in dest
+}
+
+/*-----------------------------------------------------------------------*/
+
+static inline void MC_avg_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ mmx_zero_reg ();
+
+ do {
+ mmx_average_2_U8 (dest, dest, ref);
+
+ if (width == 16)
+ mmx_average_2_U8 (dest+8, dest+8, ref+8);
+
+ dest += stride;
+ ref += stride;
+ } while (--height);
+}
+
+static void MC_avg_16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_avg_8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_mmx (8, height, dest, ref, stride);
+}
+
+/*-----------------------------------------------------------------------*/
+
+static inline void MC_put_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ mmx_zero_reg ();
+
+ do {
+ movq_m2r (* ref, mm1); // load 8 ref bytes
+ movq_r2m (mm1,* dest); // store 8 bytes at curr
+
+ if (width == 16)
+ {
+ movq_m2r (* (ref+8), mm1); // load 8 ref bytes
+ movq_r2m (mm1,* (dest+8)); // store 8 bytes at curr
+ }
+
+ dest += stride;
+ ref += stride;
+ } while (--height);
+}
+
+static void MC_put_16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_put_8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_mmx (8, height, dest, ref, stride);
+}
+
+/*-----------------------------------------------------------------------*/
+
+/* Half pixel interpolation in the x direction */
+static inline void MC_avg_x_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ mmx_zero_reg ();
+
+ do {
+ mmx_interp_average_2_U8 (dest, ref, ref+1);
+
+ if (width == 16)
+ mmx_interp_average_2_U8 (dest+8, ref+8, ref+9);
+
+ dest += stride;
+ ref += stride;
+ } while (--height);
+}
+
+static void MC_avg_x16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_x_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_avg_x8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_x_mmx (8, height, dest, ref, stride);
+}
+
+/*-----------------------------------------------------------------------*/
+
+static inline void MC_put_x_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ mmx_zero_reg ();
+
+ do {
+ mmx_average_2_U8 (dest, ref, ref+1);
+
+ if (width == 16)
+ mmx_average_2_U8 (dest+8, ref+8, ref+9);
+
+ dest += stride;
+ ref += stride;
+ } while (--height);
+}
+
+static void MC_put_x16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_x_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_put_x8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_x_mmx (8, height, dest, ref, stride);
+}
+
+/*-----------------------------------------------------------------------*/
+
+static inline void MC_avg_xy_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ uint8_t * ref_next = ref+stride;
+
+ mmx_zero_reg ();
+
+ do {
+ mmx_interp_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1);
+
+ if (width == 16)
+ mmx_interp_average_4_U8 (dest+8, ref+8, ref+9,
+ ref_next+8, ref_next+9);
+
+ dest += stride;
+ ref += stride;
+ ref_next += stride;
+ } while (--height);
+}
+
+static void MC_avg_xy16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_xy_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_avg_xy8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_xy_mmx (8, height, dest, ref, stride);
+}
+
+/*-----------------------------------------------------------------------*/
+
+static inline void MC_put_xy_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ uint8_t * ref_next = ref+stride;
+
+ mmx_zero_reg ();
+
+ do {
+ mmx_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1);
+
+ if (width == 16)
+ mmx_average_4_U8 (dest+8, ref+8, ref+9, ref_next+8, ref_next+9);
+
+ dest += stride;
+ ref += stride;
+ ref_next += stride;
+ } while (--height);
+}
+
+static void MC_put_xy16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_xy_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_put_xy8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_xy_mmx (8, height, dest, ref, stride);
+}
+
+/*-----------------------------------------------------------------------*/
+
+static inline void MC_avg_y_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ uint8_t * ref_next = ref+stride;
+
+ mmx_zero_reg ();
+
+ do {
+ mmx_interp_average_2_U8 (dest, ref, ref_next);
+
+ if (width == 16)
+ mmx_interp_average_2_U8 (dest+8, ref+8, ref_next+8);
+
+ dest += stride;
+ ref += stride;
+ ref_next += stride;
+ } while (--height);
+}
+
+static void MC_avg_y16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_y_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_avg_y8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg_y_mmx (8, height, dest, ref, stride);
+}
+
+/*-----------------------------------------------------------------------*/
+
+static inline void MC_put_y_mmx (int width, int height,
+ uint8_t * dest, uint8_t * ref, int stride)
+{
+ uint8_t * ref_next = ref+stride;
+
+ mmx_zero_reg ();
+
+ do {
+ mmx_average_2_U8 (dest, ref, ref_next);
+
+ if (width == 16)
+ mmx_average_2_U8 (dest+8, ref+8, ref_next+8);
+
+ dest += stride;
+ ref += stride;
+ ref_next += stride;
+ } while (--height);
+}
+
+static void MC_put_y16_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_y_mmx (16, height, dest, ref, stride);
+}
+
+static void MC_put_y8_mmx (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put_y_mmx (8, height, dest, ref, stride);
+}
+
+
+MOTION_COMP_EXTERN (mmx)
+
+
+
+
+
+
+
+/* CPU_MMXEXT/CPU_3DNOW adaptation layer */
+
+#define pavg_r2r(src,dest) \
+do { \
+ if (cpu == CPU_MMXEXT) \
+ pavgb_r2r (src, dest); \
+ else \
+ pavgusb_r2r (src, dest); \
+} while (0)
+
+#define pavg_m2r(src,dest) \
+do { \
+ if (cpu == CPU_MMXEXT) \
+ pavgb_m2r (src, dest); \
+ else \
+ pavgusb_m2r (src, dest); \
+} while (0)
+
+
+/* CPU_MMXEXT code */
+
+
+static inline void MC_put1_8 (int height, uint8_t * dest, uint8_t * ref,
+ int stride)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_r2m (mm0, *dest);
+ ref += stride;
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_put1_16 (int height, uint8_t * dest, uint8_t * ref,
+ int stride)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+8), mm1);
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ movq_r2m (mm1, *(dest+8));
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_avg1_8 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ pavg_m2r (*dest, mm0);
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_avg1_16 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+8), mm1);
+ pavg_m2r (*dest, mm0);
+ pavg_m2r (*(dest+8), mm1);
+ movq_r2m (mm0, *dest);
+ ref += stride;
+ movq_r2m (mm1, *(dest+8));
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_put2_8 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int offset, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ pavg_m2r (*(ref+offset), mm0);
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_put2_16 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int offset, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+8), mm1);
+ pavg_m2r (*(ref+offset), mm0);
+ pavg_m2r (*(ref+offset+8), mm1);
+ movq_r2m (mm0, *dest);
+ ref += stride;
+ movq_r2m (mm1, *(dest+8));
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_avg2_8 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int offset, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ pavg_m2r (*(ref+offset), mm0);
+ pavg_m2r (*dest, mm0);
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_avg2_16 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int offset, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+8), mm1);
+ pavg_m2r (*(ref+offset), mm0);
+ pavg_m2r (*(ref+offset+8), mm1);
+ pavg_m2r (*dest, mm0);
+ pavg_m2r (*(dest+8), mm1);
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ movq_r2m (mm1, *(dest+8));
+ dest += stride;
+ } while (--height);
+}
+
+static mmx_t mask_one = {0x0101010101010101LL};
+
+static inline void MC_put4_8 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int cpu)
+{
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+1), mm1);
+ movq_r2r (mm0, mm7);
+ pxor_r2r (mm1, mm7);
+ pavg_r2r (mm1, mm0);
+ ref += stride;
+
+ do {
+ movq_m2r (*ref, mm2);
+ movq_r2r (mm0, mm5);
+
+ movq_m2r (*(ref+1), mm3);
+ movq_r2r (mm2, mm6);
+
+ pxor_r2r (mm3, mm6);
+ pavg_r2r (mm3, mm2);
+
+ por_r2r (mm6, mm7);
+ pxor_r2r (mm2, mm5);
+
+ pand_r2r (mm5, mm7);
+ pavg_r2r (mm2, mm0);
+
+ pand_m2r (mask_one, mm7);
+
+ psubusb_r2r (mm7, mm0);
+
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ dest += stride;
+
+ movq_r2r (mm6, mm7); // unroll !
+ movq_r2r (mm2, mm0); // unroll !
+ } while (--height);
+}
+
+static inline void MC_put4_16 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+stride+1), mm1);
+ movq_r2r (mm0, mm7);
+ movq_m2r (*(ref+1), mm2);
+ pxor_r2r (mm1, mm7);
+ movq_m2r (*(ref+stride), mm3);
+ movq_r2r (mm2, mm6);
+ pxor_r2r (mm3, mm6);
+ pavg_r2r (mm1, mm0);
+ pavg_r2r (mm3, mm2);
+ por_r2r (mm6, mm7);
+ movq_r2r (mm0, mm6);
+ pxor_r2r (mm2, mm6);
+ pand_r2r (mm6, mm7);
+ pand_m2r (mask_one, mm7);
+ pavg_r2r (mm2, mm0);
+ psubusb_r2r (mm7, mm0);
+ movq_r2m (mm0, *dest);
+
+ movq_m2r (*(ref+8), mm0);
+ movq_m2r (*(ref+stride+9), mm1);
+ movq_r2r (mm0, mm7);
+ movq_m2r (*(ref+9), mm2);
+ pxor_r2r (mm1, mm7);
+ movq_m2r (*(ref+stride+8), mm3);
+ movq_r2r (mm2, mm6);
+ pxor_r2r (mm3, mm6);
+ pavg_r2r (mm1, mm0);
+ pavg_r2r (mm3, mm2);
+ por_r2r (mm6, mm7);
+ movq_r2r (mm0, mm6);
+ pxor_r2r (mm2, mm6);
+ pand_r2r (mm6, mm7);
+ pand_m2r (mask_one, mm7);
+ pavg_r2r (mm2, mm0);
+ psubusb_r2r (mm7, mm0);
+ ref += stride;
+ movq_r2m (mm0, *(dest+8));
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_avg4_8 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+stride+1), mm1);
+ movq_r2r (mm0, mm7);
+ movq_m2r (*(ref+1), mm2);
+ pxor_r2r (mm1, mm7);
+ movq_m2r (*(ref+stride), mm3);
+ movq_r2r (mm2, mm6);
+ pxor_r2r (mm3, mm6);
+ pavg_r2r (mm1, mm0);
+ pavg_r2r (mm3, mm2);
+ por_r2r (mm6, mm7);
+ movq_r2r (mm0, mm6);
+ pxor_r2r (mm2, mm6);
+ pand_r2r (mm6, mm7);
+ pand_m2r (mask_one, mm7);
+ pavg_r2r (mm2, mm0);
+ psubusb_r2r (mm7, mm0);
+ movq_m2r (*dest, mm1);
+ pavg_r2r (mm1, mm0);
+ ref += stride;
+ movq_r2m (mm0, *dest);
+ dest += stride;
+ } while (--height);
+}
+
+static inline void MC_avg4_16 (int height, uint8_t * dest, uint8_t * ref,
+ int stride, int cpu)
+{
+ do {
+ movq_m2r (*ref, mm0);
+ movq_m2r (*(ref+stride+1), mm1);
+ movq_r2r (mm0, mm7);
+ movq_m2r (*(ref+1), mm2);
+ pxor_r2r (mm1, mm7);
+ movq_m2r (*(ref+stride), mm3);
+ movq_r2r (mm2, mm6);
+ pxor_r2r (mm3, mm6);
+ pavg_r2r (mm1, mm0);
+ pavg_r2r (mm3, mm2);
+ por_r2r (mm6, mm7);
+ movq_r2r (mm0, mm6);
+ pxor_r2r (mm2, mm6);
+ pand_r2r (mm6, mm7);
+ pand_m2r (mask_one, mm7);
+ pavg_r2r (mm2, mm0);
+ psubusb_r2r (mm7, mm0);
+ movq_m2r (*dest, mm1);
+ pavg_r2r (mm1, mm0);
+ movq_r2m (mm0, *dest);
+
+ movq_m2r (*(ref+8), mm0);
+ movq_m2r (*(ref+stride+9), mm1);
+ movq_r2r (mm0, mm7);
+ movq_m2r (*(ref+9), mm2);
+ pxor_r2r (mm1, mm7);
+ movq_m2r (*(ref+stride+8), mm3);
+ movq_r2r (mm2, mm6);
+ pxor_r2r (mm3, mm6);
+ pavg_r2r (mm1, mm0);
+ pavg_r2r (mm3, mm2);
+ por_r2r (mm6, mm7);
+ movq_r2r (mm0, mm6);
+ pxor_r2r (mm2, mm6);
+ pand_r2r (mm6, mm7);
+ pand_m2r (mask_one, mm7);
+ pavg_r2r (mm2, mm0);
+ psubusb_r2r (mm7, mm0);
+ movq_m2r (*(dest+8), mm1);
+ pavg_r2r (mm1, mm0);
+ ref += stride;
+ movq_r2m (mm0, *(dest+8));
+ dest += stride;
+ } while (--height);
+}
+
+static void MC_avg_16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg1_16 (height, dest, ref, stride, CPU_MMXEXT);
+}
+
+static void MC_avg_8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg1_8 (height, dest, ref, stride, CPU_MMXEXT);
+}
+
+static void MC_put_16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put1_16 (height, dest, ref, stride);
+}
+
+static void MC_put_8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put1_8 (height, dest, ref, stride);
+}
+
+static void MC_avg_x16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_16 (height, dest, ref, stride, 1, CPU_MMXEXT);
+}
+
+static void MC_avg_x8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_8 (height, dest, ref, stride, 1, CPU_MMXEXT);
+}
+
+static void MC_put_x16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_16 (height, dest, ref, stride, 1, CPU_MMXEXT);
+}
+
+static void MC_put_x8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_8 (height, dest, ref, stride, 1, CPU_MMXEXT);
+}
+
+static void MC_avg_y16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_16 (height, dest, ref, stride, stride, CPU_MMXEXT);
+}
+
+static void MC_avg_y8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_8 (height, dest, ref, stride, stride, CPU_MMXEXT);
+}
+
+static void MC_put_y16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_16 (height, dest, ref, stride, stride, CPU_MMXEXT);
+}
+
+static void MC_put_y8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_8 (height, dest, ref, stride, stride, CPU_MMXEXT);
+}
+
+static void MC_avg_xy16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg4_16 (height, dest, ref, stride, CPU_MMXEXT);
+}
+
+static void MC_avg_xy8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg4_8 (height, dest, ref, stride, CPU_MMXEXT);
+}
+
+static void MC_put_xy16_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put4_16 (height, dest, ref, stride, CPU_MMXEXT);
+}
+
+static void MC_put_xy8_mmxext (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put4_8 (height, dest, ref, stride, CPU_MMXEXT);
+}
+
+
+MOTION_COMP_EXTERN (mmxext)
+
+
+
+static void MC_avg_16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg1_16 (height, dest, ref, stride, CPU_3DNOW);
+}
+
+static void MC_avg_8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg1_8 (height, dest, ref, stride, CPU_3DNOW);
+}
+
+static void MC_put_16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put1_16 (height, dest, ref, stride);
+}
+
+static void MC_put_8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put1_8 (height, dest, ref, stride);
+}
+
+static void MC_avg_x16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_16 (height, dest, ref, stride, 1, CPU_3DNOW);
+}
+
+static void MC_avg_x8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_8 (height, dest, ref, stride, 1, CPU_3DNOW);
+}
+
+static void MC_put_x16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_16 (height, dest, ref, stride, 1, CPU_3DNOW);
+}
+
+static void MC_put_x8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_8 (height, dest, ref, stride, 1, CPU_3DNOW);
+}
+
+static void MC_avg_y16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_16 (height, dest, ref, stride, stride, CPU_3DNOW);
+}
+
+static void MC_avg_y8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg2_8 (height, dest, ref, stride, stride, CPU_3DNOW);
+}
+
+static void MC_put_y16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_16 (height, dest, ref, stride, stride, CPU_3DNOW);
+}
+
+static void MC_put_y8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put2_8 (height, dest, ref, stride, stride, CPU_3DNOW);
+}
+
+static void MC_avg_xy16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg4_16 (height, dest, ref, stride, CPU_3DNOW);
+}
+
+static void MC_avg_xy8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_avg4_8 (height, dest, ref, stride, CPU_3DNOW);
+}
+
+static void MC_put_xy16_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put4_16 (height, dest, ref, stride, CPU_3DNOW);
+}
+
+static void MC_put_xy8_3dnow (uint8_t * dest, uint8_t * ref,
+ int stride, int height)
+{
+ MC_put4_8 (height, dest, ref, stride, CPU_3DNOW);
+}
+
+
+MOTION_COMP_EXTERN (3dnow)
+
+#endif
diff --git a/src/libmpeg2/mpeg2.h b/src/libmpeg2/mpeg2.h
new file mode 100644
index 000000000..c83a61e7e
--- /dev/null
+++ b/src/libmpeg2/mpeg2.h
@@ -0,0 +1,67 @@
+/*
+ * mpeg2.h
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Structure for the mpeg2dec decoder */
+
+typedef struct mpeg2dec_s {
+ vo_instance_t * output;
+
+ /* this is where we keep the state of the decoder */
+ struct picture_s * picture;
+
+ uint32_t shift;
+ int is_display_initialized;
+ int is_sequence_needed;
+ int drop_flag;
+ int drop_frame;
+ int in_slice;
+
+ /* the maximum chunk size is determined by vbv_buffer_size */
+ /* which is 224K for MP@ML streams. */
+ /* (we make no pretenses of decoding anything more than that) */
+ /* allocated in init - gcc has problems allocating such big structures */
+ uint8_t * chunk_buffer;
+ /* pointer to current position in chunk_buffer */
+ uint8_t * chunk_ptr;
+ /* last start code ? */
+ uint8_t code;
+
+ uint32_t pts;
+
+ /* ONLY for 0.2.0 release - will not stay there later */
+ int frame_rate_code;
+} mpeg2dec_t ;
+
+
+
+
+
+/* initialize mpegdec with a opaque user pointer */
+void mpeg2_init (mpeg2dec_t * mpeg2dec, uint32_t mm_accel,
+ vo_instance_t * output);
+
+/* destroy everything which was allocated, shutdown the output */
+void mpeg2_close (mpeg2dec_t * mpeg2dec);
+
+int mpeg2_decode_data (mpeg2dec_t * mpeg2dec,
+ uint8_t * data_start, uint8_t * data_end, uint32_t pts);
+
+void mpeg2_drop (mpeg2dec_t * mpeg2dec, int flag);
diff --git a/src/libmpeg2/mpeg2_internal.h b/src/libmpeg2/mpeg2_internal.h
new file mode 100644
index 000000000..d3a92eb74
--- /dev/null
+++ b/src/libmpeg2/mpeg2_internal.h
@@ -0,0 +1,194 @@
+/*
+ * mpeg2_internal.h
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* macroblock modes */
+#define MACROBLOCK_INTRA 1
+#define MACROBLOCK_PATTERN 2
+#define MACROBLOCK_MOTION_BACKWARD 4
+#define MACROBLOCK_MOTION_FORWARD 8
+#define MACROBLOCK_QUANT 16
+#define DCT_TYPE_INTERLACED 32
+/* motion_type */
+#define MOTION_TYPE_MASK (3*64)
+#define MOTION_TYPE_BASE 64
+#define MC_FIELD (1*64)
+#define MC_FRAME (2*64)
+#define MC_16X8 (2*64)
+#define MC_DMV (3*64)
+
+/* picture structure */
+#define TOP_FIELD 1
+#define BOTTOM_FIELD 2
+#define FRAME_PICTURE 3
+
+/* picture coding type */
+#define I_TYPE 1
+#define P_TYPE 2
+#define B_TYPE 3
+#define D_TYPE 4
+
+typedef struct motion_s {
+ uint8_t * ref[2][3];
+ int pmv[2][2];
+ int f_code[2];
+} motion_t;
+
+typedef struct picture_s {
+ /* first, state that carries information from one macroblock to the */
+ /* next inside a slice, and is never used outside of slice_process() */
+
+ /* DCT coefficients - should be kept aligned ! */
+ int16_t DCTblock[64];
+
+ /* bit parsing stuff */
+ uint32_t bitstream_buf; /* current 32 bit working set of buffer */
+ int bitstream_bits; /* used bits in working set */
+ uint8_t * bitstream_ptr; /* buffer with stream data */
+
+ /* Motion vectors */
+ /* The f_ and b_ correspond to the forward and backward motion */
+ /* predictors */
+ motion_t b_motion;
+ motion_t f_motion;
+
+ /* predictor for DC coefficients in intra blocks */
+ int16_t dc_dct_pred[3];
+
+ int quantizer_scale; /* remove */
+ int current_field; /* remove */
+ int v_offset; /* remove */
+
+
+ /* now non-slice-specific information */
+
+ /* sequence header stuff */
+ uint8_t intra_quantizer_matrix [64];
+ uint8_t non_intra_quantizer_matrix [64];
+
+ /* The width and height of the picture snapped to macroblock units */
+ int coded_picture_width;
+ int coded_picture_height;
+
+ /* picture header stuff */
+
+ /* what type of picture this is (I, P, B, D) */
+ int picture_coding_type;
+
+ /* picture coding extension stuff */
+
+ /* quantization factor for intra dc coefficients */
+ int intra_dc_precision;
+ /* top/bottom/both fields */
+ int picture_structure;
+ /* bool to indicate all predictions are frame based */
+ int frame_pred_frame_dct;
+ /* bool to indicate whether intra blocks have motion vectors */
+ /* (for concealment) */
+ int concealment_motion_vectors;
+ /* bit to indicate which quantization table to use */
+ int q_scale_type;
+ /* bool to use different vlc tables */
+ int intra_vlc_format;
+ /* used for DMV MC */
+ int top_field_first;
+
+ /* stuff derived from bitstream */
+
+ /* pointer to the zigzag scan we're supposed to be using */
+ uint8_t * scan;
+
+ struct vo_frame_s * current_frame;
+ struct vo_frame_s * forward_reference_frame;
+ struct vo_frame_s * backward_reference_frame;
+
+ int second_field;
+
+ int mpeg1;
+
+ /* these things are not needed by the decoder */
+ /* this is a temporary interface, we will build a better one later. */
+ int aspect_ratio_information;
+ int frame_rate_code;
+ int progressive_sequence;
+ int repeat_first_field;
+ int progressive_frame;
+ int bitrate;
+} picture_t;
+
+typedef struct mpeg2_config_s {
+ /* Bit flags that enable various things */
+ uint32_t flags;
+} mpeg2_config_t;
+
+/* The only global variable, */
+/* the config struct */
+extern mpeg2_config_t config;
+
+
+
+/* slice.c */
+void header_state_init (picture_t * picture);
+int header_process_picture_header (picture_t * picture, uint8_t * buffer);
+int header_process_sequence_header (picture_t * picture, uint8_t * buffer);
+int header_process_extension (picture_t * picture, uint8_t * buffer);
+
+/* idct.c */
+void idct_init (void);
+
+/* idct_mlib.c */
+void idct_block_copy_mlib (int16_t * block, uint8_t * dest, int stride);
+void idct_block_add_mlib (int16_t * block, uint8_t * dest, int stride);
+
+/* idct_mmx.c */
+void idct_block_copy_mmxext (int16_t *block, uint8_t * dest, int stride);
+void idct_block_add_mmxext (int16_t *block, uint8_t * dest, int stride);
+void idct_block_copy_mmx (int16_t *block, uint8_t * dest, int stride);
+void idct_block_add_mmx (int16_t *block, uint8_t * dest, int stride);
+void idct_mmx_init (void);
+
+/* motion_comp.c */
+void motion_comp_init (void);
+
+typedef struct mc_functions_s
+{
+ void (* put [8]) (uint8_t *dst, uint8_t *, int32_t, int32_t);
+ void (* avg [8]) (uint8_t *dst, uint8_t *, int32_t, int32_t);
+} mc_functions_t;
+
+#define MOTION_COMP_EXTERN(x) mc_functions_t mc_functions_##x = \
+{ \
+ {MC_put_16_##x, MC_put_x16_##x, MC_put_y16_##x, MC_put_xy16_##x, \
+ MC_put_8_##x, MC_put_x8_##x, MC_put_y8_##x, MC_put_xy8_##x}, \
+ {MC_avg_16_##x, MC_avg_x16_##x, MC_avg_y16_##x, MC_avg_xy16_##x, \
+ MC_avg_8_##x, MC_avg_x8_##x, MC_avg_y8_##x, MC_avg_xy8_##x} \
+};
+
+extern mc_functions_t mc_functions_c;
+extern mc_functions_t mc_functions_mmx;
+extern mc_functions_t mc_functions_mmxext;
+extern mc_functions_t mc_functions_3dnow;
+extern mc_functions_t mc_functions_mlib;
+
+/* slice.c */
+int slice_process (picture_t *picture, uint8_t code, uint8_t * buffer);
+
+/* stats.c */
+void stats_header (uint8_t code, uint8_t * buffer);
diff --git a/src/libmpeg2/slice.c b/src/libmpeg2/slice.c
new file mode 100644
index 000000000..727adb3d9
--- /dev/null
+++ b/src/libmpeg2/slice.c
@@ -0,0 +1,1799 @@
+/*
+ * slice.c
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <inttypes.h>
+
+#include "video_out.h"
+#include "mpeg2_internal.h"
+#include "attributes.h"
+
+extern mc_functions_t mc_functions;
+extern void (* idct_block_copy) (int16_t * block, uint8_t * dest, int stride);
+extern void (* idct_block_add) (int16_t * block, uint8_t * dest, int stride);
+
+#include "vlc.h"
+
+static int non_linear_quantizer_scale [] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 10, 12, 14, 16, 18, 20, 22,
+ 24, 28, 32, 36, 40, 44, 48, 52,
+ 56, 64, 72, 80, 88, 96, 104, 112
+};
+
+static inline int get_macroblock_modes (picture_t * picture)
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ int macroblock_modes;
+ MBtab * tab;
+
+ switch (picture->picture_coding_type) {
+ case I_TYPE:
+
+ tab = MB_I + UBITS (bit_buf, 1);
+ DUMPBITS (bit_buf, bits, tab->len);
+ macroblock_modes = tab->modes;
+
+ if ((! (picture->frame_pred_frame_dct)) &&
+ (picture->picture_structure == FRAME_PICTURE)) {
+ macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
+ DUMPBITS (bit_buf, bits, 1);
+ }
+
+ return macroblock_modes;
+
+ case P_TYPE:
+
+ tab = MB_P + UBITS (bit_buf, 5);
+ DUMPBITS (bit_buf, bits, tab->len);
+ macroblock_modes = tab->modes;
+
+ if (picture->picture_structure != FRAME_PICTURE) {
+ if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) {
+ macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
+ DUMPBITS (bit_buf, bits, 2);
+ }
+ return macroblock_modes;
+ } else if (picture->frame_pred_frame_dct) {
+ if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)
+ macroblock_modes |= MC_FRAME;
+ return macroblock_modes;
+ } else {
+ if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) {
+ macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
+ DUMPBITS (bit_buf, bits, 2);
+ }
+ if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) {
+ macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
+ DUMPBITS (bit_buf, bits, 1);
+ }
+ return macroblock_modes;
+ }
+
+ case B_TYPE:
+
+ tab = MB_B + UBITS (bit_buf, 6);
+ DUMPBITS (bit_buf, bits, tab->len);
+ macroblock_modes = tab->modes;
+
+ if (picture->picture_structure != FRAME_PICTURE) {
+ if (! (macroblock_modes & MACROBLOCK_INTRA)) {
+ macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
+ DUMPBITS (bit_buf, bits, 2);
+ }
+ return macroblock_modes;
+ } else if (picture->frame_pred_frame_dct) {
+ /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */
+ macroblock_modes |= MC_FRAME;
+ return macroblock_modes;
+ } else {
+ if (macroblock_modes & MACROBLOCK_INTRA)
+ goto intra;
+ macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE;
+ DUMPBITS (bit_buf, bits, 2);
+ if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) {
+ intra:
+ macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED;
+ DUMPBITS (bit_buf, bits, 1);
+ }
+ return macroblock_modes;
+ }
+
+ case D_TYPE:
+
+ DUMPBITS (bit_buf, bits, 1);
+ return MACROBLOCK_INTRA;
+
+ default:
+ return 0;
+ }
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline int get_quantizer_scale (picture_t * picture)
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+
+ int quantizer_scale_code;
+
+ quantizer_scale_code = UBITS (bit_buf, 5);
+ DUMPBITS (bit_buf, bits, 5);
+
+ if (picture->q_scale_type)
+ return non_linear_quantizer_scale [quantizer_scale_code];
+ else
+ return quantizer_scale_code << 1;
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline int get_motion_delta (picture_t * picture, int f_code)
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+
+ int delta;
+ int sign;
+ MVtab * tab;
+
+ if (bit_buf & 0x80000000) {
+ DUMPBITS (bit_buf, bits, 1);
+ return 0;
+ } else if (bit_buf >= 0x0c000000) {
+
+ tab = MV_4 + UBITS (bit_buf, 4);
+ delta = (tab->delta << f_code) + 1;
+ bits += tab->len + f_code + 1;
+ bit_buf <<= tab->len;
+
+ sign = SBITS (bit_buf, 1);
+ bit_buf <<= 1;
+
+ if (f_code)
+ delta += UBITS (bit_buf, f_code);
+ bit_buf <<= f_code;
+
+ return (delta ^ sign) - sign;
+
+ } else {
+
+ tab = MV_10 + UBITS (bit_buf, 10);
+ delta = (tab->delta << f_code) + 1;
+ bits += tab->len + 1;
+ bit_buf <<= tab->len;
+
+ sign = SBITS (bit_buf, 1);
+ bit_buf <<= 1;
+
+ if (f_code) {
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ delta += UBITS (bit_buf, f_code);
+ DUMPBITS (bit_buf, bits, f_code);
+ }
+
+ return (delta ^ sign) - sign;
+
+ }
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline int bound_motion_vector (int vector, int f_code)
+{
+#if 1
+ int limit;
+
+ limit = 16 << f_code;
+
+ if (vector >= limit)
+ return vector - 2*limit;
+ else if (vector < -limit)
+ return vector + 2*limit;
+ else return vector;
+#else
+ return (vector << (27 - f_code)) >> (27 - f_code);
+#endif
+}
+
+static inline int get_dmv (picture_t * picture)
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+
+ DMVtab * tab;
+
+ tab = DMV_2 + UBITS (bit_buf, 2);
+ DUMPBITS (bit_buf, bits, tab->len);
+ return tab->dmv;
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline int get_coded_block_pattern (picture_t * picture)
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+
+ CBPtab * tab;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ if (bit_buf >= 0x20000000) {
+
+ tab = CBP_7 - 16 + UBITS (bit_buf, 7);
+ DUMPBITS (bit_buf, bits, tab->len);
+ return tab->cbp;
+
+ } else {
+
+ tab = CBP_9 + UBITS (bit_buf, 9);
+ DUMPBITS (bit_buf, bits, tab->len);
+ return tab->cbp;
+ }
+
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline int get_luma_dc_dct_diff (picture_t * picture)
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ DCtab * tab;
+ int size;
+ int dc_diff;
+
+ if (bit_buf < 0xf8000000) {
+ tab = DC_lum_5 + UBITS (bit_buf, 5);
+ size = tab->size;
+ if (size) {
+ bits += tab->len + size;
+ bit_buf <<= tab->len;
+ dc_diff =
+ UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
+ bit_buf <<= size;
+ return dc_diff;
+ } else {
+ DUMPBITS (bit_buf, bits, 3);
+ return 0;
+ }
+ } else {
+ tab = DC_long - 0x1e0 + UBITS (bit_buf, 9);
+ size = tab->size;
+ DUMPBITS (bit_buf, bits, tab->len);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
+ DUMPBITS (bit_buf, bits, size);
+ return dc_diff;
+ }
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline int get_chroma_dc_dct_diff (picture_t * picture)
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ DCtab * tab;
+ int size;
+ int dc_diff;
+
+ if (bit_buf < 0xf8000000) {
+ tab = DC_chrom_5 + UBITS (bit_buf, 5);
+ size = tab->size;
+ if (size) {
+ bits += tab->len + size;
+ bit_buf <<= tab->len;
+ dc_diff =
+ UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
+ bit_buf <<= size;
+ return dc_diff;
+ } else {
+ DUMPBITS (bit_buf, bits, 2);
+ return 0;
+ }
+ } else {
+ tab = DC_long - 0x3e0 + UBITS (bit_buf, 10);
+ size = tab->size;
+ DUMPBITS (bit_buf, bits, tab->len + 1);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size);
+ DUMPBITS (bit_buf, bits, size);
+ return dc_diff;
+ }
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+#define SATURATE(val) \
+do { \
+ if ((uint32_t)(val + 2048) > 4095) \
+ val = (val > 0) ? 2047 : -2048; \
+} while (0)
+
+static void get_intra_block_B14 (picture_t * picture)
+{
+ int i;
+ int j;
+ int val;
+ uint8_t * scan = picture->scan;
+ uint8_t * quant_matrix = picture->intra_quantizer_matrix;
+ int quantizer_scale = picture->quantizer_scale;
+ int mismatch;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+ int16_t * dest;
+
+ dest = picture->DCTblock;
+ i = 0;
+ mismatch = ~dest[0];
+
+ bit_buf = picture->bitstream_buf;
+ bits = picture->bitstream_bits;
+ bit_ptr = picture->bitstream_ptr;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ while (1) {
+ if (bit_buf >= 0x28000000) {
+
+ tab = DCT_B14AC_5 - 5 + UBITS (bit_buf, 5);
+
+ i += tab->run;
+ if (i >= 64)
+ break; /* end of block */
+
+ normal_code:
+ j = scan[i];
+ bit_buf <<= tab->len;
+ bits += tab->len + 1;
+ val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4;
+
+ /* if (bitstream_get (1)) val = -val; */
+ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
+
+ SATURATE (val);
+ dest[j] = val;
+ mismatch ^= val;
+
+ bit_buf <<= 1;
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else if (bit_buf >= 0x04000000) {
+
+ tab = DCT_B14_8 - 4 + UBITS (bit_buf, 8);
+
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+
+ /* escape code */
+
+ i += UBITS (bit_buf << 6, 6) - 64;
+ if (i >= 64)
+ break; /* illegal, check needed to avoid buffer overflow */
+
+ j = scan[i];
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ val = (SBITS (bit_buf, 12) *
+ quantizer_scale * quant_matrix[j]) / 16;
+
+ SATURATE (val);
+ dest[j] = val;
+ mismatch ^= val;
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else if (bit_buf >= 0x02000000) {
+ tab = DCT_B14_10 - 8 + UBITS (bit_buf, 10);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00800000) {
+ tab = DCT_13 - 16 + UBITS (bit_buf, 13);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00200000) {
+ tab = DCT_15 - 16 + UBITS (bit_buf, 15);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else {
+ tab = DCT_16 + UBITS (bit_buf, 16);
+ bit_buf <<= 16;
+ GETWORD (bit_buf, bits + 16, bit_ptr);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ }
+ break; /* illegal, check needed to avoid buffer overflow */
+ }
+ dest[63] ^= mismatch & 1;
+ DUMPBITS (bit_buf, bits, 2); /* dump end of block code */
+ picture->bitstream_buf = bit_buf;
+ picture->bitstream_bits = bits;
+ picture->bitstream_ptr = bit_ptr;
+}
+
+static void get_intra_block_B15 (picture_t * picture)
+{
+ int i;
+ int j;
+ int val;
+ uint8_t * scan = picture->scan;
+ uint8_t * quant_matrix = picture->intra_quantizer_matrix;
+ int quantizer_scale = picture->quantizer_scale;
+ int mismatch;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+ int16_t * dest;
+
+ dest = picture->DCTblock;
+ i = 0;
+ mismatch = ~dest[0];
+
+ bit_buf = picture->bitstream_buf;
+ bits = picture->bitstream_bits;
+ bit_ptr = picture->bitstream_ptr;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ while (1) {
+ if (bit_buf >= 0x04000000) {
+
+ tab = DCT_B15_8 - 4 + UBITS (bit_buf, 8);
+
+ i += tab->run;
+ if (i < 64) {
+
+ normal_code:
+ j = scan[i];
+ bit_buf <<= tab->len;
+ bits += tab->len + 1;
+ val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4;
+
+ /* if (bitstream_get (1)) val = -val; */
+ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
+
+ SATURATE (val);
+ dest[j] = val;
+ mismatch ^= val;
+
+ bit_buf <<= 1;
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else {
+
+ /* end of block. I commented out this code because if we */
+ /* dont exit here we will still exit at the later test :) */
+
+ /* if (i >= 128) break; */ /* end of block */
+
+ /* escape code */
+
+ i += UBITS (bit_buf << 6, 6) - 64;
+ if (i >= 64)
+ break; /* illegal, check against buffer overflow */
+
+ j = scan[i];
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ val = (SBITS (bit_buf, 12) *
+ quantizer_scale * quant_matrix[j]) / 16;
+
+ SATURATE (val);
+ dest[j] = val;
+ mismatch ^= val;
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ }
+ } else if (bit_buf >= 0x02000000) {
+ tab = DCT_B15_10 - 8 + UBITS (bit_buf, 10);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00800000) {
+ tab = DCT_13 - 16 + UBITS (bit_buf, 13);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00200000) {
+ tab = DCT_15 - 16 + UBITS (bit_buf, 15);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else {
+ tab = DCT_16 + UBITS (bit_buf, 16);
+ bit_buf <<= 16;
+ GETWORD (bit_buf, bits + 16, bit_ptr);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ }
+ break; /* illegal, check needed to avoid buffer overflow */
+ }
+ dest[63] ^= mismatch & 1;
+ DUMPBITS (bit_buf, bits, 4); /* dump end of block code */
+ picture->bitstream_buf = bit_buf;
+ picture->bitstream_bits = bits;
+ picture->bitstream_ptr = bit_ptr;
+}
+
+static void get_non_intra_block (picture_t * picture)
+{
+ int i;
+ int j;
+ int val;
+ uint8_t * scan = picture->scan;
+ uint8_t * quant_matrix = picture->non_intra_quantizer_matrix;
+ int quantizer_scale = picture->quantizer_scale;
+ int mismatch;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+ int16_t * dest;
+
+ i = -1;
+ mismatch = 1;
+ dest = picture->DCTblock;
+
+ bit_buf = picture->bitstream_buf;
+ bits = picture->bitstream_bits;
+ bit_ptr = picture->bitstream_ptr;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ if (bit_buf >= 0x28000000) {
+ tab = DCT_B14DC_5 - 5 + UBITS (bit_buf, 5);
+ goto entry_1;
+ } else
+ goto entry_2;
+
+ while (1) {
+ if (bit_buf >= 0x28000000) {
+
+ tab = DCT_B14AC_5 - 5 + UBITS (bit_buf, 5);
+
+ entry_1:
+ i += tab->run;
+ if (i >= 64)
+ break; /* end of block */
+
+ normal_code:
+ j = scan[i];
+ bit_buf <<= tab->len;
+ bits += tab->len + 1;
+ val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5;
+
+ /* if (bitstream_get (1)) val = -val; */
+ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
+
+ SATURATE (val);
+ dest[j] = val;
+ mismatch ^= val;
+
+ bit_buf <<= 1;
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ }
+
+ entry_2:
+ if (bit_buf >= 0x04000000) {
+
+ tab = DCT_B14_8 - 4 + UBITS (bit_buf, 8);
+
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+
+ /* escape code */
+
+ i += UBITS (bit_buf << 6, 6) - 64;
+ if (i >= 64)
+ break; /* illegal, check needed to avoid buffer overflow */
+
+ j = scan[i];
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ val = 2 * (SBITS (bit_buf, 12) + SBITS (bit_buf, 1)) + 1;
+ val = (val * quantizer_scale * quant_matrix[j]) / 32;
+
+ SATURATE (val);
+ dest[j] = val;
+ mismatch ^= val;
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else if (bit_buf >= 0x02000000) {
+ tab = DCT_B14_10 - 8 + UBITS (bit_buf, 10);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00800000) {
+ tab = DCT_13 - 16 + UBITS (bit_buf, 13);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00200000) {
+ tab = DCT_15 - 16 + UBITS (bit_buf, 15);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else {
+ tab = DCT_16 + UBITS (bit_buf, 16);
+ bit_buf <<= 16;
+ GETWORD (bit_buf, bits + 16, bit_ptr);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ }
+ break; /* illegal, check needed to avoid buffer overflow */
+ }
+ dest[63] ^= mismatch & 1;
+ DUMPBITS (bit_buf, bits, 2); /* dump end of block code */
+ picture->bitstream_buf = bit_buf;
+ picture->bitstream_bits = bits;
+ picture->bitstream_ptr = bit_ptr;
+}
+
+static void get_mpeg1_intra_block (picture_t * picture)
+{
+ int i;
+ int j;
+ int val;
+ uint8_t * scan = picture->scan;
+ uint8_t * quant_matrix = picture->intra_quantizer_matrix;
+ int quantizer_scale = picture->quantizer_scale;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+ int16_t * dest;
+
+ i = 0;
+ dest = picture->DCTblock;
+
+ bit_buf = picture->bitstream_buf;
+ bits = picture->bitstream_bits;
+ bit_ptr = picture->bitstream_ptr;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ while (1) {
+ if (bit_buf >= 0x28000000) {
+
+ tab = DCT_B14AC_5 - 5 + UBITS (bit_buf, 5);
+
+ i += tab->run;
+ if (i >= 64)
+ break; /* end of block */
+
+ normal_code:
+ j = scan[i];
+ bit_buf <<= tab->len;
+ bits += tab->len + 1;
+ val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4;
+
+ /* oddification */
+ val = (val - 1) | 1;
+
+ /* if (bitstream_get (1)) val = -val; */
+ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
+
+ SATURATE (val);
+ dest[j] = val;
+
+ bit_buf <<= 1;
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else if (bit_buf >= 0x04000000) {
+
+ tab = DCT_B14_8 - 4 + UBITS (bit_buf, 8);
+
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+
+ /* escape code */
+
+ i += UBITS (bit_buf << 6, 6) - 64;
+ if (i >= 64)
+ break; /* illegal, check needed to avoid buffer overflow */
+
+ j = scan[i];
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ val = SBITS (bit_buf, 8);
+ if (! (val & 0x7f)) {
+ DUMPBITS (bit_buf, bits, 8);
+ val = UBITS (bit_buf, 8) + 2 * val;
+ }
+ val = (val * quantizer_scale * quant_matrix[j]) / 16;
+
+ /* oddification */
+ val = (val + ~SBITS (val, 1)) | 1;
+
+ SATURATE (val);
+ dest[j] = val;
+
+ DUMPBITS (bit_buf, bits, 8);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else if (bit_buf >= 0x02000000) {
+ tab = DCT_B14_10 - 8 + UBITS (bit_buf, 10);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00800000) {
+ tab = DCT_13 - 16 + UBITS (bit_buf, 13);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00200000) {
+ tab = DCT_15 - 16 + UBITS (bit_buf, 15);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else {
+ tab = DCT_16 + UBITS (bit_buf, 16);
+ bit_buf <<= 16;
+ GETWORD (bit_buf, bits + 16, bit_ptr);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ }
+ break; /* illegal, check needed to avoid buffer overflow */
+ }
+ DUMPBITS (bit_buf, bits, 2); /* dump end of block code */
+ picture->bitstream_buf = bit_buf;
+ picture->bitstream_bits = bits;
+ picture->bitstream_ptr = bit_ptr;
+}
+
+static void get_mpeg1_non_intra_block (picture_t * picture)
+{
+ int i;
+ int j;
+ int val;
+ uint8_t * scan = picture->scan;
+ uint8_t * quant_matrix = picture->non_intra_quantizer_matrix;
+ int quantizer_scale = picture->quantizer_scale;
+ DCTtab * tab;
+ uint32_t bit_buf;
+ int bits;
+ uint8_t * bit_ptr;
+ int16_t * dest;
+
+ i = -1;
+ dest = picture->DCTblock;
+
+ bit_buf = picture->bitstream_buf;
+ bits = picture->bitstream_bits;
+ bit_ptr = picture->bitstream_ptr;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ if (bit_buf >= 0x28000000) {
+ tab = DCT_B14DC_5 - 5 + UBITS (bit_buf, 5);
+ goto entry_1;
+ } else
+ goto entry_2;
+
+ while (1) {
+ if (bit_buf >= 0x28000000) {
+
+ tab = DCT_B14AC_5 - 5 + UBITS (bit_buf, 5);
+
+ entry_1:
+ i += tab->run;
+ if (i >= 64)
+ break; /* end of block */
+
+ normal_code:
+ j = scan[i];
+ bit_buf <<= tab->len;
+ bits += tab->len + 1;
+ val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5;
+
+ /* oddification */
+ val = (val - 1) | 1;
+
+ /* if (bitstream_get (1)) val = -val; */
+ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1);
+
+ SATURATE (val);
+ dest[j] = val;
+
+ bit_buf <<= 1;
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ }
+
+ entry_2:
+ if (bit_buf >= 0x04000000) {
+
+ tab = DCT_B14_8 - 4 + UBITS (bit_buf, 8);
+
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+
+ /* escape code */
+
+ i += UBITS (bit_buf << 6, 6) - 64;
+ if (i >= 64)
+ break; /* illegal, check needed to avoid buffer overflow */
+
+ j = scan[i];
+
+ DUMPBITS (bit_buf, bits, 12);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ val = SBITS (bit_buf, 8);
+ if (! (val & 0x7f)) {
+ DUMPBITS (bit_buf, bits, 8);
+ val = UBITS (bit_buf, 8) + 2 * val;
+ }
+ val = 2 * (val + SBITS (val, 1)) + 1;
+ val = (val * quantizer_scale * quant_matrix[j]) / 32;
+
+ /* oddification */
+ val = (val + ~SBITS (val, 1)) | 1;
+
+ SATURATE (val);
+ dest[j] = val;
+
+ DUMPBITS (bit_buf, bits, 8);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ continue;
+
+ } else if (bit_buf >= 0x02000000) {
+ tab = DCT_B14_10 - 8 + UBITS (bit_buf, 10);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00800000) {
+ tab = DCT_13 - 16 + UBITS (bit_buf, 13);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else if (bit_buf >= 0x00200000) {
+ tab = DCT_15 - 16 + UBITS (bit_buf, 15);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ } else {
+ tab = DCT_16 + UBITS (bit_buf, 16);
+ bit_buf <<= 16;
+ GETWORD (bit_buf, bits + 16, bit_ptr);
+ i += tab->run;
+ if (i < 64)
+ goto normal_code;
+ }
+ break; /* illegal, check needed to avoid buffer overflow */
+ }
+ DUMPBITS (bit_buf, bits, 2); /* dump end of block code */
+ picture->bitstream_buf = bit_buf;
+ picture->bitstream_bits = bits;
+ picture->bitstream_ptr = bit_ptr;
+}
+
+static inline int get_macroblock_address_increment (picture_t * picture)
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+
+ MBAtab * tab;
+ int mba;
+
+ mba = 0;
+
+ while (1) {
+ if (bit_buf >= 0x10000000) {
+ tab = MBA_5 - 2 + UBITS (bit_buf, 5);
+ DUMPBITS (bit_buf, bits, tab->len);
+ return mba + tab->mba;
+ } else if (bit_buf >= 0x03000000) {
+ tab = MBA_11 - 24 + UBITS (bit_buf, 11);
+ DUMPBITS (bit_buf, bits, tab->len);
+ return mba + tab->mba;
+ } else switch (UBITS (bit_buf, 11)) {
+ case 8: /* macroblock_escape */
+ mba += 33;
+ /* no break here on purpose */
+ case 15: /* macroblock_stuffing (MPEG1 only) */
+ DUMPBITS (bit_buf, bits, 11);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ break;
+ default: /* end of slice, or error */
+ return 0;
+ }
+ }
+
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline void slice_intra_DCT (picture_t * picture, int cc,
+ uint8_t * dest, int stride)
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ /* Get the intra DC coefficient and inverse quantize it */
+ if (cc == 0)
+ picture->dc_dct_pred[0] += get_luma_dc_dct_diff (picture);
+ else
+ picture->dc_dct_pred[cc] += get_chroma_dc_dct_diff (picture);
+ picture->DCTblock[0] =
+ picture->dc_dct_pred[cc] << (3 - picture->intra_dc_precision);
+ memset (picture->DCTblock + 1, 0, 63 * sizeof (int16_t));
+
+ if (picture->mpeg1) {
+ if (picture->picture_coding_type != D_TYPE)
+ get_mpeg1_intra_block (picture);
+ } else if (picture->intra_vlc_format)
+ get_intra_block_B15 (picture);
+ else
+ get_intra_block_B14 (picture);
+ idct_block_copy (picture->DCTblock, dest, stride);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static inline void slice_non_intra_DCT (picture_t * picture, uint8_t * dest,
+ int stride)
+{
+ memset (picture->DCTblock, 0, 64 * sizeof (int16_t));
+ if (picture->mpeg1)
+ get_mpeg1_non_intra_block (picture);
+ else
+ get_non_intra_block (picture);
+ idct_block_add (picture->DCTblock, dest, stride);
+}
+
+#define MOTION_Y(table,offset_x,offset_y,motion_x,motion_y, \
+ dest,src,offset_dest,offset_src,stride,height) \
+do { \
+ int xy_half; \
+ int total_offset; \
+ \
+ xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \
+ total_offset = ((offset_y + (motion_y >> 1)) * stride + \
+ offset_x + (motion_x >> 1) + (offset_src)); \
+ table[xy_half] (dest[0] + offset_x + (offset_dest), \
+ src[0] + total_offset, stride, height); \
+} while (0)
+
+#define MOTION_UV(table,offset_x,offset_y,motion_x,motion_y, \
+ dest,src,offset_dest,offset_src,stride,height) \
+do { \
+ int xy_half; \
+ int total_offset; \
+ \
+ xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \
+ total_offset = (((offset_y + motion_y) >> 1) * (stride) + \
+ ((offset_x + motion_x) >> 1) + (offset_src)); \
+ table[4+xy_half] (dest[1] + (offset_x >> 1) + (offset_dest), \
+ src[1] + total_offset, stride, height); \
+ table[4+xy_half] (dest[2] + (offset_x >> 1) + (offset_dest), \
+ src[2] + total_offset, stride, height); \
+} while (0)
+
+static inline void motion_block (void (** table) (uint8_t *, uint8_t *,
+ int32_t, int32_t),
+ int x_offset, int y_offset, int mb_y_8_offset,
+ int src_field, int dest_field,
+ int x_pred, int y_pred,
+ uint8_t * dest[3], uint8_t * src[3],
+ int stride, int height)
+{
+ MOTION_Y (table, x_offset, y_offset, x_pred, y_pred, dest, src,
+ dest_field + mb_y_8_offset*8*stride, src_field, stride, height);
+
+ x_pred /= 2;
+ y_pred /= 2;
+ stride >>= 1;
+ height >>= 1;
+
+ MOTION_UV (table, x_offset, y_offset, x_pred, y_pred, dest, src,
+ (dest_field >> 1) + mb_y_8_offset*4*stride, src_field >> 1,
+ stride, height);
+}
+
+static void motion_mp1 (picture_t * picture, motion_t * motion,
+ uint8_t * dest[3], int offset, int stride,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ int motion_x, motion_y;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[0][0] + get_motion_delta (picture,
+ motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = motion->pmv[0][1] + get_motion_delta (picture,
+ motion->f_code[0]);
+ motion_y = bound_motion_vector (motion_y, motion->f_code[0]);
+ motion->pmv[0][1] = motion_y;
+
+ if (motion->f_code[1]) {
+ motion_x <<= 1;
+ motion_y <<= 1;
+ }
+
+ motion_block (table, offset, picture->v_offset, 0, 0, 0,
+ motion_x, motion_y, dest, motion->ref[0], stride, 16);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static void motion_mp1_reuse (picture_t * picture, motion_t * motion,
+ uint8_t * dest[3], int offset, int stride,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+ int motion_x, motion_y;
+
+ motion_x = motion->pmv[0][0];
+ motion_y = motion->pmv[0][1];
+
+ if (motion->f_code[1]) {
+ motion_x <<= 1;
+ motion_y <<= 1;
+ }
+
+ motion_block (table, offset, picture->v_offset, 0, 0, 0,
+ motion_x, motion_y, dest, motion->ref[0], stride, 16);
+}
+
+static void motion_fr_frame (picture_t * picture, motion_t * motion,
+ uint8_t * dest[3], int offset, int stride,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ int motion_x, motion_y;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[0][0] + get_motion_delta (picture,
+ motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[1][0] = motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = motion->pmv[0][1] + get_motion_delta (picture,
+ motion->f_code[1]);
+ motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
+ motion->pmv[1][1] = motion->pmv[0][1] = motion_y;
+
+ motion_block (table, offset, picture->v_offset, 0, 0, 0,
+ motion_x, motion_y, dest, motion->ref[0], stride, 16);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static void motion_fr_field (picture_t * picture, motion_t * motion,
+ uint8_t * dest[3], int offset, int stride,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ int motion_x, motion_y;
+ int field_select;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ field_select = SBITS (bit_buf, 1);
+ DUMPBITS (bit_buf, bits, 1);
+
+ motion_x = motion->pmv[0][0] + get_motion_delta (picture,
+ motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = (motion->pmv[0][1] >> 1) + get_motion_delta (picture,
+ motion->f_code[1]);
+ /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */
+ motion->pmv[0][1] = motion_y << 1;
+
+ motion_block (table, offset, picture->v_offset >> 1,
+ 0, (field_select & stride), 0,
+ motion_x, motion_y, dest, motion->ref[0], stride * 2, 8);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ field_select = SBITS (bit_buf, 1);
+ DUMPBITS (bit_buf, bits, 1);
+
+ motion_x = motion->pmv[1][0] + get_motion_delta (picture,
+ motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[1][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = (motion->pmv[1][1] >> 1) + get_motion_delta (picture,
+ motion->f_code[1]);
+ /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */
+ motion->pmv[1][1] = motion_y << 1;
+
+ motion_block (table, offset, picture->v_offset >> 1,
+ 0, (field_select & stride), stride,
+ motion_x, motion_y, dest, motion->ref[0], stride * 2, 8);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static void motion_fr_dmv (picture_t * picture, motion_t * motion,
+ uint8_t * dest[3], int offset, int stride,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ int motion_x, motion_y;
+ int dmv_x, dmv_y;
+ int m;
+ int other_x, other_y;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[0][0] + get_motion_delta (picture,
+ motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[1][0] = motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ dmv_x = get_dmv (picture);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = (motion->pmv[0][1] >> 1) + get_motion_delta (picture,
+ motion->f_code[1]);
+ /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */
+ motion->pmv[1][1] = motion->pmv[0][1] = motion_y << 1;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ dmv_y = get_dmv (picture);
+
+ motion_block (mc_functions.put, offset, picture->v_offset >> 1, 0, 0, 0,
+ motion_x, motion_y, dest, motion->ref[0], stride * 2, 8);
+
+ m = picture->top_field_first ? 1 : 3;
+ other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x;
+ other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y - 1;
+ motion_block (mc_functions.avg, offset, picture->v_offset >> 1, 0, stride, 0,
+ other_x, other_y, dest, motion->ref[0], stride * 2, 8);
+
+ motion_block (mc_functions.put, offset, picture->v_offset >> 1,
+ 0, stride, stride,
+ motion_x, motion_y, dest, motion->ref[0], stride * 2, 8);
+
+ m = picture->top_field_first ? 3 : 1;
+ other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x;
+ other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y + 1;
+ motion_block (mc_functions.avg, offset, picture->v_offset >> 1, 0, 0, stride,
+ other_x, other_y, dest, motion->ref[0], stride * 2, 8);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+/* like motion_frame, but reuse previous motion vectors */
+static void motion_fr_reuse (picture_t * picture, motion_t * motion,
+ uint8_t * dest[3], int offset, int stride,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+ motion_block (table, offset, picture->v_offset, 0, 0, 0,
+ motion->pmv[0][0], motion->pmv[0][1],
+ dest, motion->ref[0], stride, 16);
+}
+
+/* like motion_frame, but use null motion vectors */
+static void motion_fr_zero (picture_t * picture, motion_t * motion,
+ uint8_t * dest[3], int offset, int stride,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+ motion_block (table, offset, picture->v_offset, 0, 0, 0, 0, 0,
+ dest, motion->ref[0], stride, 16);
+}
+
+/* like motion_frame, but parsing without actual motion compensation */
+static void motion_fr_conceal (picture_t * picture)
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ int tmp;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ tmp = (picture->f_motion.pmv[0][0] +
+ get_motion_delta (picture, picture->f_motion.f_code[0]));
+ tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]);
+ picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ tmp = (picture->f_motion.pmv[0][1] +
+ get_motion_delta (picture, picture->f_motion.f_code[1]));
+ tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]);
+ picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp;
+
+ DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static void motion_fi_field (picture_t * picture, motion_t * motion,
+ uint8_t * dest[3], int offset, int stride,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ int motion_x, motion_y;
+ int field_select;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ field_select = UBITS (bit_buf, 1);
+ DUMPBITS (bit_buf, bits, 1);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[0][0] + get_motion_delta (picture,
+ motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[1][0] = motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = motion->pmv[0][1] + get_motion_delta (picture,
+ motion->f_code[1]);
+ motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
+ motion->pmv[1][1] = motion->pmv[0][1] = motion_y;
+
+ motion_block (table, offset, picture->v_offset, 0, 0, 0,
+ motion_x, motion_y,
+ dest, motion->ref[field_select], stride, 16);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static void motion_fi_16x8 (picture_t * picture, motion_t * motion,
+ uint8_t * dest[3], int offset, int stride,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ int motion_x, motion_y;
+ int field_select;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ field_select = UBITS (bit_buf, 1);
+ DUMPBITS (bit_buf, bits, 1);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[0][0] + get_motion_delta (picture,
+ motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = motion->pmv[0][1] + get_motion_delta (picture,
+ motion->f_code[1]);
+ motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
+ motion->pmv[0][1] = motion_y;
+
+ motion_block (table, offset, picture->v_offset, 0, 0, 0,
+ motion_x, motion_y,
+ dest, motion->ref[field_select], stride, 8);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ field_select = UBITS (bit_buf, 1);
+ DUMPBITS (bit_buf, bits, 1);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[1][0] + get_motion_delta (picture,
+ motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[1][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = motion->pmv[1][1] + get_motion_delta (picture,
+ motion->f_code[1]);
+ motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
+ motion->pmv[1][1] = motion_y;
+
+ motion_block (table, offset, picture->v_offset+8, 1, 0, 0,
+ motion_x, motion_y,
+ dest, motion->ref[field_select], stride, 8);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static void motion_fi_dmv (picture_t * picture, motion_t * motion,
+ uint8_t * dest[3], int offset, int stride,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ int motion_x, motion_y;
+ int dmv_x, dmv_y;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_x = motion->pmv[0][0] + get_motion_delta (picture,
+ motion->f_code[0]);
+ motion_x = bound_motion_vector (motion_x, motion->f_code[0]);
+ motion->pmv[1][0] = motion->pmv[0][0] = motion_x;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ dmv_x = get_dmv (picture);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ motion_y = motion->pmv[0][1] + get_motion_delta (picture,
+ motion->f_code[1]);
+ motion_y = bound_motion_vector (motion_y, motion->f_code[1]);
+ motion->pmv[1][1] = motion->pmv[0][1] = motion_y;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ dmv_y = get_dmv (picture);
+
+ motion_block (mc_functions.put, offset, picture->v_offset, 0, 0, 0,
+ motion_x, motion_y,
+ dest, motion->ref[picture->current_field], stride, 16);
+
+ motion_x = ((motion_x + (motion_x > 0)) >> 1) + dmv_x;
+ motion_y = ((motion_y + (motion_y > 0)) >> 1) + dmv_y +
+ 2 * picture->current_field - 1;
+ motion_block (mc_functions.avg, offset, picture->v_offset, 0, 0, 0,
+ motion_x, motion_y,
+ dest, motion->ref[!picture->current_field], stride, 16);
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+static void motion_fi_reuse (picture_t * picture, motion_t * motion,
+ uint8_t * dest[3], int offset, int stride,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+ motion_block (table, offset, picture->v_offset, 0, 0, 0,
+ motion->pmv[0][0], motion->pmv[0][1],
+ dest, motion->ref[picture->current_field], stride, 16);
+}
+
+static void motion_fi_zero (picture_t * picture, motion_t * motion,
+ uint8_t * dest[3], int offset, int stride,
+ void (** table) (uint8_t *, uint8_t *, int, int))
+{
+ motion_block (table, offset, picture->v_offset, 0, 0, 0, 0, 0,
+ dest, motion->ref[picture->current_field], stride, 16);
+}
+
+static void motion_fi_conceal (picture_t * picture)
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ int tmp;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ DUMPBITS (bit_buf, bits, 1); /* remove field_select */
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ tmp = (picture->f_motion.pmv[0][0] +
+ get_motion_delta (picture, picture->f_motion.f_code[0]));
+ tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]);
+ picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ tmp = (picture->f_motion.pmv[0][1] +
+ get_motion_delta (picture, picture->f_motion.f_code[1]));
+ tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]);
+ picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp;
+
+ DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
+
+#define MOTION(routine,direction) \
+do { \
+ if ((direction) & MACROBLOCK_MOTION_FORWARD) \
+ routine (picture, &(picture->f_motion), dest, offset, stride, \
+ mc_functions.put); \
+ if ((direction) & MACROBLOCK_MOTION_BACKWARD) \
+ routine (picture, &(picture->b_motion), dest, offset, stride, \
+ ((direction) & MACROBLOCK_MOTION_FORWARD ? \
+ mc_functions.avg : mc_functions.put)); \
+} while (0)
+
+#define CHECK_DISPLAY \
+do { \
+ if (offset == picture->coded_picture_width) { \
+ do { /* just so we can use the break statement */ \
+ if (picture->current_frame->copy) { \
+ picture->current_frame->copy (picture->current_frame, \
+ dest); \
+ if (picture->picture_coding_type == B_TYPE) \
+ break; \
+ } \
+ dest[0] += 16 * stride; \
+ dest[1] += 4 * stride; \
+ dest[2] += 4 * stride; \
+ } while (0); \
+ if (! (picture->mpeg1)) \
+ return 0; \
+ picture->v_offset += 16; \
+ if (picture->v_offset >= picture->coded_picture_height) \
+ return 0; \
+ offset = 0; \
+ } \
+} while (0)
+
+int slice_process (picture_t * picture, uint8_t code, uint8_t * buffer)
+{
+#define bit_buf (picture->bitstream_buf)
+#define bits (picture->bitstream_bits)
+#define bit_ptr (picture->bitstream_ptr)
+ int macroblock_modes;
+ int stride;
+ uint8_t * dest[3];
+ int offset;
+ uint8_t ** forward_ref[2];
+
+ stride = picture->coded_picture_width;
+ offset = (code - 1) * stride * 4;
+ picture->v_offset = (code - 1) * 16;
+
+ forward_ref[0] = picture->forward_reference_frame->base;
+ if (picture->picture_structure != FRAME_PICTURE) {
+ forward_ref[1] = picture->forward_reference_frame->base;
+ offset <<= 1;
+ picture->current_field = (picture->picture_structure == BOTTOM_FIELD);
+ if ((picture->second_field) &&
+ (picture->picture_coding_type != B_TYPE))
+ forward_ref[picture->picture_structure == TOP_FIELD] =
+ picture->current_frame->base;
+
+ picture->f_motion.ref[1][0] = forward_ref[1][0] + stride;
+ picture->f_motion.ref[1][1] = forward_ref[1][1] + (stride >> 1);
+ picture->f_motion.ref[1][2] = forward_ref[1][2] + (stride >> 1);
+
+ picture->b_motion.ref[1][0] =
+ picture->backward_reference_frame->base[0] + stride;
+ picture->b_motion.ref[1][1] =
+ picture->backward_reference_frame->base[1] + (stride >> 1);
+ picture->b_motion.ref[1][2] =
+ picture->backward_reference_frame->base[2] + (stride >> 1);
+ }
+
+ picture->f_motion.ref[0][0] = forward_ref[0][0];
+ picture->f_motion.ref[0][1] = forward_ref[0][1];
+ picture->f_motion.ref[0][2] = forward_ref[0][2];
+
+ picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0;
+ picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0;
+
+ picture->b_motion.ref[0][0] = picture->backward_reference_frame->base[0];
+ picture->b_motion.ref[0][1] = picture->backward_reference_frame->base[1];
+ picture->b_motion.ref[0][2] = picture->backward_reference_frame->base[2];
+
+ picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0;
+ picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0;
+
+ if ((picture->current_frame->copy) &&
+ (picture->picture_coding_type == B_TYPE))
+ offset = 0;
+
+ dest[0] = picture->current_frame->base[0] + offset * 4;
+ dest[1] = picture->current_frame->base[1] + offset;
+ dest[2] = picture->current_frame->base[2] + offset;
+
+ switch (picture->picture_structure) {
+ case BOTTOM_FIELD:
+ dest[0] += stride;
+ dest[1] += stride >> 1;
+ dest[2] += stride >> 1;
+ /* follow thru */
+ case TOP_FIELD:
+ stride <<= 1;
+ }
+
+ picture->dc_dct_pred[0] = picture->dc_dct_pred[1] =
+ picture->dc_dct_pred[2] = 1 << (picture->intra_dc_precision + 7);
+
+ bitstream_init (picture, buffer);
+
+ picture->quantizer_scale = get_quantizer_scale (picture);
+
+ /* ignore intra_slice and all the extra data */
+ while (bit_buf & 0x80000000) {
+ DUMPBITS (bit_buf, bits, 9);
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ }
+ DUMPBITS (bit_buf, bits, 1);
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ offset = get_macroblock_address_increment (picture) << 4;
+
+ while (1) {
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ macroblock_modes = get_macroblock_modes (picture);
+
+ /* maybe integrate MACROBLOCK_QUANT test into get_macroblock_modes ? */
+ if (macroblock_modes & MACROBLOCK_QUANT)
+ picture->quantizer_scale = get_quantizer_scale (picture);
+
+ if (macroblock_modes & MACROBLOCK_INTRA) {
+
+ int DCT_offset, DCT_stride;
+
+ if (picture->concealment_motion_vectors) {
+ if (picture->picture_structure == FRAME_PICTURE)
+ motion_fr_conceal (picture);
+ else
+ motion_fi_conceal (picture);
+ } else {
+ picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0;
+ picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0;
+ picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0;
+ picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0;
+ }
+
+ if (macroblock_modes & DCT_TYPE_INTERLACED) {
+ DCT_offset = stride;
+ DCT_stride = stride * 2;
+ } else {
+ DCT_offset = stride * 8;
+ DCT_stride = stride;
+ }
+
+ slice_intra_DCT (picture, 0, dest[0] + offset, DCT_stride);
+ slice_intra_DCT (picture, 0, dest[0] + offset + 8, DCT_stride);
+ slice_intra_DCT (picture, 0, dest[0] + offset + DCT_offset,
+ DCT_stride);
+ slice_intra_DCT (picture, 0, dest[0] + offset + DCT_offset + 8,
+ DCT_stride);
+
+ slice_intra_DCT (picture, 1, dest[1] + (offset >> 1), stride >> 1);
+ slice_intra_DCT (picture, 2, dest[2] + (offset >> 1), stride >> 1);
+
+ if (picture->picture_coding_type == D_TYPE) {
+ NEEDBITS (bit_buf, bits, bit_ptr);
+ DUMPBITS (bit_buf, bits, 1);
+ }
+ } else {
+
+ if (picture->mpeg1) {
+ if ((macroblock_modes & MOTION_TYPE_MASK) == MC_FRAME)
+ MOTION (motion_mp1, macroblock_modes);
+ else {
+ /* non-intra mb without forward mv in a P picture */
+ picture->f_motion.pmv[0][0] = 0;
+ picture->f_motion.pmv[0][1] = 0;
+ picture->f_motion.pmv[1][0] = 0;
+ picture->f_motion.pmv[1][1] = 0;
+ MOTION (motion_fr_zero, MACROBLOCK_MOTION_FORWARD);
+ }
+ } else if (picture->picture_structure == FRAME_PICTURE)
+ switch (macroblock_modes & MOTION_TYPE_MASK) {
+ case MC_FRAME:
+ MOTION (motion_fr_frame, macroblock_modes);
+ break;
+
+ case MC_FIELD:
+ MOTION (motion_fr_field, macroblock_modes);
+ break;
+
+ case MC_DMV:
+ MOTION (motion_fr_dmv, MACROBLOCK_MOTION_FORWARD);
+ break;
+
+ case 0:
+ /* non-intra mb without forward mv in a P picture */
+ picture->f_motion.pmv[0][0] = 0;
+ picture->f_motion.pmv[0][1] = 0;
+ picture->f_motion.pmv[1][0] = 0;
+ picture->f_motion.pmv[1][1] = 0;
+ MOTION (motion_fr_zero, MACROBLOCK_MOTION_FORWARD);
+ break;
+ }
+ else
+ switch (macroblock_modes & MOTION_TYPE_MASK) {
+ case MC_FIELD:
+ MOTION (motion_fi_field, macroblock_modes);
+ break;
+
+ case MC_16X8:
+ MOTION (motion_fi_16x8, macroblock_modes);
+ break;
+
+ case MC_DMV:
+ MOTION (motion_fi_dmv, MACROBLOCK_MOTION_FORWARD);
+ break;
+
+ case 0:
+ /* non-intra mb without forward mv in a P picture */
+ picture->f_motion.pmv[0][0] = 0;
+ picture->f_motion.pmv[0][1] = 0;
+ picture->f_motion.pmv[1][0] = 0;
+ picture->f_motion.pmv[1][1] = 0;
+ MOTION (motion_fi_zero, MACROBLOCK_MOTION_FORWARD);
+ break;
+ }
+
+ if (macroblock_modes & MACROBLOCK_PATTERN) {
+ int coded_block_pattern;
+ int DCT_offset, DCT_stride;
+
+ if (macroblock_modes & DCT_TYPE_INTERLACED) {
+ DCT_offset = stride;
+ DCT_stride = stride * 2;
+ } else {
+ DCT_offset = stride * 8;
+ DCT_stride = stride;
+ }
+
+ coded_block_pattern = get_coded_block_pattern (picture);
+
+ if (coded_block_pattern & 0x20)
+ slice_non_intra_DCT (picture, dest[0] + offset,
+ DCT_stride);
+ if (coded_block_pattern & 0x10)
+ slice_non_intra_DCT (picture, dest[0] + offset + 8,
+ DCT_stride);
+ if (coded_block_pattern & 0x08)
+ slice_non_intra_DCT (picture,
+ dest[0] + offset + DCT_offset,
+ DCT_stride);
+ if (coded_block_pattern & 0x04)
+ slice_non_intra_DCT (picture,
+ dest[0] + offset + DCT_offset + 8,
+ DCT_stride);
+
+ if (coded_block_pattern & 0x2)
+ slice_non_intra_DCT (picture, dest[1] + (offset >> 1),
+ stride >> 1);
+ if (coded_block_pattern & 0x1)
+ slice_non_intra_DCT (picture, dest[2] + (offset >> 1),
+ stride >> 1);
+ }
+
+ picture->dc_dct_pred[0] = picture->dc_dct_pred[1] =
+ picture->dc_dct_pred[2] = 1 << (picture->intra_dc_precision+7);
+ }
+
+ offset += 16;
+ CHECK_DISPLAY;
+
+ NEEDBITS (bit_buf, bits, bit_ptr);
+
+ if (bit_buf & 0x80000000) {
+ DUMPBITS (bit_buf, bits, 1);
+ } else {
+ int mba_inc;
+
+ mba_inc = get_macroblock_address_increment (picture);
+ if (!mba_inc)
+ break;
+
+ picture->dc_dct_pred[0] = picture->dc_dct_pred[1] =
+ picture->dc_dct_pred[2] = 1 << (picture->intra_dc_precision+7);
+
+ if (picture->picture_coding_type == P_TYPE) {
+ picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0;
+ picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0;
+
+ do {
+ if (picture->picture_structure == FRAME_PICTURE)
+ MOTION (motion_fr_zero, MACROBLOCK_MOTION_FORWARD);
+ else
+ MOTION (motion_fi_zero, MACROBLOCK_MOTION_FORWARD);
+
+ offset += 16;
+ CHECK_DISPLAY;
+ } while (--mba_inc);
+ } else {
+ do {
+ if (picture->mpeg1)
+ MOTION (motion_mp1_reuse, macroblock_modes);
+ else if (picture->picture_structure == FRAME_PICTURE)
+ MOTION (motion_fr_reuse, macroblock_modes);
+ else
+ MOTION (motion_fi_reuse, macroblock_modes);
+
+ offset += 16;
+ CHECK_DISPLAY;
+ } while (--mba_inc);
+ }
+ }
+ }
+
+ return 0;
+#undef bit_buf
+#undef bits
+#undef bit_ptr
+}
diff --git a/src/libmpeg2/stats.c b/src/libmpeg2/stats.c
new file mode 100644
index 000000000..f3456058d
--- /dev/null
+++ b/src/libmpeg2/stats.c
@@ -0,0 +1,315 @@
+/*
+ * stats.c
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "mpeg2_internal.h"
+
+static int debug_level = -1;
+
+/* Determine is debug output is required. */
+/* We could potentially have multiple levels of debug info */
+static int debug_is_on (void)
+{
+ char * env_var;
+
+ if (debug_level < 0) {
+ env_var = getenv ("MPEG2_DEBUG");
+
+ if (env_var)
+ debug_level = 1;
+ else
+ debug_level = 0;
+ }
+
+ return debug_level;
+}
+
+static void stats_picture (uint8_t * buffer)
+{
+ static char * picture_coding_type_str [8] = {
+ "Invalid picture type",
+ "I-type",
+ "P-type",
+ "B-type",
+ "D (very bad)",
+ "Invalid","Invalid","Invalid"
+ };
+
+ int picture_coding_type;
+ int temporal_reference;
+ int vbv_delay;
+
+ temporal_reference = (buffer[0] << 2) | (buffer[1] >> 6);
+ picture_coding_type = (buffer [1] >> 3) & 7;
+ vbv_delay = ((buffer[1] << 13) | (buffer[2] << 5) |
+ (buffer[3] >> 3)) & 0xffff;
+
+ fprintf (stderr, " (picture) %s temporal_reference %d, vbv_delay %d\n",
+ picture_coding_type_str [picture_coding_type],
+ temporal_reference, vbv_delay);
+}
+
+static void stats_user_data (uint8_t * buffer)
+{
+ fprintf (stderr, " (user_data)\n");
+}
+
+static void stats_sequence (uint8_t * buffer)
+{
+ static char * aspect_ratio_information_str[8] = {
+ "Invalid Aspect Ratio",
+ "1:1",
+ "4:3",
+ "16:9",
+ "2.21:1",
+ "Invalid Aspect Ratio",
+ "Invalid Aspect Ratio",
+ "Invalid Aspect Ratio"
+ };
+ static char * frame_rate_str[16] = {
+ "Invalid frame_rate_code",
+ "23.976", "24", "25" , "29.97",
+ "30" , "50", "59.94", "60" ,
+ "Invalid frame_rate_code", "Invalid frame_rate_code",
+ "Invalid frame_rate_code", "Invalid frame_rate_code",
+ "Invalid frame_rate_code", "Invalid frame_rate_code",
+ "Invalid frame_rate_code"
+ };
+
+ int horizontal_size;
+ int vertical_size;
+ int aspect_ratio_information;
+ int frame_rate_code;
+ int bit_rate_value;
+ int vbv_buffer_size_value;
+ int constrained_parameters_flag;
+ int load_intra_quantizer_matrix;
+ int load_non_intra_quantizer_matrix;
+
+ vertical_size = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
+ horizontal_size = vertical_size >> 12;
+ vertical_size &= 0xfff;
+ aspect_ratio_information = buffer[3] >> 4;
+ frame_rate_code = buffer[3] & 15;
+ bit_rate_value = (buffer[4] << 10) | (buffer[5] << 2) | (buffer[6] >> 6);
+ vbv_buffer_size_value = ((buffer[6] << 5) | (buffer[7] >> 3)) & 0x3ff;
+ constrained_parameters_flag = buffer[7] & 4;
+ load_intra_quantizer_matrix = buffer[7] & 2;
+ if (load_intra_quantizer_matrix)
+ buffer += 64;
+ load_non_intra_quantizer_matrix = buffer[7] & 1;
+
+ fprintf (stderr, " (seq) %dx%d %s, %s fps, %5.0f kbps, VBV %d kB%s%s%s\n",
+ horizontal_size, vertical_size,
+ aspect_ratio_information_str [aspect_ratio_information],
+ frame_rate_str [frame_rate_code],
+ bit_rate_value * 400.0 / 1000.0,
+ 2 * vbv_buffer_size_value,
+ constrained_parameters_flag ? " , CP":"",
+ load_intra_quantizer_matrix ? " , Custom Intra Matrix":"",
+ load_non_intra_quantizer_matrix ? " , Custom Non-Intra Matrix":"");
+}
+
+static void stats_sequence_error (uint8_t * buffer)
+{
+ fprintf (stderr, " (sequence_error)\n");
+}
+
+static void stats_sequence_end (uint8_t * buffer)
+{
+ fprintf (stderr, " (sequence_end)\n");
+}
+
+static void stats_group (uint8_t * buffer)
+{
+ fprintf (stderr, " (group)%s%s\n",
+ (buffer[4] & 0x40) ? " closed_gop" : "",
+ (buffer[4] & 0x20) ? " broken_link" : "");
+}
+
+static void stats_slice (uint8_t code, uint8_t * buffer)
+{
+ /* fprintf (stderr, " (slice %d)\n", code); */
+}
+
+static void stats_sequence_extension (uint8_t * buffer)
+{
+ static char * chroma_format_str[4] = {
+ "Invalid Chroma Format",
+ "4:2:0 Chroma",
+ "4:2:2 Chroma",
+ "4:4:4 Chroma"
+ };
+
+ int progressive_sequence;
+ int chroma_format;
+
+ progressive_sequence = (buffer[1] >> 3) & 1;
+ chroma_format = (buffer[1] >> 1) & 3;
+
+ fprintf (stderr, " (seq_ext) progressive_sequence %d, %s\n",
+ progressive_sequence, chroma_format_str [chroma_format]);
+}
+
+static void stats_sequence_display_extension (uint8_t * buffer)
+{
+ fprintf (stderr, " (sequence_display_extension)\n");
+}
+
+static void stats_quant_matrix_extension (uint8_t * buffer)
+{
+ fprintf (stderr, " (quant_matrix_extension)\n");
+}
+
+static void stats_copyright_extension (uint8_t * buffer)
+{
+ fprintf (stderr, " (copyright_extension)\n");
+}
+
+
+static void stats_sequence_scalable_extension (uint8_t * buffer)
+{
+ fprintf (stderr, " (sequence_scalable_extension)\n");
+}
+
+static void stats_picture_display_extension (uint8_t * buffer)
+{
+ fprintf (stderr, " (picture_display_extension)\n");
+}
+
+static void stats_picture_coding_extension (uint8_t * buffer)
+{
+ static char * picture_structure_str[4] = {
+ "Invalid Picture Structure",
+ "Top field",
+ "Bottom field",
+ "Frame Picture"
+ };
+
+ int f_code[2][2];
+ int intra_dc_precision;
+ int picture_structure;
+ int top_field_first;
+ int frame_pred_frame_dct;
+ int concealment_motion_vectors;
+ int q_scale_type;
+ int intra_vlc_format;
+ int alternate_scan;
+ int repeat_first_field;
+ int progressive_frame;
+
+ f_code[0][0] = buffer[0] & 15;
+ f_code[0][1] = buffer[1] >> 4;
+ f_code[1][0] = buffer[1] & 15;
+ f_code[1][1] = buffer[2] >> 4;
+ intra_dc_precision = (buffer[2] >> 2) & 3;
+ picture_structure = buffer[2] & 3;
+ top_field_first = buffer[3] >> 7;
+ frame_pred_frame_dct = (buffer[3] >> 6) & 1;
+ concealment_motion_vectors = (buffer[3] >> 5) & 1;
+ q_scale_type = (buffer[3] >> 4) & 1;
+ intra_vlc_format = (buffer[3] >> 3) & 1;
+ alternate_scan = (buffer[3] >> 2) & 1;
+ repeat_first_field = (buffer[3] >> 1) & 1;
+ progressive_frame = buffer[4] >> 7;
+
+ fprintf (stderr,
+ " (pic_ext) %s\n", picture_structure_str [picture_structure]);
+ fprintf (stderr,
+ " (pic_ext) forward horizontal f_code % d, forward vertical f_code % d\n",
+ f_code[0][0], f_code[0][1]);
+ fprintf (stderr,
+ " (pic_ext) backward horizontal f_code % d, backward vertical f_code % d\n",
+ f_code[1][0], f_code[1][1]);
+ fprintf (stderr,
+ " (pic_ext) intra_dc_precision %d, top_field_first %d, frame_pred_frame_dct %d\n",
+ intra_dc_precision, top_field_first, frame_pred_frame_dct);
+ fprintf (stderr,
+ " (pic_ext) concealment_motion_vectors %d, q_scale_type %d, intra_vlc_format %d\n",
+ concealment_motion_vectors, q_scale_type, intra_vlc_format);
+ fprintf (stderr,
+ " (pic_ext) alternate_scan %d, repeat_first_field %d, progressive_frame %d\n",
+ alternate_scan, repeat_first_field, progressive_frame);
+}
+
+void stats_header (uint8_t code, uint8_t * buffer)
+{
+ if (! (debug_is_on ()))
+ return;
+
+ switch (code) {
+ case 0x00:
+ stats_picture (buffer);
+ break;
+ case 0xb2:
+ stats_user_data (buffer);
+ break;
+ case 0xb3:
+ stats_sequence (buffer);
+ break;
+ case 0xb4:
+ stats_sequence_error (buffer);
+ break;
+ case 0xb5:
+ switch (buffer[0] >> 4) {
+ case 1:
+ stats_sequence_extension (buffer);
+ break;
+ case 2:
+ stats_sequence_display_extension (buffer);
+ break;
+ case 3:
+ stats_quant_matrix_extension (buffer);
+ break;
+ case 4:
+ stats_copyright_extension (buffer);
+ break;
+ case 5:
+ stats_sequence_scalable_extension (buffer);
+ break;
+ case 7:
+ stats_picture_display_extension (buffer);
+ break;
+ case 8:
+ stats_picture_coding_extension (buffer);
+ break;
+ default:
+ fprintf (stderr, " (unknown extension %#x)\n", buffer[0] >> 4);
+ }
+ break;
+ case 0xb7:
+ stats_sequence_end (buffer);
+ break;
+ case 0xb8:
+ stats_group (buffer);
+ break;
+ default:
+ if (code < 0xb0)
+ stats_slice (code, buffer);
+ else
+ fprintf (stderr, " (unknown start code %#02x)\n", code);
+ }
+}
diff --git a/src/libmpeg2/vlc.h b/src/libmpeg2/vlc.h
new file mode 100644
index 000000000..ed2e04f88
--- /dev/null
+++ b/src/libmpeg2/vlc.h
@@ -0,0 +1,425 @@
+/*
+ * vlc.h
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define GETWORD(bit_buf,shift,bit_ptr) \
+do { \
+ bit_buf |= ((bit_ptr[0] << 8) | bit_ptr[1]) << (shift); \
+ bit_ptr += 2; \
+} while (0)
+
+static inline void bitstream_init (picture_t * picture, uint8_t * start)
+{
+ picture->bitstream_buf = 0; GETWORD (picture->bitstream_buf, 16, start);
+ picture->bitstream_ptr = start;
+ picture->bitstream_bits = 0;
+}
+
+/* make sure that there are at least 16 valid bits in bit_buf */
+#define NEEDBITS(bit_buf,bits,bit_ptr) \
+do { \
+ if (bits > 0) { \
+ GETWORD (bit_buf, bits, bit_ptr); \
+ bits -= 16; \
+ } \
+} while (0)
+
+/* remove num valid bits from bit_buf */
+#define DUMPBITS(bit_buf,bits,num) \
+do { \
+ bit_buf <<= (num); \
+ bits += (num); \
+} while (0)
+
+/* take num bits from the high part of bit_buf and zero extend them */
+#define UBITS(bit_buf,num) (((uint32_t)(bit_buf)) >> (32 - (num)))
+
+/* take num bits from the high part of bit_buf and sign extend them */
+#define SBITS(bit_buf,num) (((int32_t)(bit_buf)) >> (32 - (num)))
+
+typedef struct {
+ uint8_t modes;
+ uint8_t len;
+} MBtab;
+
+typedef struct {
+ uint8_t delta;
+ uint8_t len;
+} MVtab;
+
+typedef struct {
+ int8_t dmv;
+ uint8_t len;
+} DMVtab;
+
+typedef struct {
+ uint8_t cbp;
+ uint8_t len;
+} CBPtab;
+
+typedef struct {
+ uint8_t size;
+ uint8_t len;
+} DCtab;
+
+typedef struct {
+ uint8_t run;
+ uint8_t level;
+ uint8_t len;
+} DCTtab;
+
+typedef struct {
+ uint8_t mba;
+ uint8_t len;
+} MBAtab;
+
+
+#define INTRA MACROBLOCK_INTRA
+#define QUANT MACROBLOCK_QUANT
+
+static MBtab MB_I [] = {
+ {INTRA|QUANT, 2}, {INTRA, 1}
+};
+
+#define MC MACROBLOCK_MOTION_FORWARD
+#define CODED MACROBLOCK_PATTERN
+
+static MBtab MB_P [] = {
+ {INTRA|QUANT, 6}, {CODED|QUANT, 5}, {MC|CODED|QUANT, 5}, {INTRA, 5},
+ {MC, 3}, {MC, 3}, {MC, 3}, {MC, 3},
+ {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2},
+ {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2},
+ {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
+ {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
+ {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1},
+ {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}
+};
+
+#define FWD MACROBLOCK_MOTION_FORWARD
+#define BWD MACROBLOCK_MOTION_BACKWARD
+#define INTER MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD
+
+static MBtab MB_B [] = {
+ {0, 0}, {INTRA|QUANT, 6},
+ {BWD|CODED|QUANT, 6}, {FWD|CODED|QUANT, 6},
+ {INTER|CODED|QUANT, 5}, {INTER|CODED|QUANT, 5},
+ {INTRA, 5}, {INTRA, 5},
+ {FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD, 4},
+ {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4},
+ {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3},
+ {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3},
+ {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3},
+ {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3},
+ {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
+ {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
+ {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
+ {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2},
+ {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
+ {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
+ {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2},
+ {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}
+};
+
+#undef INTRA
+#undef QUANT
+#undef MC
+#undef CODED
+#undef FWD
+#undef BWD
+#undef INTER
+
+
+static MVtab MV_4 [] = {
+ { 3, 6}, { 2, 4}, { 1, 3}, { 1, 3}, { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2}
+};
+
+static MVtab MV_10 [] = {
+ { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10},
+ { 0,10}, { 0,10}, { 0,10}, { 0,10}, {15,10}, {14,10}, {13,10}, {12,10},
+ {11,10}, {10,10}, { 9, 9}, { 9, 9}, { 8, 9}, { 8, 9}, { 7, 9}, { 7, 9},
+ { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7},
+ { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7},
+ { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}
+};
+
+
+static DMVtab DMV_2 [] = {
+ { 0, 1}, { 0, 1}, { 1, 2}, {-1, 2}
+};
+
+
+static CBPtab CBP_7 [] = {
+ {0x22, 7}, {0x12, 7}, {0x0a, 7}, {0x06, 7},
+ {0x21, 7}, {0x11, 7}, {0x09, 7}, {0x05, 7},
+ {0x3f, 6}, {0x3f, 6}, {0x03, 6}, {0x03, 6},
+ {0x24, 6}, {0x24, 6}, {0x18, 6}, {0x18, 6},
+ {0x3e, 5}, {0x3e, 5}, {0x3e, 5}, {0x3e, 5},
+ {0x02, 5}, {0x02, 5}, {0x02, 5}, {0x02, 5},
+ {0x3d, 5}, {0x3d, 5}, {0x3d, 5}, {0x3d, 5},
+ {0x01, 5}, {0x01, 5}, {0x01, 5}, {0x01, 5},
+ {0x38, 5}, {0x38, 5}, {0x38, 5}, {0x38, 5},
+ {0x34, 5}, {0x34, 5}, {0x34, 5}, {0x34, 5},
+ {0x2c, 5}, {0x2c, 5}, {0x2c, 5}, {0x2c, 5},
+ {0x1c, 5}, {0x1c, 5}, {0x1c, 5}, {0x1c, 5},
+ {0x28, 5}, {0x28, 5}, {0x28, 5}, {0x28, 5},
+ {0x14, 5}, {0x14, 5}, {0x14, 5}, {0x14, 5},
+ {0x30, 5}, {0x30, 5}, {0x30, 5}, {0x30, 5},
+ {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5},
+ {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4},
+ {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4},
+ {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4},
+ {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4},
+ {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4},
+ {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4},
+ {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4},
+ {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4},
+ {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3},
+ {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3},
+ {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3},
+ {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}
+};
+
+static CBPtab CBP_9 [] = {
+ {0, 0}, {0x00, 9}, {0x27, 9}, {0x1b, 9},
+ {0x3b, 9}, {0x37, 9}, {0x2f, 9}, {0x1f, 9},
+ {0x3a, 8}, {0x3a, 8}, {0x36, 8}, {0x36, 8},
+ {0x2e, 8}, {0x2e, 8}, {0x1e, 8}, {0x1e, 8},
+ {0x39, 8}, {0x39, 8}, {0x35, 8}, {0x35, 8},
+ {0x2d, 8}, {0x2d, 8}, {0x1d, 8}, {0x1d, 8},
+ {0x26, 8}, {0x26, 8}, {0x1a, 8}, {0x1a, 8},
+ {0x25, 8}, {0x25, 8}, {0x19, 8}, {0x19, 8},
+ {0x2b, 8}, {0x2b, 8}, {0x17, 8}, {0x17, 8},
+ {0x33, 8}, {0x33, 8}, {0x0f, 8}, {0x0f, 8},
+ {0x2a, 8}, {0x2a, 8}, {0x16, 8}, {0x16, 8},
+ {0x32, 8}, {0x32, 8}, {0x0e, 8}, {0x0e, 8},
+ {0x29, 8}, {0x29, 8}, {0x15, 8}, {0x15, 8},
+ {0x31, 8}, {0x31, 8}, {0x0d, 8}, {0x0d, 8},
+ {0x23, 8}, {0x23, 8}, {0x13, 8}, {0x13, 8},
+ {0x0b, 8}, {0x0b, 8}, {0x07, 8}, {0x07, 8}
+};
+
+
+static DCtab DC_lum_5 [] = {
+ {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
+ {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
+ {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3},
+ {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}
+};
+
+static DCtab DC_chrom_5 [] = {
+ {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2},
+ {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2},
+ {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2},
+ {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}
+};
+
+static DCtab DC_long [] = {
+ {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5},
+ {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5},
+ {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, { 7, 6}, { 7, 6},
+ {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10, 9}, {11, 9}
+};
+
+
+static DCTtab DCT_16 [] = {
+ {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
+ {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
+ {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
+ {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0},
+ { 2,18, 0}, { 2,17, 0}, { 2,16, 0}, { 2,15, 0},
+ { 7, 3, 0}, { 17, 2, 0}, { 16, 2, 0}, { 15, 2, 0},
+ { 14, 2, 0}, { 13, 2, 0}, { 12, 2, 0}, { 32, 1, 0},
+ { 31, 1, 0}, { 30, 1, 0}, { 29, 1, 0}, { 28, 1, 0}
+};
+
+static DCTtab DCT_15 [] = {
+ { 1,40,15}, { 1,39,15}, { 1,38,15}, { 1,37,15},
+ { 1,36,15}, { 1,35,15}, { 1,34,15}, { 1,33,15},
+ { 1,32,15}, { 2,14,15}, { 2,13,15}, { 2,12,15},
+ { 2,11,15}, { 2,10,15}, { 2, 9,15}, { 2, 8,15},
+ { 1,31,14}, { 1,31,14}, { 1,30,14}, { 1,30,14},
+ { 1,29,14}, { 1,29,14}, { 1,28,14}, { 1,28,14},
+ { 1,27,14}, { 1,27,14}, { 1,26,14}, { 1,26,14},
+ { 1,25,14}, { 1,25,14}, { 1,24,14}, { 1,24,14},
+ { 1,23,14}, { 1,23,14}, { 1,22,14}, { 1,22,14},
+ { 1,21,14}, { 1,21,14}, { 1,20,14}, { 1,20,14},
+ { 1,19,14}, { 1,19,14}, { 1,18,14}, { 1,18,14},
+ { 1,17,14}, { 1,17,14}, { 1,16,14}, { 1,16,14}
+};
+
+static DCTtab DCT_13 [] = {
+ { 11, 2,13}, { 10, 2,13}, { 6, 3,13}, { 4, 4,13},
+ { 3, 5,13}, { 2, 7,13}, { 2, 6,13}, { 1,15,13},
+ { 1,14,13}, { 1,13,13}, { 1,12,13}, { 27, 1,13},
+ { 26, 1,13}, { 25, 1,13}, { 24, 1,13}, { 23, 1,13},
+ { 1,11,12}, { 1,11,12}, { 9, 2,12}, { 9, 2,12},
+ { 5, 3,12}, { 5, 3,12}, { 1,10,12}, { 1,10,12},
+ { 3, 4,12}, { 3, 4,12}, { 8, 2,12}, { 8, 2,12},
+ { 22, 1,12}, { 22, 1,12}, { 21, 1,12}, { 21, 1,12},
+ { 1, 9,12}, { 1, 9,12}, { 20, 1,12}, { 20, 1,12},
+ { 19, 1,12}, { 19, 1,12}, { 2, 5,12}, { 2, 5,12},
+ { 4, 3,12}, { 4, 3,12}, { 1, 8,12}, { 1, 8,12},
+ { 7, 2,12}, { 7, 2,12}, { 18, 1,12}, { 18, 1,12}
+};
+
+static DCTtab DCT_B14_10 [] = {
+ { 17, 1,10}, { 6, 2,10}, { 1, 7,10}, { 3, 3,10},
+ { 2, 4,10}, { 16, 1,10}, { 15, 1,10}, { 5, 2,10}
+};
+
+static DCTtab DCT_B14_8 [] = {
+ { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6},
+ { 3, 2, 7}, { 3, 2, 7}, { 10, 1, 7}, { 10, 1, 7},
+ { 1, 4, 7}, { 1, 4, 7}, { 9, 1, 7}, { 9, 1, 7},
+ { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6},
+ { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6},
+ { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6},
+ { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
+ { 14, 1, 8}, { 1, 6, 8}, { 13, 1, 8}, { 12, 1, 8},
+ { 4, 2, 8}, { 2, 3, 8}, { 1, 5, 8}, { 11, 1, 8}
+};
+
+static DCTtab DCT_B14AC_5 [] = {
+ { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
+ { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
+ { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
+ {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
+ {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}
+};
+
+static DCTtab DCT_B14DC_5 [] = {
+ { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5},
+ { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4},
+ { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
+ { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
+ { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
+ { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1},
+ { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}, { 1, 1, 1}
+};
+
+static DCTtab DCT_B15_10 [] = {
+ { 6, 2, 9}, { 6, 2, 9}, { 15, 1, 9}, { 15, 1, 9},
+ { 3, 4,10}, { 17, 1,10}, { 16, 1, 9}, { 16, 1, 9}
+};
+
+static DCTtab DCT_B15_8 [] = {
+ { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6},
+ { 8, 1, 7}, { 8, 1, 7}, { 9, 1, 7}, { 9, 1, 7},
+ { 7, 1, 7}, { 7, 1, 7}, { 3, 2, 7}, { 3, 2, 7},
+ { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6},
+ { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6},
+ { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6},
+ { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6},
+ { 2, 5, 8}, { 12, 1, 8}, { 1,11, 8}, { 1,10, 8},
+ { 14, 1, 8}, { 13, 1, 8}, { 4, 2, 8}, { 2, 4, 8},
+ { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
+ { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5},
+ { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5},
+ { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5},
+ { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5},
+ { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5},
+ { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
+ { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
+ { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
+ { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
+ { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
+ { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
+ { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
+ { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3},
+ {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
+ {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
+ {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
+ {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4},
+ { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
+ { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
+ { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
+ { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2},
+ { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
+ { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
+ { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
+ { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
+ { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
+ { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
+ { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
+ { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3},
+ { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
+ { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5},
+ { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
+ { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5},
+ { 10, 1, 7}, { 10, 1, 7}, { 2, 3, 7}, { 2, 3, 7},
+ { 11, 1, 7}, { 11, 1, 7}, { 1, 8, 7}, { 1, 8, 7},
+ { 1, 9, 7}, { 1, 9, 7}, { 1,12, 8}, { 1,13, 8},
+ { 3, 3, 8}, { 5, 2, 8}, { 1,14, 8}, { 1,15, 8}
+};
+
+
+static MBAtab MBA_5 [] = {
+ {6, 5}, {5, 5}, {4, 4}, {4, 4}, {3, 4}, {3, 4},
+ {2, 3}, {2, 3}, {2, 3}, {2, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3},
+ {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1},
+ {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}
+};
+
+static MBAtab MBA_11 [] = {
+ {32, 11}, {31, 11}, {30, 11}, {29, 11},
+ {28, 11}, {27, 11}, {26, 11}, {25, 11},
+ {24, 11}, {23, 11}, {22, 11}, {21, 11},
+ {20, 10}, {20, 10}, {19, 10}, {19, 10},
+ {18, 10}, {18, 10}, {17, 10}, {17, 10},
+ {16, 10}, {16, 10}, {15, 10}, {15, 10},
+ {14, 8}, {14, 8}, {14, 8}, {14, 8},
+ {14, 8}, {14, 8}, {14, 8}, {14, 8},
+ {13, 8}, {13, 8}, {13, 8}, {13, 8},
+ {13, 8}, {13, 8}, {13, 8}, {13, 8},
+ {12, 8}, {12, 8}, {12, 8}, {12, 8},
+ {12, 8}, {12, 8}, {12, 8}, {12, 8},
+ {11, 8}, {11, 8}, {11, 8}, {11, 8},
+ {11, 8}, {11, 8}, {11, 8}, {11, 8},
+ {10, 8}, {10, 8}, {10, 8}, {10, 8},
+ {10, 8}, {10, 8}, {10, 8}, {10, 8},
+ { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8},
+ { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8},
+ { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
+ { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
+ { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
+ { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7},
+ { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
+ { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
+ { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7},
+ { 7, 7}, { 7, 7}, { 7, 7}, { 7, 7}
+};
diff --git a/src/libmpg123/Makefile.am b/src/libmpg123/Makefile.am
new file mode 100644
index 000000000..20b4c7aff
--- /dev/null
+++ b/src/libmpg123/Makefile.am
@@ -0,0 +1,22 @@
+CFLAGS = @BUILD_LIB_STATIC@ @GLOBAL_CFLAGS@
+
+EXTRA_DIST = main.c
+
+noinst_LTLIBRARIES = libmpg123.la
+
+libmpg123_la_SOURCES = common.c decode_i386.c layer1.c layer3.c tabinit.c \
+ dct64_i386.c interface.c layer2.c
+
+
+noinst_HEADERS = huffman.h mpg123.h mpglib.h l2tables.h
+
+debug:
+ $(MAKE) CFLAGS="$(DEBUG_CFLAGS)"
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/libmpg123/README b/src/libmpg123/README
new file mode 100644
index 000000000..3c5f33749
--- /dev/null
+++ b/src/libmpg123/README
@@ -0,0 +1,39 @@
+MP3 library
+-----------
+Version 0.2
+
+This decoder is a 'light' version (thrown out all unnecessay parts)
+from the mpg123 package. I made this for a company.
+
+Currently only Layer3 is enabled to save some space. Layer1,2 isn't
+tested at all. The interface will not change significantly.
+A backport to the mpg123 package is planed.
+
+comiled and tested only on Solaris 2.6
+main.c contains a simple demo application for library.
+
+COPYING: you may use this source under GPL terms!
+
+PLEASE NOTE: This software may contain patented alogrithm (at least
+ patented in some countries). It may be not allowed to sell/use products
+ based on this source code in these countries. Check this out first!
+
+COPYRIGHT of MP3 music:
+ Please note, that the duplicating of copyrighted music without explicit
+ permission violates the rights of the owner.
+
+SENDING PATCHES:
+ Maybe I change the copyright policy (ie some kind of more free BSD licencse).
+ Please consider this when sending patches/changes.
+ I also want to have the freedom to sell the code to companies that
+ can not use the code under GPL. So, if you send me significant patches,
+ I need your explicit permission to do this. Of course, there will also
+ be the GPLed open source version of the 100% same code.
+ For the case you cannot accept this: the code is GPL, it's your freedom
+ to distribute your changes again under GPL.
+
+FEEDBACK:
+ I'm interessted to here from you, when you use this package as part
+ of another project.
+
+
diff --git a/src/libmpg123/TODO b/src/libmpg123/TODO
new file mode 100644
index 000000000..403711010
--- /dev/null
+++ b/src/libmpg123/TODO
@@ -0,0 +1,2 @@
+
+apply 'VBR' bugfix
diff --git a/src/libmpg123/common.c b/src/libmpg123/common.c
new file mode 100644
index 000000000..0112cbc58
--- /dev/null
+++ b/src/libmpg123/common.c
@@ -0,0 +1,181 @@
+#include <ctype.h>
+#include <stdlib.h>
+#include <signal.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "mpg123.h"
+
+struct parameter mpg123_param = { 1 , 1 , 0 , 0 };
+
+int tabsel_123[2][3][16] = {
+ { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,},
+ {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,},
+ {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} },
+
+ { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,},
+ {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,},
+ {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} }
+};
+
+long freqs[9] = { 44100, 48000, 32000,
+ 22050, 24000, 16000 ,
+ 11025 , 12000 , 8000 };
+
+int mpg123_bitindex;
+unsigned char *mpg123_wordpointer;
+unsigned char *pcm_sample;
+int pcm_point = 0;
+
+
+#define HDRCMPMASK 0xfffffd00
+
+/*
+ * the code a header and write the information
+ * into the frame structure
+ */
+int decode_header(struct frame *fr,unsigned long newhead)
+{
+ if( newhead & (1<<20) ) {
+ fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1;
+ fr->mpeg25 = 0;
+ }
+ else {
+ fr->lsf = 1;
+ fr->mpeg25 = 1;
+ }
+
+ fr->lay = 4-((newhead>>17)&3);
+ if( ((newhead>>10)&0x3) == 0x3) {
+ fprintf(stderr,"Stream error\n");
+ exit(1);
+ }
+ if(fr->mpeg25) {
+ fr->sampling_frequency = 6 + ((newhead>>10)&0x3);
+ }
+ else {
+ int dummy;
+ fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3);
+ dummy = (newhead>>10)&0x3;
+ switch (dummy) {
+ case 0:
+ fr->sample_rate = 44100;
+ break;
+ case 1:
+ fr->sample_rate = 48000;
+ break;
+ case 2:
+ fr->sample_rate = 32000;
+ break;
+ case 3:
+ fprintf (stderr, "invalid sampling rate\n");
+ fr->sample_rate = 44100;
+ break;
+ }
+ }
+
+ fr->error_protection = ((newhead>>16)&0x1)^0x1;
+
+ if(fr->mpeg25) /* allow Bitrate change for 2.5 ... */
+ fr->bitrate_index = ((newhead>>12)&0xf);
+
+ fr->bitrate_index = ((newhead>>12)&0xf);
+ fr->padding = ((newhead>>9)&0x1);
+ fr->extension = ((newhead>>8)&0x1);
+ fr->mode = ((newhead>>6)&0x3);
+ fr->mode_ext = ((newhead>>4)&0x3);
+ fr->copyright = ((newhead>>3)&0x1);
+ fr->original = ((newhead>>2)&0x1);
+ fr->emphasis = newhead & 0x3;
+
+ fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
+
+ if(!fr->bitrate_index)
+ {
+ fprintf(stderr,"Free format not supported.\n");
+ return (0);
+ }
+
+ switch(fr->lay)
+ {
+ case 1:
+ fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
+ fr->framesize /= freqs[fr->sampling_frequency];
+ fr->framesize = ((fr->framesize+fr->padding)<<2)-4;
+ break;
+ case 2:
+ fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
+ fr->framesize /= freqs[fr->sampling_frequency];
+ fr->framesize += fr->padding - 4;
+ break;
+ case 3:
+ fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
+ fr->framesize /= freqs[fr->sampling_frequency]<<(fr->lsf);
+ fr->framesize = fr->framesize + fr->padding - 4;
+ break;
+ default:
+ fprintf(stderr,"Sorry, unknown layer type.\n");
+ return (0);
+ }
+ return 1;
+}
+
+unsigned int getbits(int number_of_bits)
+{
+ unsigned long rval;
+
+ if(!number_of_bits)
+ return 0;
+
+ {
+ rval = mpg123_wordpointer[0];
+ rval <<= 8;
+ rval |= mpg123_wordpointer[1];
+ rval <<= 8;
+ rval |= mpg123_wordpointer[2];
+ rval <<= mpg123_bitindex;
+ rval &= 0xffffff;
+
+ mpg123_bitindex += number_of_bits;
+
+ rval >>= (24-number_of_bits);
+
+ mpg123_wordpointer += (mpg123_bitindex>>3);
+ mpg123_bitindex &= 7;
+ }
+ return rval;
+}
+
+unsigned int getbits_fast(int number_of_bits)
+{
+ unsigned long rval;
+
+ {
+ rval = mpg123_wordpointer[0];
+ rval <<= 8;
+ rval |= mpg123_wordpointer[1];
+ rval <<= mpg123_bitindex;
+ rval &= 0xffff;
+ mpg123_bitindex += number_of_bits;
+
+ rval >>= (16-number_of_bits);
+
+ mpg123_wordpointer += (mpg123_bitindex>>3);
+ mpg123_bitindex &= 7;
+ }
+ return rval;
+}
+
+unsigned int get1bit(void)
+{
+ unsigned char rval;
+ rval = *mpg123_wordpointer << mpg123_bitindex;
+
+ mpg123_bitindex++;
+ mpg123_wordpointer += (mpg123_bitindex>>3);
+ mpg123_bitindex &= 7;
+
+ return rval>>7;
+}
diff --git a/src/libmpg123/dct64_i386.c b/src/libmpg123/dct64_i386.c
new file mode 100644
index 000000000..b98b47400
--- /dev/null
+++ b/src/libmpg123/dct64_i386.c
@@ -0,0 +1,315 @@
+
+/*
+ * Discrete Cosine Tansform (DCT) for subband synthesis
+ * optimized for machines with no auto-increment.
+ * The performance is highly compiler dependend. Maybe
+ * the dct64.c version for 'normal' processor may be faster
+ * even for Intel processors.
+ */
+
+#include "mpg123.h"
+
+static void dct64_1(real *out0,real *out1,real *b1,real *b2,real *samples)
+{
+
+ {
+ register real *costab = pnts[0];
+
+ b1[0x00] = samples[0x00] + samples[0x1F];
+ b1[0x1F] = (samples[0x00] - samples[0x1F]) * costab[0x0];
+
+ b1[0x01] = samples[0x01] + samples[0x1E];
+ b1[0x1E] = (samples[0x01] - samples[0x1E]) * costab[0x1];
+
+ b1[0x02] = samples[0x02] + samples[0x1D];
+ b1[0x1D] = (samples[0x02] - samples[0x1D]) * costab[0x2];
+
+ b1[0x03] = samples[0x03] + samples[0x1C];
+ b1[0x1C] = (samples[0x03] - samples[0x1C]) * costab[0x3];
+
+ b1[0x04] = samples[0x04] + samples[0x1B];
+ b1[0x1B] = (samples[0x04] - samples[0x1B]) * costab[0x4];
+
+ b1[0x05] = samples[0x05] + samples[0x1A];
+ b1[0x1A] = (samples[0x05] - samples[0x1A]) * costab[0x5];
+
+ b1[0x06] = samples[0x06] + samples[0x19];
+ b1[0x19] = (samples[0x06] - samples[0x19]) * costab[0x6];
+
+ b1[0x07] = samples[0x07] + samples[0x18];
+ b1[0x18] = (samples[0x07] - samples[0x18]) * costab[0x7];
+
+ b1[0x08] = samples[0x08] + samples[0x17];
+ b1[0x17] = (samples[0x08] - samples[0x17]) * costab[0x8];
+
+ b1[0x09] = samples[0x09] + samples[0x16];
+ b1[0x16] = (samples[0x09] - samples[0x16]) * costab[0x9];
+
+ b1[0x0A] = samples[0x0A] + samples[0x15];
+ b1[0x15] = (samples[0x0A] - samples[0x15]) * costab[0xA];
+
+ b1[0x0B] = samples[0x0B] + samples[0x14];
+ b1[0x14] = (samples[0x0B] - samples[0x14]) * costab[0xB];
+
+ b1[0x0C] = samples[0x0C] + samples[0x13];
+ b1[0x13] = (samples[0x0C] - samples[0x13]) * costab[0xC];
+
+ b1[0x0D] = samples[0x0D] + samples[0x12];
+ b1[0x12] = (samples[0x0D] - samples[0x12]) * costab[0xD];
+
+ b1[0x0E] = samples[0x0E] + samples[0x11];
+ b1[0x11] = (samples[0x0E] - samples[0x11]) * costab[0xE];
+
+ b1[0x0F] = samples[0x0F] + samples[0x10];
+ b1[0x10] = (samples[0x0F] - samples[0x10]) * costab[0xF];
+ }
+
+
+ {
+ register real *costab = pnts[1];
+
+ b2[0x00] = b1[0x00] + b1[0x0F];
+ b2[0x0F] = (b1[0x00] - b1[0x0F]) * costab[0];
+ b2[0x01] = b1[0x01] + b1[0x0E];
+ b2[0x0E] = (b1[0x01] - b1[0x0E]) * costab[1];
+ b2[0x02] = b1[0x02] + b1[0x0D];
+ b2[0x0D] = (b1[0x02] - b1[0x0D]) * costab[2];
+ b2[0x03] = b1[0x03] + b1[0x0C];
+ b2[0x0C] = (b1[0x03] - b1[0x0C]) * costab[3];
+ b2[0x04] = b1[0x04] + b1[0x0B];
+ b2[0x0B] = (b1[0x04] - b1[0x0B]) * costab[4];
+ b2[0x05] = b1[0x05] + b1[0x0A];
+ b2[0x0A] = (b1[0x05] - b1[0x0A]) * costab[5];
+ b2[0x06] = b1[0x06] + b1[0x09];
+ b2[0x09] = (b1[0x06] - b1[0x09]) * costab[6];
+ b2[0x07] = b1[0x07] + b1[0x08];
+ b2[0x08] = (b1[0x07] - b1[0x08]) * costab[7];
+
+ b2[0x10] = b1[0x10] + b1[0x1F];
+ b2[0x1F] = (b1[0x1F] - b1[0x10]) * costab[0];
+ b2[0x11] = b1[0x11] + b1[0x1E];
+ b2[0x1E] = (b1[0x1E] - b1[0x11]) * costab[1];
+ b2[0x12] = b1[0x12] + b1[0x1D];
+ b2[0x1D] = (b1[0x1D] - b1[0x12]) * costab[2];
+ b2[0x13] = b1[0x13] + b1[0x1C];
+ b2[0x1C] = (b1[0x1C] - b1[0x13]) * costab[3];
+ b2[0x14] = b1[0x14] + b1[0x1B];
+ b2[0x1B] = (b1[0x1B] - b1[0x14]) * costab[4];
+ b2[0x15] = b1[0x15] + b1[0x1A];
+ b2[0x1A] = (b1[0x1A] - b1[0x15]) * costab[5];
+ b2[0x16] = b1[0x16] + b1[0x19];
+ b2[0x19] = (b1[0x19] - b1[0x16]) * costab[6];
+ b2[0x17] = b1[0x17] + b1[0x18];
+ b2[0x18] = (b1[0x18] - b1[0x17]) * costab[7];
+ }
+
+ {
+ register real *costab = pnts[2];
+
+ b1[0x00] = b2[0x00] + b2[0x07];
+ b1[0x07] = (b2[0x00] - b2[0x07]) * costab[0];
+ b1[0x01] = b2[0x01] + b2[0x06];
+ b1[0x06] = (b2[0x01] - b2[0x06]) * costab[1];
+ b1[0x02] = b2[0x02] + b2[0x05];
+ b1[0x05] = (b2[0x02] - b2[0x05]) * costab[2];
+ b1[0x03] = b2[0x03] + b2[0x04];
+ b1[0x04] = (b2[0x03] - b2[0x04]) * costab[3];
+
+ b1[0x08] = b2[0x08] + b2[0x0F];
+ b1[0x0F] = (b2[0x0F] - b2[0x08]) * costab[0];
+ b1[0x09] = b2[0x09] + b2[0x0E];
+ b1[0x0E] = (b2[0x0E] - b2[0x09]) * costab[1];
+ b1[0x0A] = b2[0x0A] + b2[0x0D];
+ b1[0x0D] = (b2[0x0D] - b2[0x0A]) * costab[2];
+ b1[0x0B] = b2[0x0B] + b2[0x0C];
+ b1[0x0C] = (b2[0x0C] - b2[0x0B]) * costab[3];
+
+ b1[0x10] = b2[0x10] + b2[0x17];
+ b1[0x17] = (b2[0x10] - b2[0x17]) * costab[0];
+ b1[0x11] = b2[0x11] + b2[0x16];
+ b1[0x16] = (b2[0x11] - b2[0x16]) * costab[1];
+ b1[0x12] = b2[0x12] + b2[0x15];
+ b1[0x15] = (b2[0x12] - b2[0x15]) * costab[2];
+ b1[0x13] = b2[0x13] + b2[0x14];
+ b1[0x14] = (b2[0x13] - b2[0x14]) * costab[3];
+
+ b1[0x18] = b2[0x18] + b2[0x1F];
+ b1[0x1F] = (b2[0x1F] - b2[0x18]) * costab[0];
+ b1[0x19] = b2[0x19] + b2[0x1E];
+ b1[0x1E] = (b2[0x1E] - b2[0x19]) * costab[1];
+ b1[0x1A] = b2[0x1A] + b2[0x1D];
+ b1[0x1D] = (b2[0x1D] - b2[0x1A]) * costab[2];
+ b1[0x1B] = b2[0x1B] + b2[0x1C];
+ b1[0x1C] = (b2[0x1C] - b2[0x1B]) * costab[3];
+ }
+
+ {
+ register real const cos0 = pnts[3][0];
+ register real const cos1 = pnts[3][1];
+
+ b2[0x00] = b1[0x00] + b1[0x03];
+ b2[0x03] = (b1[0x00] - b1[0x03]) * cos0;
+ b2[0x01] = b1[0x01] + b1[0x02];
+ b2[0x02] = (b1[0x01] - b1[0x02]) * cos1;
+
+ b2[0x04] = b1[0x04] + b1[0x07];
+ b2[0x07] = (b1[0x07] - b1[0x04]) * cos0;
+ b2[0x05] = b1[0x05] + b1[0x06];
+ b2[0x06] = (b1[0x06] - b1[0x05]) * cos1;
+
+ b2[0x08] = b1[0x08] + b1[0x0B];
+ b2[0x0B] = (b1[0x08] - b1[0x0B]) * cos0;
+ b2[0x09] = b1[0x09] + b1[0x0A];
+ b2[0x0A] = (b1[0x09] - b1[0x0A]) * cos1;
+
+ b2[0x0C] = b1[0x0C] + b1[0x0F];
+ b2[0x0F] = (b1[0x0F] - b1[0x0C]) * cos0;
+ b2[0x0D] = b1[0x0D] + b1[0x0E];
+ b2[0x0E] = (b1[0x0E] - b1[0x0D]) * cos1;
+
+ b2[0x10] = b1[0x10] + b1[0x13];
+ b2[0x13] = (b1[0x10] - b1[0x13]) * cos0;
+ b2[0x11] = b1[0x11] + b1[0x12];
+ b2[0x12] = (b1[0x11] - b1[0x12]) * cos1;
+
+ b2[0x14] = b1[0x14] + b1[0x17];
+ b2[0x17] = (b1[0x17] - b1[0x14]) * cos0;
+ b2[0x15] = b1[0x15] + b1[0x16];
+ b2[0x16] = (b1[0x16] - b1[0x15]) * cos1;
+
+ b2[0x18] = b1[0x18] + b1[0x1B];
+ b2[0x1B] = (b1[0x18] - b1[0x1B]) * cos0;
+ b2[0x19] = b1[0x19] + b1[0x1A];
+ b2[0x1A] = (b1[0x19] - b1[0x1A]) * cos1;
+
+ b2[0x1C] = b1[0x1C] + b1[0x1F];
+ b2[0x1F] = (b1[0x1F] - b1[0x1C]) * cos0;
+ b2[0x1D] = b1[0x1D] + b1[0x1E];
+ b2[0x1E] = (b1[0x1E] - b1[0x1D]) * cos1;
+ }
+
+ {
+ register real const cos0 = pnts[4][0];
+
+ b1[0x00] = b2[0x00] + b2[0x01];
+ b1[0x01] = (b2[0x00] - b2[0x01]) * cos0;
+ b1[0x02] = b2[0x02] + b2[0x03];
+ b1[0x03] = (b2[0x03] - b2[0x02]) * cos0;
+ b1[0x02] += b1[0x03];
+
+ b1[0x04] = b2[0x04] + b2[0x05];
+ b1[0x05] = (b2[0x04] - b2[0x05]) * cos0;
+ b1[0x06] = b2[0x06] + b2[0x07];
+ b1[0x07] = (b2[0x07] - b2[0x06]) * cos0;
+ b1[0x06] += b1[0x07];
+ b1[0x04] += b1[0x06];
+ b1[0x06] += b1[0x05];
+ b1[0x05] += b1[0x07];
+
+ b1[0x08] = b2[0x08] + b2[0x09];
+ b1[0x09] = (b2[0x08] - b2[0x09]) * cos0;
+ b1[0x0A] = b2[0x0A] + b2[0x0B];
+ b1[0x0B] = (b2[0x0B] - b2[0x0A]) * cos0;
+ b1[0x0A] += b1[0x0B];
+
+ b1[0x0C] = b2[0x0C] + b2[0x0D];
+ b1[0x0D] = (b2[0x0C] - b2[0x0D]) * cos0;
+ b1[0x0E] = b2[0x0E] + b2[0x0F];
+ b1[0x0F] = (b2[0x0F] - b2[0x0E]) * cos0;
+ b1[0x0E] += b1[0x0F];
+ b1[0x0C] += b1[0x0E];
+ b1[0x0E] += b1[0x0D];
+ b1[0x0D] += b1[0x0F];
+
+ b1[0x10] = b2[0x10] + b2[0x11];
+ b1[0x11] = (b2[0x10] - b2[0x11]) * cos0;
+ b1[0x12] = b2[0x12] + b2[0x13];
+ b1[0x13] = (b2[0x13] - b2[0x12]) * cos0;
+ b1[0x12] += b1[0x13];
+
+ b1[0x14] = b2[0x14] + b2[0x15];
+ b1[0x15] = (b2[0x14] - b2[0x15]) * cos0;
+ b1[0x16] = b2[0x16] + b2[0x17];
+ b1[0x17] = (b2[0x17] - b2[0x16]) * cos0;
+ b1[0x16] += b1[0x17];
+ b1[0x14] += b1[0x16];
+ b1[0x16] += b1[0x15];
+ b1[0x15] += b1[0x17];
+
+ b1[0x18] = b2[0x18] + b2[0x19];
+ b1[0x19] = (b2[0x18] - b2[0x19]) * cos0;
+ b1[0x1A] = b2[0x1A] + b2[0x1B];
+ b1[0x1B] = (b2[0x1B] - b2[0x1A]) * cos0;
+ b1[0x1A] += b1[0x1B];
+
+ b1[0x1C] = b2[0x1C] + b2[0x1D];
+ b1[0x1D] = (b2[0x1C] - b2[0x1D]) * cos0;
+ b1[0x1E] = b2[0x1E] + b2[0x1F];
+ b1[0x1F] = (b2[0x1F] - b2[0x1E]) * cos0;
+ b1[0x1E] += b1[0x1F];
+ b1[0x1C] += b1[0x1E];
+ b1[0x1E] += b1[0x1D];
+ b1[0x1D] += b1[0x1F];
+ }
+
+ out0[0x10*16] = b1[0x00];
+ out0[0x10*12] = b1[0x04];
+ out0[0x10* 8] = b1[0x02];
+ out0[0x10* 4] = b1[0x06];
+ out0[0x10* 0] = b1[0x01];
+ out1[0x10* 0] = b1[0x01];
+ out1[0x10* 4] = b1[0x05];
+ out1[0x10* 8] = b1[0x03];
+ out1[0x10*12] = b1[0x07];
+
+ b1[0x08] += b1[0x0C];
+ out0[0x10*14] = b1[0x08];
+ b1[0x0C] += b1[0x0a];
+ out0[0x10*10] = b1[0x0C];
+ b1[0x0A] += b1[0x0E];
+ out0[0x10* 6] = b1[0x0A];
+ b1[0x0E] += b1[0x09];
+ out0[0x10* 2] = b1[0x0E];
+ b1[0x09] += b1[0x0D];
+ out1[0x10* 2] = b1[0x09];
+ b1[0x0D] += b1[0x0B];
+ out1[0x10* 6] = b1[0x0D];
+ b1[0x0B] += b1[0x0F];
+ out1[0x10*10] = b1[0x0B];
+ out1[0x10*14] = b1[0x0F];
+
+ b1[0x18] += b1[0x1C];
+ out0[0x10*15] = b1[0x10] + b1[0x18];
+ out0[0x10*13] = b1[0x18] + b1[0x14];
+ b1[0x1C] += b1[0x1a];
+ out0[0x10*11] = b1[0x14] + b1[0x1C];
+ out0[0x10* 9] = b1[0x1C] + b1[0x12];
+ b1[0x1A] += b1[0x1E];
+ out0[0x10* 7] = b1[0x12] + b1[0x1A];
+ out0[0x10* 5] = b1[0x1A] + b1[0x16];
+ b1[0x1E] += b1[0x19];
+ out0[0x10* 3] = b1[0x16] + b1[0x1E];
+ out0[0x10* 1] = b1[0x1E] + b1[0x11];
+ b1[0x19] += b1[0x1D];
+ out1[0x10* 1] = b1[0x11] + b1[0x19];
+ out1[0x10* 3] = b1[0x19] + b1[0x15];
+ b1[0x1D] += b1[0x1B];
+ out1[0x10* 5] = b1[0x15] + b1[0x1D];
+ out1[0x10* 7] = b1[0x1D] + b1[0x13];
+ b1[0x1B] += b1[0x1F];
+ out1[0x10* 9] = b1[0x13] + b1[0x1B];
+ out1[0x10*11] = b1[0x1B] + b1[0x17];
+ out1[0x10*13] = b1[0x17] + b1[0x1F];
+ out1[0x10*15] = b1[0x1F];
+}
+
+/*
+ * the call via dct64 is a trick to force GCC to use
+ * (new) registers for the b1,b2 pointer to the bufs[xx] field
+ */
+void dct64(real *a,real *b,real *c)
+{
+ real bufs[0x40];
+ dct64_1(a,b,bufs,bufs+0x20,c);
+}
+
diff --git a/src/libmpg123/decode_i386.c b/src/libmpg123/decode_i386.c
new file mode 100644
index 000000000..dc73c33cc
--- /dev/null
+++ b/src/libmpg123/decode_i386.c
@@ -0,0 +1,151 @@
+/*
+ * Mpeg Layer-1,2,3 audio decoder
+ * ------------------------------
+ * copyright (c) 1995,1996,1997 by Michael Hipp, All rights reserved.
+ * See also 'README'
+ *
+ * slighlty optimized for machines without autoincrement/decrement.
+ * The performance is highly compiler dependend. Maybe
+ * the decode.c version for 'normal' processor may be faster
+ * even for Intel processors.
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include "mpg123.h"
+#include "mpglib.h"
+
+ /* old WRITE_SAMPLE */
+#define WRITE_SAMPLE(samples,sum,clip) \
+ if( (sum) > 32767.0) { *(samples) = 0x7fff; (clip)++; } \
+ else if( (sum) < -32768.0) { *(samples) = -0x8000; (clip)++; /* printf ("too small : %f\n",sum);*/} \
+ else { *(samples) = sum; }
+
+int synth_1to1_mono(mpgaudio_t *mp, real *bandPtr,unsigned char *samples,int *pnt)
+{
+ short samples_tmp[64];
+ short *tmp1 = samples_tmp;
+ int i,ret;
+ int pnt1 = 0;
+
+ ret = synth_1to1(mp, bandPtr,0,(unsigned char *) samples_tmp,&pnt1);
+ samples += *pnt;
+
+ for(i=0;i<32;i++) {
+ *( (short *) samples) = *tmp1;
+ samples += 2;
+ tmp1 += 2;
+ }
+ *pnt += 64;
+
+ return ret;
+}
+
+
+int synth_1to1(mpgaudio_t *mp, real *bandPtr,int channel,unsigned char *out,int *pnt)
+{
+ static const int step = 2;
+ int bo;
+ short *samples = (short *) (out + *pnt);
+
+ real *b0,(*buf)[0x110];
+ int clip = 0;
+ int bo1;
+
+ bo = mp->synth_bo;
+
+ if(!channel) {
+ bo--;
+ bo &= 0xf;
+ buf = mp->synth_buffs[0];
+ }
+ else {
+ samples++;
+ buf = mp->synth_buffs[1];
+ }
+
+ if(bo & 0x1) {
+ b0 = buf[0];
+ bo1 = bo;
+ dct64(buf[1]+((bo+1)&0xf),buf[0]+bo,bandPtr);
+ }
+ else {
+ b0 = buf[1];
+ bo1 = bo+1;
+ dct64(buf[0]+bo,buf[1]+bo+1,bandPtr);
+ }
+
+ mp->synth_bo = bo;
+
+ {
+ register int j;
+ real *window = decwin + 16 - bo1;
+
+ for (j=16;j;j--,b0+=0x10,window+=0x20,samples+=step)
+ {
+ real sum;
+ sum = window[0x0] * b0[0x0];
+ sum -= window[0x1] * b0[0x1];
+ sum += window[0x2] * b0[0x2];
+ sum -= window[0x3] * b0[0x3];
+ sum += window[0x4] * b0[0x4];
+ sum -= window[0x5] * b0[0x5];
+ sum += window[0x6] * b0[0x6];
+ sum -= window[0x7] * b0[0x7];
+ sum += window[0x8] * b0[0x8];
+ sum -= window[0x9] * b0[0x9];
+ sum += window[0xA] * b0[0xA];
+ sum -= window[0xB] * b0[0xB];
+ sum += window[0xC] * b0[0xC];
+ sum -= window[0xD] * b0[0xD];
+ sum += window[0xE] * b0[0xE];
+ sum -= window[0xF] * b0[0xF];
+
+ WRITE_SAMPLE(samples,sum,clip);
+ }
+
+ {
+ real sum;
+ sum = window[0x0] * b0[0x0];
+ sum += window[0x2] * b0[0x2];
+ sum += window[0x4] * b0[0x4];
+ sum += window[0x6] * b0[0x6];
+ sum += window[0x8] * b0[0x8];
+ sum += window[0xA] * b0[0xA];
+ sum += window[0xC] * b0[0xC];
+ sum += window[0xE] * b0[0xE];
+ WRITE_SAMPLE(samples,sum,clip);
+ b0-=0x10,window-=0x20,samples+=step;
+ }
+ window += bo1<<1;
+
+ for (j=15;j;j--,b0-=0x10,window-=0x20,samples+=step)
+ {
+ real sum;
+ sum = -window[-0x1] * b0[0x0];
+ sum -= window[-0x2] * b0[0x1];
+ sum -= window[-0x3] * b0[0x2];
+ sum -= window[-0x4] * b0[0x3];
+ sum -= window[-0x5] * b0[0x4];
+ sum -= window[-0x6] * b0[0x5];
+ sum -= window[-0x7] * b0[0x6];
+ sum -= window[-0x8] * b0[0x7];
+ sum -= window[-0x9] * b0[0x8];
+ sum -= window[-0xA] * b0[0x9];
+ sum -= window[-0xB] * b0[0xA];
+ sum -= window[-0xC] * b0[0xB];
+ sum -= window[-0xD] * b0[0xC];
+ sum -= window[-0xE] * b0[0xD];
+ sum -= window[-0xF] * b0[0xE];
+ sum -= window[-0x0] * b0[0xF];
+
+ WRITE_SAMPLE(samples,sum,clip);
+ }
+ }
+ *pnt += 128;
+
+ return clip;
+}
+
diff --git a/src/libmpg123/huffman.h b/src/libmpg123/huffman.h
new file mode 100644
index 000000000..7fec0d589
--- /dev/null
+++ b/src/libmpg123/huffman.h
@@ -0,0 +1,332 @@
+/*
+ * huffman tables ... recalcualted to work with my optimzed
+ * decoder scheme (MH)
+ *
+ * probably we could save a few bytes of memory, because the
+ * smaller tables are often the part of a bigger table
+ */
+
+struct newhuff
+{
+ unsigned int linbits;
+ short *table;
+};
+
+static short tab0[] =
+{
+ 0
+};
+
+static short tab1[] =
+{
+ -5, -3, -1, 17, 1, 16, 0
+};
+
+static short tab2[] =
+{
+ -15, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 17, -1, 1,
+ 16, 0
+};
+
+static short tab3[] =
+{
+ -13, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 16, 17, -1,
+ 1, 0
+};
+
+static short tab5[] =
+{
+ -29, -25, -23, -15, -7, -5, -3, -1, 51, 35, 50, 49, -3, -1, 19,
+ 3, -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, 17, -1, 1, 16,
+ 0
+};
+
+static short tab6[] =
+{
+ -25, -19, -13, -9, -5, -3, -1, 51, 3, 35, -1, 50, 48, -1, 19,
+ 49, -3, -1, 34, 2, 18, -3, -1, 33, 32, 1, -1, 17, -1, 16,
+ 0
+};
+
+static short tab7[] =
+{
+ -69, -65, -57, -39, -29, -17, -11, -7, -3, -1, 85, 69, -1, 84, 83,
+ -1, 53, 68, -3, -1, 37, 82, 21, -5, -1, 81, -1, 5, 52, -1,
+ 80, -1, 67, 51, -5, -3, -1, 36, 66, 20, -1, 65, 64, -11, -7,
+ -3, -1, 4, 35, -1, 50, 3, -1, 19, 49, -3, -1, 48, 34, 18,
+ -5, -1, 33, -1, 2, 32, 17, -1, 1, 16, 0
+};
+
+static short tab8[] =
+{
+ -65, -63, -59, -45, -31, -19, -13, -7, -5, -3, -1, 85, 84, 69, 83,
+ -3, -1, 53, 68, 37, -3, -1, 82, 5, 21, -5, -1, 81, -1, 52,
+ 67, -3, -1, 80, 51, 36, -5, -3, -1, 66, 20, 65, -3, -1, 4,
+ 64, -1, 35, 50, -9, -7, -3, -1, 19, 49, -1, 3, 48, 34, -1,
+ 2, 32, -1, 18, 33, 17, -3, -1, 1, 16, 0
+};
+
+static short tab9[] =
+{
+ -63, -53, -41, -29, -19, -11, -5, -3, -1, 85, 69, 53, -1, 83, -1,
+ 84, 5, -3, -1, 68, 37, -1, 82, 21, -3, -1, 81, 52, -1, 67,
+ -1, 80, 4, -7, -3, -1, 36, 66, -1, 51, 64, -1, 20, 65, -5,
+ -3, -1, 35, 50, 19, -1, 49, -1, 3, 48, -5, -3, -1, 34, 2,
+ 18, -1, 33, 32, -3, -1, 17, 1, -1, 16, 0
+};
+
+static short tab10[] =
+{
+-125,-121,-111, -83, -55, -35, -21, -13, -7, -3, -1, 119, 103, -1, 118,
+ 87, -3, -1, 117, 102, 71, -3, -1, 116, 86, -1, 101, 55, -9, -3,
+ -1, 115, 70, -3, -1, 85, 84, 99, -1, 39, 114, -11, -5, -3, -1,
+ 100, 7, 112, -1, 98, -1, 69, 53, -5, -1, 6, -1, 83, 68, 23,
+ -17, -5, -1, 113, -1, 54, 38, -5, -3, -1, 37, 82, 21, -1, 81,
+ -1, 52, 67, -3, -1, 22, 97, -1, 96, -1, 5, 80, -19, -11, -7,
+ -3, -1, 36, 66, -1, 51, 4, -1, 20, 65, -3, -1, 64, 35, -1,
+ 50, 3, -3, -1, 19, 49, -1, 48, 34, -7, -3, -1, 18, 33, -1,
+ 2, 32, 17, -1, 1, 16, 0
+};
+
+static short tab11[] =
+{
+-121,-113, -89, -59, -43, -27, -17, -7, -3, -1, 119, 103, -1, 118, 117,
+ -3, -1, 102, 71, -1, 116, -1, 87, 85, -5, -3, -1, 86, 101, 55,
+ -1, 115, 70, -9, -7, -3, -1, 69, 84, -1, 53, 83, 39, -1, 114,
+ -1, 100, 7, -5, -1, 113, -1, 23, 112, -3, -1, 54, 99, -1, 96,
+ -1, 68, 37, -13, -7, -5, -3, -1, 82, 5, 21, 98, -3, -1, 38,
+ 6, 22, -5, -1, 97, -1, 81, 52, -5, -1, 80, -1, 67, 51, -1,
+ 36, 66, -15, -11, -7, -3, -1, 20, 65, -1, 4, 64, -1, 35, 50,
+ -1, 19, 49, -5, -3, -1, 3, 48, 34, 33, -5, -1, 18, -1, 2,
+ 32, 17, -3, -1, 1, 16, 0
+};
+
+static short tab12[] =
+{
+-115, -99, -73, -45, -27, -17, -9, -5, -3, -1, 119, 103, 118, -1, 87,
+ 117, -3, -1, 102, 71, -1, 116, 101, -3, -1, 86, 55, -3, -1, 115,
+ 85, 39, -7, -3, -1, 114, 70, -1, 100, 23, -5, -1, 113, -1, 7,
+ 112, -1, 54, 99, -13, -9, -3, -1, 69, 84, -1, 68, -1, 6, 5,
+ -1, 38, 98, -5, -1, 97, -1, 22, 96, -3, -1, 53, 83, -1, 37,
+ 82, -17, -7, -3, -1, 21, 81, -1, 52, 67, -5, -3, -1, 80, 4,
+ 36, -1, 66, 20, -3, -1, 51, 65, -1, 35, 50, -11, -7, -5, -3,
+ -1, 64, 3, 48, 19, -1, 49, 34, -1, 18, 33, -7, -5, -3, -1,
+ 2, 32, 0, 17, -1, 1, 16
+};
+
+static short tab13[] =
+{
+-509,-503,-475,-405,-333,-265,-205,-153,-115, -83, -53, -35, -21, -13, -9,
+ -7, -5, -3, -1, 254, 252, 253, 237, 255, -1, 239, 223, -3, -1, 238,
+ 207, -1, 222, 191, -9, -3, -1, 251, 206, -1, 220, -1, 175, 233, -1,
+ 236, 221, -9, -5, -3, -1, 250, 205, 190, -1, 235, 159, -3, -1, 249,
+ 234, -1, 189, 219, -17, -9, -3, -1, 143, 248, -1, 204, -1, 174, 158,
+ -5, -1, 142, -1, 127, 126, 247, -5, -1, 218, -1, 173, 188, -3, -1,
+ 203, 246, 111, -15, -7, -3, -1, 232, 95, -1, 157, 217, -3, -1, 245,
+ 231, -1, 172, 187, -9, -3, -1, 79, 244, -3, -1, 202, 230, 243, -1,
+ 63, -1, 141, 216, -21, -9, -3, -1, 47, 242, -3, -1, 110, 156, 15,
+ -5, -3, -1, 201, 94, 171, -3, -1, 125, 215, 78, -11, -5, -3, -1,
+ 200, 214, 62, -1, 185, -1, 155, 170, -1, 31, 241, -23, -13, -5, -1,
+ 240, -1, 186, 229, -3, -1, 228, 140, -1, 109, 227, -5, -1, 226, -1,
+ 46, 14, -1, 30, 225, -15, -7, -3, -1, 224, 93, -1, 213, 124, -3,
+ -1, 199, 77, -1, 139, 184, -7, -3, -1, 212, 154, -1, 169, 108, -1,
+ 198, 61, -37, -21, -9, -5, -3, -1, 211, 123, 45, -1, 210, 29, -5,
+ -1, 183, -1, 92, 197, -3, -1, 153, 122, 195, -7, -5, -3, -1, 167,
+ 151, 75, 209, -3, -1, 13, 208, -1, 138, 168, -11, -7, -3, -1, 76,
+ 196, -1, 107, 182, -1, 60, 44, -3, -1, 194, 91, -3, -1, 181, 137,
+ 28, -43, -23, -11, -5, -1, 193, -1, 152, 12, -1, 192, -1, 180, 106,
+ -5, -3, -1, 166, 121, 59, -1, 179, -1, 136, 90, -11, -5, -1, 43,
+ -1, 165, 105, -1, 164, -1, 120, 135, -5, -1, 148, -1, 119, 118, 178,
+ -11, -3, -1, 27, 177, -3, -1, 11, 176, -1, 150, 74, -7, -3, -1,
+ 58, 163, -1, 89, 149, -1, 42, 162, -47, -23, -9, -3, -1, 26, 161,
+ -3, -1, 10, 104, 160, -5, -3, -1, 134, 73, 147, -3, -1, 57, 88,
+ -1, 133, 103, -9, -3, -1, 41, 146, -3, -1, 87, 117, 56, -5, -1,
+ 131, -1, 102, 71, -3, -1, 116, 86, -1, 101, 115, -11, -3, -1, 25,
+ 145, -3, -1, 9, 144, -1, 72, 132, -7, -5, -1, 114, -1, 70, 100,
+ 40, -1, 130, 24, -41, -27, -11, -5, -3, -1, 55, 39, 23, -1, 113,
+ -1, 85, 7, -7, -3, -1, 112, 54, -1, 99, 69, -3, -1, 84, 38,
+ -1, 98, 53, -5, -1, 129, -1, 8, 128, -3, -1, 22, 97, -1, 6,
+ 96, -13, -9, -5, -3, -1, 83, 68, 37, -1, 82, 5, -1, 21, 81,
+ -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, -19, -11,
+ -5, -1, 65, -1, 4, 64, -3, -1, 35, 50, 19, -3, -1, 49, 3,
+ -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16,
+ 0
+};
+
+static short tab15[] =
+{
+-495,-445,-355,-263,-183,-115, -77, -43, -27, -13, -7, -3, -1, 255, 239,
+ -1, 254, 223, -1, 238, -1, 253, 207, -7, -3, -1, 252, 222, -1, 237,
+ 191, -1, 251, -1, 206, 236, -7, -3, -1, 221, 175, -1, 250, 190, -3,
+ -1, 235, 205, -1, 220, 159, -15, -7, -3, -1, 249, 234, -1, 189, 219,
+ -3, -1, 143, 248, -1, 204, 158, -7, -3, -1, 233, 127, -1, 247, 173,
+ -3, -1, 218, 188, -1, 111, -1, 174, 15, -19, -11, -3, -1, 203, 246,
+ -3, -1, 142, 232, -1, 95, 157, -3, -1, 245, 126, -1, 231, 172, -9,
+ -3, -1, 202, 187, -3, -1, 217, 141, 79, -3, -1, 244, 63, -1, 243,
+ 216, -33, -17, -9, -3, -1, 230, 47, -1, 242, -1, 110, 240, -3, -1,
+ 31, 241, -1, 156, 201, -7, -3, -1, 94, 171, -1, 186, 229, -3, -1,
+ 125, 215, -1, 78, 228, -15, -7, -3, -1, 140, 200, -1, 62, 109, -3,
+ -1, 214, 227, -1, 155, 185, -7, -3, -1, 46, 170, -1, 226, 30, -5,
+ -1, 225, -1, 14, 224, -1, 93, 213, -45, -25, -13, -7, -3, -1, 124,
+ 199, -1, 77, 139, -1, 212, -1, 184, 154, -7, -3, -1, 169, 108, -1,
+ 198, 61, -1, 211, 210, -9, -5, -3, -1, 45, 13, 29, -1, 123, 183,
+ -5, -1, 209, -1, 92, 208, -1, 197, 138, -17, -7, -3, -1, 168, 76,
+ -1, 196, 107, -5, -1, 182, -1, 153, 12, -1, 60, 195, -9, -3, -1,
+ 122, 167, -1, 166, -1, 192, 11, -1, 194, -1, 44, 91, -55, -29, -15,
+ -7, -3, -1, 181, 28, -1, 137, 152, -3, -1, 193, 75, -1, 180, 106,
+ -5, -3, -1, 59, 121, 179, -3, -1, 151, 136, -1, 43, 90, -11, -5,
+ -1, 178, -1, 165, 27, -1, 177, -1, 176, 105, -7, -3, -1, 150, 74,
+ -1, 164, 120, -3, -1, 135, 58, 163, -17, -7, -3, -1, 89, 149, -1,
+ 42, 162, -3, -1, 26, 161, -3, -1, 10, 160, 104, -7, -3, -1, 134,
+ 73, -1, 148, 57, -5, -1, 147, -1, 119, 9, -1, 88, 133, -53, -29,
+ -13, -7, -3, -1, 41, 103, -1, 118, 146, -1, 145, -1, 25, 144, -7,
+ -3, -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 71, -7,
+ -3, -1, 40, 130, -1, 24, 129, -7, -3, -1, 116, 8, -1, 128, 86,
+ -3, -1, 101, 55, -1, 115, 70, -17, -7, -3, -1, 39, 114, -1, 100,
+ 23, -3, -1, 85, 113, -3, -1, 7, 112, 54, -7, -3, -1, 99, 69,
+ -1, 84, 38, -3, -1, 98, 22, -3, -1, 6, 96, 53, -33, -19, -9,
+ -5, -1, 97, -1, 83, 68, -1, 37, 82, -3, -1, 21, 81, -3, -1,
+ 5, 80, 52, -7, -3, -1, 67, 36, -1, 66, 51, -1, 65, -1, 20,
+ 4, -9, -3, -1, 35, 50, -3, -1, 64, 3, 19, -3, -1, 49, 48,
+ 34, -9, -7, -3, -1, 18, 33, -1, 2, 32, 17, -3, -1, 1, 16,
+ 0
+};
+
+static short tab16[] =
+{
+-509,-503,-461,-323,-103, -37, -27, -15, -7, -3, -1, 239, 254, -1, 223,
+ 253, -3, -1, 207, 252, -1, 191, 251, -5, -1, 175, -1, 250, 159, -3,
+ -1, 249, 248, 143, -7, -3, -1, 127, 247, -1, 111, 246, 255, -9, -5,
+ -3, -1, 95, 245, 79, -1, 244, 243, -53, -1, 240, -1, 63, -29, -19,
+ -13, -7, -5, -1, 206, -1, 236, 221, 222, -1, 233, -1, 234, 217, -1,
+ 238, -1, 237, 235, -3, -1, 190, 205, -3, -1, 220, 219, 174, -11, -5,
+ -1, 204, -1, 173, 218, -3, -1, 126, 172, 202, -5, -3, -1, 201, 125,
+ 94, 189, 242, -93, -5, -3, -1, 47, 15, 31, -1, 241, -49, -25, -13,
+ -5, -1, 158, -1, 188, 203, -3, -1, 142, 232, -1, 157, 231, -7, -3,
+ -1, 187, 141, -1, 216, 110, -1, 230, 156, -13, -7, -3, -1, 171, 186,
+ -1, 229, 215, -1, 78, -1, 228, 140, -3, -1, 200, 62, -1, 109, -1,
+ 214, 155, -19, -11, -5, -3, -1, 185, 170, 225, -1, 212, -1, 184, 169,
+ -5, -1, 123, -1, 183, 208, 227, -7, -3, -1, 14, 224, -1, 93, 213,
+ -3, -1, 124, 199, -1, 77, 139, -75, -45, -27, -13, -7, -3, -1, 154,
+ 108, -1, 198, 61, -3, -1, 92, 197, 13, -7, -3, -1, 138, 168, -1,
+ 153, 76, -3, -1, 182, 122, 60, -11, -5, -3, -1, 91, 137, 28, -1,
+ 192, -1, 152, 121, -1, 226, -1, 46, 30, -15, -7, -3, -1, 211, 45,
+ -1, 210, 209, -5, -1, 59, -1, 151, 136, 29, -7, -3, -1, 196, 107,
+ -1, 195, 167, -1, 44, -1, 194, 181, -23, -13, -7, -3, -1, 193, 12,
+ -1, 75, 180, -3, -1, 106, 166, 179, -5, -3, -1, 90, 165, 43, -1,
+ 178, 27, -13, -5, -1, 177, -1, 11, 176, -3, -1, 105, 150, -1, 74,
+ 164, -5, -3, -1, 120, 135, 163, -3, -1, 58, 89, 42, -97, -57, -33,
+ -19, -11, -5, -3, -1, 149, 104, 161, -3, -1, 134, 119, 148, -5, -3,
+ -1, 73, 87, 103, 162, -5, -1, 26, -1, 10, 160, -3, -1, 57, 147,
+ -1, 88, 133, -9, -3, -1, 41, 146, -3, -1, 118, 9, 25, -5, -1,
+ 145, -1, 144, 72, -3, -1, 132, 117, -1, 56, 131, -21, -11, -5, -3,
+ -1, 102, 40, 130, -3, -1, 71, 116, 24, -3, -1, 129, 128, -3, -1,
+ 8, 86, 55, -9, -5, -1, 115, -1, 101, 70, -1, 39, 114, -5, -3,
+ -1, 100, 85, 7, 23, -23, -13, -5, -1, 113, -1, 112, 54, -3, -1,
+ 99, 69, -1, 84, 38, -3, -1, 98, 22, -1, 97, -1, 6, 96, -9,
+ -5, -1, 83, -1, 53, 68, -1, 37, 82, -1, 81, -1, 21, 5, -33,
+ -23, -13, -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20,
+ -5, -1, 65, -1, 4, 64, -1, 35, 50, -3, -1, 19, 49, -3, -1,
+ 3, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16,
+ 0
+};
+
+static short tab24[] =
+{
+-451,-117, -43, -25, -15, -7, -3, -1, 239, 254, -1, 223, 253, -3, -1,
+ 207, 252, -1, 191, 251, -5, -1, 250, -1, 175, 159, -1, 249, 248, -9,
+ -5, -3, -1, 143, 127, 247, -1, 111, 246, -3, -1, 95, 245, -1, 79,
+ 244, -71, -7, -3, -1, 63, 243, -1, 47, 242, -5, -1, 241, -1, 31,
+ 240, -25, -9, -1, 15, -3, -1, 238, 222, -1, 237, 206, -7, -3, -1,
+ 236, 221, -1, 190, 235, -3, -1, 205, 220, -1, 174, 234, -15, -7, -3,
+ -1, 189, 219, -1, 204, 158, -3, -1, 233, 173, -1, 218, 188, -7, -3,
+ -1, 203, 142, -1, 232, 157, -3, -1, 217, 126, -1, 231, 172, 255,-235,
+-143, -77, -45, -25, -15, -7, -3, -1, 202, 187, -1, 141, 216, -5, -3,
+ -1, 14, 224, 13, 230, -5, -3, -1, 110, 156, 201, -1, 94, 186, -9,
+ -5, -1, 229, -1, 171, 125, -1, 215, 228, -3, -1, 140, 200, -3, -1,
+ 78, 46, 62, -15, -7, -3, -1, 109, 214, -1, 227, 155, -3, -1, 185,
+ 170, -1, 226, 30, -7, -3, -1, 225, 93, -1, 213, 124, -3, -1, 199,
+ 77, -1, 139, 184, -31, -15, -7, -3, -1, 212, 154, -1, 169, 108, -3,
+ -1, 198, 61, -1, 211, 45, -7, -3, -1, 210, 29, -1, 123, 183, -3,
+ -1, 209, 92, -1, 197, 138, -17, -7, -3, -1, 168, 153, -1, 76, 196,
+ -3, -1, 107, 182, -3, -1, 208, 12, 60, -7, -3, -1, 195, 122, -1,
+ 167, 44, -3, -1, 194, 91, -1, 181, 28, -57, -35, -19, -7, -3, -1,
+ 137, 152, -1, 193, 75, -5, -3, -1, 192, 11, 59, -3, -1, 176, 10,
+ 26, -5, -1, 180, -1, 106, 166, -3, -1, 121, 151, -3, -1, 160, 9,
+ 144, -9, -3, -1, 179, 136, -3, -1, 43, 90, 178, -7, -3, -1, 165,
+ 27, -1, 177, 105, -1, 150, 164, -17, -9, -5, -3, -1, 74, 120, 135,
+ -1, 58, 163, -3, -1, 89, 149, -1, 42, 162, -7, -3, -1, 161, 104,
+ -1, 134, 119, -3, -1, 73, 148, -1, 57, 147, -63, -31, -15, -7, -3,
+ -1, 88, 133, -1, 41, 103, -3, -1, 118, 146, -1, 25, 145, -7, -3,
+ -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 40, -17, -7,
+ -3, -1, 130, 24, -1, 71, 116, -5, -1, 129, -1, 8, 128, -1, 86,
+ 101, -7, -5, -1, 23, -1, 7, 112, 115, -3, -1, 55, 39, 114, -15,
+ -7, -3, -1, 70, 100, -1, 85, 113, -3, -1, 54, 99, -1, 69, 84,
+ -7, -3, -1, 38, 98, -1, 22, 97, -5, -3, -1, 6, 96, 53, -1,
+ 83, 68, -51, -37, -23, -15, -9, -3, -1, 37, 82, -1, 21, -1, 5,
+ 80, -1, 81, -1, 52, 67, -3, -1, 36, 66, -1, 51, 20, -9, -5,
+ -1, 65, -1, 4, 64, -1, 35, 50, -1, 19, 49, -7, -5, -3, -1,
+ 3, 48, 34, 18, -1, 33, -1, 2, 32, -3, -1, 17, 1, -1, 16,
+ 0
+};
+
+static short tab_c0[] =
+{
+ -29, -21, -13, -7, -3, -1, 11, 15, -1, 13, 14, -3, -1, 7, 5,
+ 9, -3, -1, 6, 3, -1, 10, 12, -3, -1, 2, 1, -1, 4, 8,
+ 0
+};
+
+static short tab_c1[] =
+{
+ -15, -7, -3, -1, 15, 14, -1, 13, 12, -3, -1, 11, 10, -1, 9,
+ 8, -7, -3, -1, 7, 6, -1, 5, 4, -3, -1, 3, 2, -1, 1,
+ 0
+};
+
+
+
+static struct newhuff ht[] =
+{
+ { /* 0 */ 0 , tab0 } ,
+ { /* 2 */ 0 , tab1 } ,
+ { /* 3 */ 0 , tab2 } ,
+ { /* 3 */ 0 , tab3 } ,
+ { /* 0 */ 0 , tab0 } ,
+ { /* 4 */ 0 , tab5 } ,
+ { /* 4 */ 0 , tab6 } ,
+ { /* 6 */ 0 , tab7 } ,
+ { /* 6 */ 0 , tab8 } ,
+ { /* 6 */ 0 , tab9 } ,
+ { /* 8 */ 0 , tab10 } ,
+ { /* 8 */ 0 , tab11 } ,
+ { /* 8 */ 0 , tab12 } ,
+ { /* 16 */ 0 , tab13 } ,
+ { /* 0 */ 0 , tab0 } ,
+ { /* 16 */ 0 , tab15 } ,
+
+ { /* 16 */ 1 , tab16 } ,
+ { /* 16 */ 2 , tab16 } ,
+ { /* 16 */ 3 , tab16 } ,
+ { /* 16 */ 4 , tab16 } ,
+ { /* 16 */ 6 , tab16 } ,
+ { /* 16 */ 8 , tab16 } ,
+ { /* 16 */ 10, tab16 } ,
+ { /* 16 */ 13, tab16 } ,
+ { /* 16 */ 4 , tab24 } ,
+ { /* 16 */ 5 , tab24 } ,
+ { /* 16 */ 6 , tab24 } ,
+ { /* 16 */ 7 , tab24 } ,
+ { /* 16 */ 8 , tab24 } ,
+ { /* 16 */ 9 , tab24 } ,
+ { /* 16 */ 11, tab24 } ,
+ { /* 16 */ 13, tab24 }
+};
+
+static struct newhuff htc[] =
+{
+ { /* 1 , 1 , */ 0 , tab_c0 } ,
+ { /* 1 , 1 , */ 0 , tab_c1 }
+};
+
+
diff --git a/src/libmpg123/interface.c b/src/libmpg123/interface.c
new file mode 100644
index 000000000..8f6a2118f
--- /dev/null
+++ b/src/libmpg123/interface.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2000 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ * The code is heavily based on libmpeg from mpg123
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: interface.c,v 1.1 2001/04/18 22:34:36 f1rmb Exp $
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "mpg123.h"
+#include "mpglib.h"
+
+void mpg_audio_reset (mpgaudio_t *mp) {
+
+ mp->framesize = 0;
+ mp->framesize_old = -1;
+ mp->bsize = 0;
+ mp->fr.single = -1;
+ mp->bsnum = 0;
+ mp->synth_bo = 1;
+ mp->is_output_initialized = 0;
+ mp->header = 0;
+}
+
+mpgaudio_t *mpg_audio_init (ao_functions_t *ao_output)
+{
+ mpgaudio_t *mp;
+
+ mp = malloc (sizeof(struct mpstr));
+ memset(mp, 0, sizeof(struct mpstr));
+
+ make_decode_tables(32767);
+ init_layer2();
+ init_layer3(SBLIMIT);
+
+ mp->ao_output = ao_output;
+
+ return mp;
+}
+
+int head_check(struct mpstr *mp)
+{
+ if( (mp->header & 0xffe00000) != 0xffe00000)
+ return 0;
+ if(!((mp->header>>17)&3))
+ return 0;
+ if( ((mp->header>>12)&0xf) == 0xf)
+ return 0;
+ if( ((mp->header>>10)&0x3) == 0x3 )
+ return 0;
+ return 1;
+}
+
+void mpg_audio_decode_data (mpgaudio_t *mp, uint8_t *data, uint8_t *data_end,
+ uint32_t pts)
+{
+ /* printf ("mpg123: decoding package\n"); */
+
+ uint32_t pts_for_package = 0;
+
+ /* pts = 0; */
+
+ while (1) {
+ /* sync */
+ if(mp->framesize == 0) {
+
+ /* printf ("mpg123: looking for header\n"); */
+
+ while (!head_check (mp)) {
+
+ if (data == data_end)
+ return;
+
+ mp->header = (mp->header << 8) | *data;
+ data++;
+ }
+
+ /* decode header */
+
+ decode_header(&mp->fr,mp->header);
+
+ mp->framesize = mp->fr.framesize;
+ mp->bsize = 0;
+ mpg123_wordpointer = mp->bsspace[mp->bsnum] + 512;
+ mp->bsnum = (mp->bsnum + 1) & 0x1;
+ mpg123_bitindex = 0;
+ pts_for_package = pts;
+ pts = 0;
+ }
+
+
+ /* printf ("mpg123: copying data\n"); */
+ /* copy data to bsspace */
+ while (mp->bsize<mp->framesize) {
+
+ if (data == data_end)
+ return;
+
+ *(mpg123_wordpointer + mp->bsize) = *data;
+ data++;
+ mp->bsize++;
+ }
+
+ if(mp->fr.error_protection)
+ getbits(16);
+
+ /* printf ("layer : %d\n",mp->fr.lay); */
+ switch(mp->fr.lay) {
+ case 1:
+ do_layer1(mp, pts_for_package);
+ break;
+ case 2:
+ do_layer2(mp, pts_for_package);
+ break;
+ case 3:
+ do_layer3(mp, pts_for_package);
+ break;
+ }
+
+ mp->framesize_old = mp->framesize;
+ mp->framesize = 0;
+ mp->header = 0;
+ pts_for_package = 0;
+ }
+}
+
+int set_pointer(mpgaudio_t *mp, long backstep)
+{
+ unsigned char *bsbufold;
+ if(mp->framesize_old < 0 && backstep > 0) {
+ fprintf(stderr,"Can't step back %ld!\n",backstep);
+ return 0;
+ }
+ bsbufold = mp->bsspace[mp->bsnum] + 512;
+ mpg123_wordpointer -= backstep;
+ if (backstep)
+ memcpy(mpg123_wordpointer,bsbufold+mp->framesize_old-backstep,backstep);
+ mpg123_bitindex = 0;
+ return 1;
+}
diff --git a/src/libmpg123/l2tables.h b/src/libmpg123/l2tables.h
new file mode 100644
index 000000000..06d21353b
--- /dev/null
+++ b/src/libmpg123/l2tables.h
@@ -0,0 +1,160 @@
+/*
+ * Layer 2 Alloc tables ..
+ * most other tables are calculated on program start (which is (of course)
+ * not ISO-conform) ..
+ * Layer-3 huffman table is in huffman.h
+ */
+
+struct al_table
+{
+ short bits;
+ short d;
+};
+
+struct al_table alloc_0[] = {
+ {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
+ {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
+ {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
+ {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
+ {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
+ {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767} };
+
+struct al_table alloc_1[] = {
+ {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
+ {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
+ {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
+ {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
+ {4,0},{5,3},{3,-3},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},{10,-511},
+ {11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {3,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767},
+ {2,0},{5,3},{7,5},{16,-32767} };
+
+struct al_table alloc_2[] = {
+ {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
+ {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
+ {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
+ {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} };
+
+struct al_table alloc_3[] = {
+ {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
+ {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
+ {4,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},{9,-255},
+ {10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},{15,-16383},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63} };
+
+struct al_table alloc_4[] = {
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
+ {4,0},{5,3},{7,5},{3,-3},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},{8,-127},
+ {9,-255},{10,-511},{11,-1023},{12,-2047},{13,-4095},{14,-8191},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {3,0},{5,3},{7,5},{10,9},{4,-7},{5,-15},{6,-31},{7,-63},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9},
+ {2,0},{5,3},{7,5},{10,9} };
+
diff --git a/src/libmpg123/layer1.c b/src/libmpg123/layer1.c
new file mode 100644
index 000000000..dad35766c
--- /dev/null
+++ b/src/libmpg123/layer1.c
@@ -0,0 +1,159 @@
+/*
+ * Mpeg Layer-1 audio decoder
+ * --------------------------
+ * copyright (c) 1995 by Michael Hipp, All rights reserved. See also 'README'
+ * near unoptimzed ...
+ *
+ * may have a few bugs after last optimization ...
+ *
+ */
+
+#include "mpg123.h"
+
+void I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT],struct frame *fr)
+{
+ unsigned int *ba=balloc;
+ unsigned int *sca = (unsigned int *) scale_index;
+
+ if(fr->stereo) {
+ int i;
+ int jsbound = fr->jsbound;
+ for (i=0;i<jsbound;i++) {
+ *ba++ = getbits(4);
+ *ba++ = getbits(4);
+ }
+ for (i=jsbound;i<SBLIMIT;i++)
+ *ba++ = getbits(4);
+
+ ba = balloc;
+
+ for (i=0;i<jsbound;i++) {
+ if ((*ba++))
+ *sca++ = getbits(6);
+ if ((*ba++))
+ *sca++ = getbits(6);
+ }
+ for (i=jsbound;i<SBLIMIT;i++)
+ if ((*ba++)) {
+ *sca++ = getbits(6);
+ *sca++ = getbits(6);
+ }
+ }
+ else {
+ int i;
+ for (i=0;i<SBLIMIT;i++)
+ *ba++ = getbits(4);
+ ba = balloc;
+ for (i=0;i<SBLIMIT;i++)
+ if ((*ba++))
+ *sca++ = getbits(6);
+ }
+}
+
+void I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT],
+ unsigned int scale_index[2][SBLIMIT],struct frame *fr)
+{
+ int i,n;
+ int smpb[2*SBLIMIT]; /* values: 0-65535 */
+ int *sample;
+ register unsigned int *ba;
+ register unsigned int *sca = (unsigned int *) scale_index;
+
+ if(fr->stereo) {
+ int jsbound = fr->jsbound;
+ register real *f0 = fraction[0];
+ register real *f1 = fraction[1];
+ ba = balloc;
+ for (sample=smpb,i=0;i<jsbound;i++) {
+ if ((n = *ba++))
+ *sample++ = getbits(n+1);
+ if ((n = *ba++))
+ *sample++ = getbits(n+1);
+ }
+ for (i=jsbound;i<SBLIMIT;i++)
+ if ((n = *ba++))
+ *sample++ = getbits(n+1);
+
+ ba = balloc;
+ for (sample=smpb,i=0;i<jsbound;i++) {
+ if((n=*ba++))
+ *f0++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
+ else
+ *f0++ = 0.0;
+ if((n=*ba++))
+ *f1++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
+ else
+ *f1++ = 0.0;
+ }
+ for (i=jsbound;i<SBLIMIT;i++) {
+ if ((n=*ba++)) {
+ real samp = ( ((-1)<<n) + (*sample++) + 1);
+ *f0++ = samp * muls[n+1][*sca++];
+ *f1++ = samp * muls[n+1][*sca++];
+ }
+ else
+ *f0++ = *f1++ = 0.0;
+ }
+ }
+ else {
+ register real *f0 = fraction[0];
+ ba = balloc;
+ for (sample=smpb,i=0;i<SBLIMIT;i++)
+ if ((n = *ba++))
+ *sample++ = getbits(n+1);
+ ba = balloc;
+ for (sample=smpb,i=0;i<SBLIMIT;i++) {
+ if((n=*ba++))
+ *f0++ = (real) ( ((-1)<<n) + (*sample++) + 1) * muls[n+1][*sca++];
+ else
+ *f0++ = 0.0;
+ }
+ }
+}
+
+void do_layer1(mpgaudio_t *mp, uint32_t pts)
+{
+ int clip=0;
+ struct frame *fr = &mp->fr;
+ int i,stereo = fr->stereo;
+ static unsigned int balloc[2*SBLIMIT];
+ static unsigned int scale_index[2][SBLIMIT];
+ static real fraction[2][SBLIMIT];
+ int single = fr->single;
+ int num_bytes;
+
+ fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ? (fr->mode_ext<<2)+4 : 32;
+
+ if(stereo == 1 || single == 3)
+ single = 0;
+
+ I_step_one(balloc,scale_index,fr);
+
+ num_bytes=0;
+ for (i=0;i<SCALE_BLOCK;i++)
+ {
+ I_step_two(fraction,balloc,scale_index,fr);
+
+ if(single >= 0) {
+ clip += synth_1to1_mono(mp, (real*)fraction[single],mp->osspace,&num_bytes);
+ }
+ else {
+ int p1 = num_bytes;
+ clip += synth_1to1(mp, (real*)fraction[0],0,mp->osspace,&p1);
+ clip += synth_1to1(mp, (real*)fraction[1],1,mp->osspace,&num_bytes);
+ }
+ }
+
+ if (!mp->is_output_initialized) {
+ mp->ao_output->open (16, fr->sample_rate,
+ stereo-1 ? AO_MODE_STEREO: AO_MODE_MONO);
+ mp->is_output_initialized = 1;
+
+ printf ("layer1\n");
+ }
+
+ mp->ao_output->write_audio_data ((int16_t*)mp->osspace, num_bytes/(stereo-1 ? 4:2), pts);
+
+}
+
+
diff --git a/src/libmpg123/layer2.c b/src/libmpg123/layer2.c
new file mode 100644
index 000000000..8c320f11b
--- /dev/null
+++ b/src/libmpg123/layer2.c
@@ -0,0 +1,300 @@
+/*
+ * Mpeg Layer-2 audio decoder
+ * --------------------------
+ * copyright (c) 1995 by Michael Hipp, All rights reserved. See also 'README'
+ *
+ */
+
+#include "mpg123.h"
+#include "l2tables.h"
+
+static int grp_3tab[32 * 3] = { 0, }; /* used: 27 */
+static int grp_5tab[128 * 3] = { 0, }; /* used: 125 */
+static int grp_9tab[1024 * 3] = { 0, }; /* used: 729 */
+
+real muls[27][64]; /* also used by layer 1 */
+
+void init_layer2(void)
+{
+ static double mulmul[27] = {
+ 0.0 , -2.0/3.0 , 2.0/3.0 ,
+ 2.0/7.0 , 2.0/15.0 , 2.0/31.0, 2.0/63.0 , 2.0/127.0 , 2.0/255.0 ,
+ 2.0/511.0 , 2.0/1023.0 , 2.0/2047.0 , 2.0/4095.0 , 2.0/8191.0 ,
+ 2.0/16383.0 , 2.0/32767.0 , 2.0/65535.0 ,
+ -4.0/5.0 , -2.0/5.0 , 2.0/5.0, 4.0/5.0 ,
+ -8.0/9.0 , -4.0/9.0 , -2.0/9.0 , 2.0/9.0 , 4.0/9.0 , 8.0/9.0 };
+ static int base[3][9] = {
+ { 1 , 0, 2 , } ,
+ { 17, 18, 0 , 19, 20 , } ,
+ { 21, 1, 22, 23, 0, 24, 25, 2, 26 } };
+ int i,j,k,l,len;
+ real *table;
+ static int tablen[3] = { 3 , 5 , 9 };
+ static int *itable,*tables[3] = { grp_3tab , grp_5tab , grp_9tab };
+
+ for(i=0;i<3;i++)
+ {
+ itable = tables[i];
+ len = tablen[i];
+ for(j=0;j<len;j++)
+ for(k=0;k<len;k++)
+ for(l=0;l<len;l++)
+ {
+ *itable++ = base[i][l];
+ *itable++ = base[i][k];
+ *itable++ = base[i][j];
+ }
+ }
+
+ for(k=0;k<27;k++)
+ {
+ double m=mulmul[k];
+ table = muls[k];
+ for(j=3,i=0;i<63;i++,j--)
+ *table++ = m * pow(2.0,(double) j / 3.0);
+ *table++ = 0.0;
+ }
+}
+
+
+void II_step_one(unsigned int *bit_alloc,int *scale,struct frame *fr)
+{
+ int stereo = fr->stereo-1;
+ int sblimit = fr->II_sblimit;
+ int jsbound = fr->jsbound;
+ int sblimit2 = fr->II_sblimit<<stereo;
+ struct al_table *alloc1 = fr->alloc;
+ int i;
+ static unsigned int scfsi_buf[64];
+ unsigned int *scfsi,*bita;
+ int sc,step;
+
+ bita = bit_alloc;
+ if(stereo)
+ {
+ for (i=jsbound;i;i--,alloc1+=(1<<step))
+ {
+ *bita++ = (char) getbits(step=alloc1->bits);
+ *bita++ = (char) getbits(step);
+ }
+ for (i=sblimit-jsbound;i;i--,alloc1+=(1<<step))
+ {
+ bita[0] = (char) getbits(step=alloc1->bits);
+ bita[1] = bita[0];
+ bita+=2;
+ }
+ bita = bit_alloc;
+ scfsi=scfsi_buf;
+ for (i=sblimit2;i;i--)
+ if (*bita++)
+ *scfsi++ = (char) getbits_fast(2);
+ }
+ else /* mono */
+ {
+ for (i=sblimit;i;i--,alloc1+=(1<<step))
+ *bita++ = (char) getbits(step=alloc1->bits);
+ bita = bit_alloc;
+ scfsi=scfsi_buf;
+ for (i=sblimit;i;i--)
+ if (*bita++)
+ *scfsi++ = (char) getbits_fast(2);
+ }
+
+ bita = bit_alloc;
+ scfsi=scfsi_buf;
+ for (i=sblimit2;i;i--)
+ if (*bita++)
+ switch (*scfsi++)
+ {
+ case 0:
+ *scale++ = getbits_fast(6);
+ *scale++ = getbits_fast(6);
+ *scale++ = getbits_fast(6);
+ break;
+ case 1 :
+ *scale++ = sc = getbits_fast(6);
+ *scale++ = sc;
+ *scale++ = getbits_fast(6);
+ break;
+ case 2:
+ *scale++ = sc = getbits_fast(6);
+ *scale++ = sc;
+ *scale++ = sc;
+ break;
+ default: /* case 3 */
+ *scale++ = getbits_fast(6);
+ *scale++ = sc = getbits_fast(6);
+ *scale++ = sc;
+ break;
+ }
+
+}
+
+void II_step_two(unsigned int *bit_alloc,real fraction[2][4][SBLIMIT],int *scale,struct frame *fr,int x1)
+{
+ int i,j,k,ba;
+ int stereo = fr->stereo;
+ int sblimit = fr->II_sblimit;
+ int jsbound = fr->jsbound;
+ struct al_table *alloc2,*alloc1 = fr->alloc;
+ unsigned int *bita=bit_alloc;
+ int d1,step;
+
+ for (i=0;i<jsbound;i++,alloc1+=(1<<step))
+ {
+ step = alloc1->bits;
+ for (j=0;j<stereo;j++)
+ {
+ if ( (ba=*bita++) )
+ {
+ k=(alloc2 = alloc1+ba)->bits;
+ if( (d1=alloc2->d) < 0)
+ {
+ real cm=muls[k][scale[x1]];
+ fraction[j][0][i] = ((real) ((int)getbits(k) + d1)) * cm;
+ fraction[j][1][i] = ((real) ((int)getbits(k) + d1)) * cm;
+ fraction[j][2][i] = ((real) ((int)getbits(k) + d1)) * cm;
+ }
+ else
+ {
+ static int *table[] = { 0,0,0,grp_3tab,0,grp_5tab,0,0,0,grp_9tab };
+ unsigned int idx,*tab,m=scale[x1];
+ idx = (unsigned int) getbits(k);
+ tab = (unsigned int *) (table[d1] + idx + idx + idx);
+ fraction[j][0][i] = muls[*tab++][m];
+ fraction[j][1][i] = muls[*tab++][m];
+ fraction[j][2][i] = muls[*tab][m];
+ }
+ scale+=3;
+ }
+ else
+ fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0;
+ }
+ }
+
+ for (i=jsbound;i<sblimit;i++,alloc1+=(1<<step))
+ {
+ step = alloc1->bits;
+ bita++; /* channel 1 and channel 2 bitalloc are the same */
+ if ( (ba=*bita++) )
+ {
+ k=(alloc2 = alloc1+ba)->bits;
+ if( (d1=alloc2->d) < 0)
+ {
+ real cm;
+ cm=muls[k][scale[x1+3]];
+ fraction[1][0][i] = (fraction[0][0][i] = (real) ((int)getbits(k) + d1) ) * cm;
+ fraction[1][1][i] = (fraction[0][1][i] = (real) ((int)getbits(k) + d1) ) * cm;
+ fraction[1][2][i] = (fraction[0][2][i] = (real) ((int)getbits(k) + d1) ) * cm;
+ cm=muls[k][scale[x1]];
+ fraction[0][0][i] *= cm; fraction[0][1][i] *= cm; fraction[0][2][i] *= cm;
+ }
+ else
+ {
+ static int *table[] = { 0,0,0,grp_3tab,0,grp_5tab,0,0,0,grp_9tab };
+ unsigned int idx,*tab,m1,m2;
+ m1 = scale[x1]; m2 = scale[x1+3];
+ idx = (unsigned int) getbits(k);
+ tab = (unsigned int *) (table[d1] + idx + idx + idx);
+ fraction[0][0][i] = muls[*tab][m1]; fraction[1][0][i] = muls[*tab++][m2];
+ fraction[0][1][i] = muls[*tab][m1]; fraction[1][1][i] = muls[*tab++][m2];
+ fraction[0][2][i] = muls[*tab][m1]; fraction[1][2][i] = muls[*tab][m2];
+ }
+ scale+=6;
+ }
+ else {
+ fraction[0][0][i] = fraction[0][1][i] = fraction[0][2][i] =
+ fraction[1][0][i] = fraction[1][1][i] = fraction[1][2][i] = 0.0;
+ }
+/*
+ should we use individual scalefac for channel 2 or
+ is the current way the right one , where we just copy channel 1 to
+ channel 2 ??
+ The current 'strange' thing is, that we throw away the scalefac
+ values for the second channel ...!!
+-> changed .. now we use the scalefac values of channel one !!
+*/
+ }
+
+ for(i=sblimit;i<SBLIMIT;i++)
+ for (j=0;j<stereo;j++)
+ fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0;
+
+}
+
+static void II_select_table(struct frame *fr)
+{
+ static int translate[3][2][16] =
+ { { { 0,2,2,2,2,2,2,0,0,0,1,1,1,1,1,0 } ,
+ { 0,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0 } } ,
+ { { 0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0 } ,
+ { 0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0 } } ,
+ { { 0,3,3,3,3,3,3,0,0,0,1,1,1,1,1,0 } ,
+ { 0,3,3,0,0,0,1,1,1,1,1,1,1,1,1,0 } } };
+
+ int table,sblim;
+ static struct al_table *tables[5] =
+ { alloc_0, alloc_1, alloc_2, alloc_3 , alloc_4 };
+ static int sblims[5] = { 27 , 30 , 8, 12 , 30 };
+
+ if(fr->lsf)
+ table = 4;
+ else
+ table = translate[fr->sampling_frequency][2-fr->stereo][fr->bitrate_index];
+ sblim = sblims[table];
+
+ fr->alloc = tables[table];
+ fr->II_sblimit = sblim;
+}
+
+void do_layer2(mpgaudio_t *mp, uint32_t pts)
+{
+ int clip=0;
+ int i,j;
+ struct frame *fr = &mp->fr;
+ int stereo = fr->stereo;
+ static real fraction[2][4][SBLIMIT]; /* pick_table clears unused subbands */
+ unsigned int bit_alloc[64];
+ int scale[192];
+ int single = fr->single;
+ int num_bytes;
+
+ II_select_table(fr);
+ fr->jsbound = (fr->mode == MPG_MD_JOINT_STEREO) ?
+ (fr->mode_ext<<2)+4 : fr->II_sblimit;
+
+ if(stereo == 1 || single == 3)
+ single = 0;
+
+ II_step_one(bit_alloc, scale, fr);
+
+ num_bytes=0;
+ for (i=0;i<SCALE_BLOCK;i++)
+ {
+ II_step_two(bit_alloc,fraction,scale,fr,i>>2);
+ for (j=0;j<3;j++) {
+ if(single >= 0) {
+ clip += synth_1to1_mono(mp, fraction[0][j],mp->osspace,&num_bytes);
+ }
+ else {
+ int p1 = num_bytes;
+ clip += synth_1to1(mp, fraction[0][j],0,mp->osspace,&p1);
+ clip += synth_1to1(mp, fraction[1][j],1,mp->osspace,&num_bytes);
+ }
+ }
+ }
+
+ if (!mp->is_output_initialized) {
+ mp->ao_output->open (16, fr->sample_rate,
+ stereo-1 ? AO_MODE_STEREO: AO_MODE_MONO);
+ mp->is_output_initialized = 1;
+
+ printf ("layer2\n");
+
+ }
+
+ mp->ao_output->write_audio_data ((int16_t*)mp->osspace, num_bytes/(stereo-1 ? 4:2), pts);
+
+}
+
+
diff --git a/src/libmpg123/layer3.c b/src/libmpg123/layer3.c
new file mode 100644
index 000000000..27fc7b547
--- /dev/null
+++ b/src/libmpg123/layer3.c
@@ -0,0 +1,1608 @@
+/*
+ * Mpeg Layer-3 audio decoder
+ * --------------------------
+ * copyright (c) 1995,1996,1997 by Michael Hipp.
+ * All rights reserved. See also 'README'
+ */
+
+#include <stdlib.h>
+#include "mpg123.h"
+#include "mpglib.h"
+#include "huffman.h"
+
+#define MPEG1
+
+
+static real ispow[8207];
+static real aa_ca[8],aa_cs[8];
+static real COS1[12][6];
+static real win[4][36];
+static real win1[4][36];
+static real gainpow2[256+118+4];
+static real COS9[9];
+static real COS6_1,COS6_2;
+static real tfcos36[9];
+static real tfcos12[3];
+
+struct bandInfoStruct {
+ short longIdx[23];
+ short longDiff[22];
+ short shortIdx[14];
+ short shortDiff[13];
+};
+
+int longLimit[9][23];
+int shortLimit[9][14];
+
+struct bandInfoStruct bandInfo[9] = {
+
+/* MPEG 1.0 */
+ { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576},
+ {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158},
+ {0,4*3,8*3,12*3,16*3,22*3,30*3,40*3,52*3,66*3, 84*3,106*3,136*3,192*3},
+ {4,4,4,4,6,8,10,12,14,18,22,30,56} } ,
+
+ { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576},
+ {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192},
+ {0,4*3,8*3,12*3,16*3,22*3,28*3,38*3,50*3,64*3, 80*3,100*3,126*3,192*3},
+ {4,4,4,4,6,6,10,12,14,16,20,26,66} } ,
+
+ { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} ,
+ {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} ,
+ {0,4*3,8*3,12*3,16*3,22*3,30*3,42*3,58*3,78*3,104*3,138*3,180*3,192*3} ,
+ {4,4,4,4,6,8,12,16,20,26,34,42,12} } ,
+
+/* MPEG 2.0 */
+ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
+ {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
+ {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} ,
+ {4,4,4,6,6,8,10,14,18,26,32,42,18 } } ,
+
+ { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576},
+ {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,70,76,36 } ,
+ {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,136*3,180*3,192*3} ,
+ {4,4,4,6,8,10,12,14,18,24,32,44,12 } } ,
+
+ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
+ {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 },
+ {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,134*3,174*3,192*3},
+ {4,4,4,6,8,10,12,14,18,24,30,40,18 } } ,
+/* MPEG 2.5 */
+ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} ,
+ {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54},
+ {0,12,24,36,54,78,108,144,186,240,312,402,522,576},
+ {4,4,4,6,8,10,12,14,18,24,30,40,18} },
+ { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} ,
+ {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54},
+ {0,12,24,36,54,78,108,144,186,240,312,402,522,576},
+ {4,4,4,6,8,10,12,14,18,24,30,40,18} },
+ { {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576},
+ {12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2},
+ {0, 24, 48, 72,108,156,216,288,372,480,486,492,498,576},
+ {8,8,8,12,16,20,24,28,36,2,2,2,26} } ,
+};
+
+static int mapbuf0[9][152];
+static int mapbuf1[9][156];
+static int mapbuf2[9][44];
+static int *map[9][3];
+static int *mapend[9][3];
+
+static unsigned int n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */
+static unsigned int i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */
+
+static real tan1_1[16],tan2_1[16],tan1_2[16],tan2_2[16];
+static real pow1_1[2][16],pow2_1[2][16],pow1_2[2][16],pow2_2[2][16];
+
+/*
+ * init tables for layer-3
+ */
+void init_layer3(int down_sample_sblimit)
+{
+ int i,j,k,l;
+
+ for(i=-256;i<118+4;i++)
+ gainpow2[i+256] = pow((double)2.0,-0.25 * (double) (i+210) );
+
+ for(i=0;i<8207;i++)
+ ispow[i] = pow((double)i,(double)4.0/3.0);
+
+ for (i=0;i<8;i++)
+ {
+ static double Ci[8]={-0.6,-0.535,-0.33,-0.185,-0.095,-0.041,-0.0142,-0.0037};
+ double sq=sqrt(1.0+Ci[i]*Ci[i]);
+ aa_cs[i] = 1.0/sq;
+ aa_ca[i] = Ci[i]/sq;
+ }
+
+ for(i=0;i<18;i++)
+ {
+ win[0][i] = win[1][i] = 0.5 * sin( M_PI / 72.0 * (double) (2*(i+0) +1) ) / cos ( M_PI * (double) (2*(i+0) +19) / 72.0 );
+ win[0][i+18] = win[3][i+18] = 0.5 * sin( M_PI / 72.0 * (double) (2*(i+18)+1) ) / cos ( M_PI * (double) (2*(i+18)+19) / 72.0 );
+ }
+ for(i=0;i<6;i++)
+ {
+ win[1][i+18] = 0.5 / cos ( M_PI * (double) (2*(i+18)+19) / 72.0 );
+ win[3][i+12] = 0.5 / cos ( M_PI * (double) (2*(i+12)+19) / 72.0 );
+ win[1][i+24] = 0.5 * sin( M_PI / 24.0 * (double) (2*i+13) ) / cos ( M_PI * (double) (2*(i+24)+19) / 72.0 );
+ win[1][i+30] = win[3][i] = 0.0;
+ win[3][i+6 ] = 0.5 * sin( M_PI / 24.0 * (double) (2*i+1) ) / cos ( M_PI * (double) (2*(i+6 )+19) / 72.0 );
+ }
+
+ for(i=0;i<9;i++)
+ COS9[i] = cos( M_PI / 18.0 * (double) i);
+
+ for(i=0;i<9;i++)
+ tfcos36[i] = 0.5 / cos ( M_PI * (double) (i*2+1) / 36.0 );
+ for(i=0;i<3;i++)
+ tfcos12[i] = 0.5 / cos ( M_PI * (double) (i*2+1) / 12.0 );
+
+ COS6_1 = cos( M_PI / 6.0 * (double) 1);
+ COS6_2 = cos( M_PI / 6.0 * (double) 2);
+
+ for(i=0;i<12;i++)
+ {
+ win[2][i] = 0.5 * sin( M_PI / 24.0 * (double) (2*i+1) ) / cos ( M_PI * (double) (2*i+7) / 24.0 );
+ for(j=0;j<6;j++)
+ COS1[i][j] = cos( M_PI / 24.0 * (double) ((2*i+7)*(2*j+1)) );
+ }
+
+ for(j=0;j<4;j++) {
+ static int len[4] = { 36,36,12,36 };
+ for(i=0;i<len[j];i+=2)
+ win1[j][i] = + win[j][i];
+ for(i=1;i<len[j];i+=2)
+ win1[j][i] = - win[j][i];
+ }
+
+ for(i=0;i<16;i++)
+ {
+ double t = tan( (double) i * M_PI / 12.0 );
+ tan1_1[i] = t / (1.0+t);
+ tan2_1[i] = 1.0 / (1.0 + t);
+ tan1_2[i] = M_SQRT2 * t / (1.0+t);
+ tan2_2[i] = M_SQRT2 / (1.0 + t);
+
+ for(j=0;j<2;j++) {
+ double base = pow(2.0,-0.25*(j+1.0));
+ double p1=1.0,p2=1.0;
+ if(i > 0) {
+ if( i & 1 )
+ p1 = pow(base,(i+1.0)*0.5);
+ else
+ p2 = pow(base,i*0.5);
+ }
+ pow1_1[j][i] = p1;
+ pow2_1[j][i] = p2;
+ pow1_2[j][i] = M_SQRT2 * p1;
+ pow2_2[j][i] = M_SQRT2 * p2;
+ }
+ }
+
+ for(j=0;j<9;j++)
+ {
+ struct bandInfoStruct *bi = &bandInfo[j];
+ int *mp;
+ int cb,lwin;
+ short *bdf;
+
+ mp = map[j][0] = mapbuf0[j];
+ bdf = bi->longDiff;
+ for(i=0,cb = 0; cb < 8 ; cb++,i+=*bdf++) {
+ *mp++ = (*bdf) >> 1;
+ *mp++ = i;
+ *mp++ = 3;
+ *mp++ = cb;
+ }
+ bdf = bi->shortDiff+3;
+ for(cb=3;cb<13;cb++) {
+ int l = (*bdf++) >> 1;
+ for(lwin=0;lwin<3;lwin++) {
+ *mp++ = l;
+ *mp++ = i + lwin;
+ *mp++ = lwin;
+ *mp++ = cb;
+ }
+ i += 6*l;
+ }
+ mapend[j][0] = mp;
+
+ mp = map[j][1] = mapbuf1[j];
+ bdf = bi->shortDiff+0;
+ for(i=0,cb=0;cb<13;cb++) {
+ int l = (*bdf++) >> 1;
+ for(lwin=0;lwin<3;lwin++) {
+ *mp++ = l;
+ *mp++ = i + lwin;
+ *mp++ = lwin;
+ *mp++ = cb;
+ }
+ i += 6*l;
+ }
+ mapend[j][1] = mp;
+
+ mp = map[j][2] = mapbuf2[j];
+ bdf = bi->longDiff;
+ for(cb = 0; cb < 22 ; cb++) {
+ *mp++ = (*bdf++) >> 1;
+ *mp++ = cb;
+ }
+ mapend[j][2] = mp;
+
+ }
+
+ for(j=0;j<9;j++) {
+ for(i=0;i<23;i++) {
+ longLimit[j][i] = (bandInfo[j].longIdx[i] - 1 + 8) / 18 + 1;
+ if(longLimit[j][i] > (down_sample_sblimit) )
+ longLimit[j][i] = down_sample_sblimit;
+ }
+ for(i=0;i<14;i++) {
+ shortLimit[j][i] = (bandInfo[j].shortIdx[i] - 1) / 18 + 1;
+ if(shortLimit[j][i] > (down_sample_sblimit) )
+ shortLimit[j][i] = down_sample_sblimit;
+ }
+ }
+
+ for(i=0;i<5;i++) {
+ for(j=0;j<6;j++) {
+ for(k=0;k<6;k++) {
+ int n = k + j * 6 + i * 36;
+ i_slen2[n] = i|(j<<3)|(k<<6)|(3<<12);
+ }
+ }
+ }
+ for(i=0;i<4;i++) {
+ for(j=0;j<4;j++) {
+ for(k=0;k<4;k++) {
+ int n = k + j * 4 + i * 16;
+ i_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12);
+ }
+ }
+ }
+ for(i=0;i<4;i++) {
+ for(j=0;j<3;j++) {
+ int n = j + i * 3;
+ i_slen2[n+244] = i|(j<<3) | (5<<12);
+ n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15);
+ }
+ }
+
+ for(i=0;i<5;i++) {
+ for(j=0;j<5;j++) {
+ for(k=0;k<4;k++) {
+ for(l=0;l<4;l++) {
+ int n = l + k * 4 + j * 16 + i * 80;
+ n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12);
+ }
+ }
+ }
+ }
+ for(i=0;i<5;i++) {
+ for(j=0;j<5;j++) {
+ for(k=0;k<4;k++) {
+ int n = k + j * 4 + i * 20;
+ n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12);
+ }
+ }
+ }
+}
+
+/*
+ * read additional side information
+ */
+#ifdef MPEG1
+static void III_get_side_info_1(struct III_sideinfo *si,int stereo,
+ int ms_stereo,long sfreq,int single)
+{
+ int ch, gr;
+ int powdiff = (single == 3) ? 4 : 0;
+
+ si->main_data_begin = getbits(9);
+ if (stereo == 1)
+ si->private_bits = getbits_fast(5);
+ else
+ si->private_bits = getbits_fast(3);
+
+ for (ch=0; ch<stereo; ch++) {
+ si->ch[ch].gr[0].scfsi = -1;
+ si->ch[ch].gr[1].scfsi = getbits_fast(4);
+ }
+
+ for (gr=0; gr<2; gr++)
+ {
+ for (ch=0; ch<stereo; ch++)
+ {
+ register struct gr_info_s *gr_info = &(si->ch[ch].gr[gr]);
+
+ gr_info->part2_3_length = getbits(12);
+ gr_info->big_values = getbits_fast(9);
+ if(gr_info->big_values > 288) {
+ fprintf(stderr,"big_values too large!\n");
+ gr_info->big_values = 288;
+ }
+ gr_info->pow2gain = gainpow2+256 - getbits_fast(8) + powdiff;
+ if(ms_stereo)
+ gr_info->pow2gain += 2;
+ gr_info->scalefac_compress = getbits_fast(4);
+/* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
+ if(get1bit())
+ {
+ int i;
+ gr_info->block_type = getbits_fast(2);
+ gr_info->mixed_block_flag = get1bit();
+ gr_info->table_select[0] = getbits_fast(5);
+ gr_info->table_select[1] = getbits_fast(5);
+ /*
+ * table_select[2] not needed, because there is no region2,
+ * but to satisfy some verifications tools we set it either.
+ */
+ gr_info->table_select[2] = 0;
+ for(i=0;i<3;i++)
+ gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast(3)<<3);
+
+ if(gr_info->block_type == 0) {
+ fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");
+ exit(1);
+ }
+ /* region_count/start parameters are implicit in this case. */
+ gr_info->region1start = 36>>1;
+ gr_info->region2start = 576>>1;
+ }
+ else
+ {
+ int i,r0c,r1c;
+ for (i=0; i<3; i++)
+ gr_info->table_select[i] = getbits_fast(5);
+ r0c = getbits_fast(4);
+ r1c = getbits_fast(3);
+ gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
+ gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
+ gr_info->block_type = 0;
+ gr_info->mixed_block_flag = 0;
+ }
+ gr_info->preflag = get1bit();
+ gr_info->scalefac_scale = get1bit();
+ gr_info->count1table_select = get1bit();
+ }
+ }
+}
+#endif
+
+/*
+ * Side Info for MPEG 2.0 / LSF
+ */
+static void III_get_side_info_2(struct III_sideinfo *si,int stereo,
+ int ms_stereo,long sfreq,int single)
+{
+ int ch;
+ int powdiff = (single == 3) ? 4 : 0;
+
+ si->main_data_begin = getbits(8);
+ if (stereo == 1)
+ si->private_bits = get1bit();
+ else
+ si->private_bits = getbits_fast(2);
+
+ for (ch=0; ch<stereo; ch++)
+ {
+ register struct gr_info_s *gr_info = &(si->ch[ch].gr[0]);
+
+ gr_info->part2_3_length = getbits(12);
+ gr_info->big_values = getbits_fast(9);
+ if(gr_info->big_values > 288) {
+ fprintf(stderr,"big_values too large!\n");
+ gr_info->big_values = 288;
+ }
+ gr_info->pow2gain = gainpow2+256 - getbits_fast(8) + powdiff;
+ if(ms_stereo)
+ gr_info->pow2gain += 2;
+ gr_info->scalefac_compress = getbits(9);
+/* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
+ if(get1bit())
+ {
+ int i;
+ gr_info->block_type = getbits_fast(2);
+ gr_info->mixed_block_flag = get1bit();
+ gr_info->table_select[0] = getbits_fast(5);
+ gr_info->table_select[1] = getbits_fast(5);
+ /*
+ * table_select[2] not needed, because there is no region2,
+ * but to satisfy some verifications tools we set it either.
+ */
+ gr_info->table_select[2] = 0;
+ for(i=0;i<3;i++)
+ gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast(3)<<3);
+
+ if(gr_info->block_type == 0) {
+ fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");
+ exit(1);
+ }
+ /* region_count/start parameters are implicit in this case. */
+/* check this again! */
+ if(gr_info->block_type == 2)
+ gr_info->region1start = 36>>1;
+ else if(sfreq == 8)
+/* check this for 2.5 and sfreq=8 */
+ gr_info->region1start = 108>>1;
+ else
+ gr_info->region1start = 54>>1;
+ gr_info->region2start = 576>>1;
+ }
+ else
+ {
+ int i,r0c,r1c;
+ for (i=0; i<3; i++)
+ gr_info->table_select[i] = getbits_fast(5);
+ r0c = getbits_fast(4);
+ r1c = getbits_fast(3);
+ gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
+ gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
+ gr_info->block_type = 0;
+ gr_info->mixed_block_flag = 0;
+ }
+ gr_info->scalefac_scale = get1bit();
+ gr_info->count1table_select = get1bit();
+ }
+}
+
+/*
+ * read scalefactors
+ */
+#ifdef MPEG1
+static int III_get_scale_factors_1(int *scf,struct gr_info_s *gr_info)
+{
+ static const unsigned char slen[2][16] = {
+ {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4},
+ {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3}
+ };
+ int numbits;
+ int num0 = slen[0][gr_info->scalefac_compress];
+ int num1 = slen[1][gr_info->scalefac_compress];
+
+ if (gr_info->block_type == 2) {
+ int i=18;
+ numbits = (num0 + num1) * 18;
+
+ if (gr_info->mixed_block_flag) {
+ for (i=8;i;i--)
+ *scf++ = getbits_fast(num0);
+ i = 9;
+ numbits -= num0; /* num0 * 17 + num1 * 18 */
+ }
+
+ for (;i;i--)
+ *scf++ = getbits_fast(num0);
+ for (i = 18; i; i--)
+ *scf++ = getbits_fast(num1);
+ *scf++ = 0; *scf++ = 0; *scf++ = 0; /* short[13][0..2] = 0 */
+ }
+ else {
+ int i;
+ int scfsi = gr_info->scfsi;
+
+ if(scfsi < 0) { /* scfsi < 0 => granule == 0 */
+ for(i=11;i;i--)
+ *scf++ = getbits_fast(num0);
+ for(i=10;i;i--)
+ *scf++ = getbits_fast(num1);
+ numbits = (num0 + num1) * 10 + num0;
+ *scf++ = 0;
+ }
+ else {
+ numbits = 0;
+ if(!(scfsi & 0x8)) {
+ for (i=0;i<6;i++)
+ *scf++ = getbits_fast(num0);
+ numbits += num0 * 6;
+ }
+ else {
+ scf += 6;
+ }
+
+ if(!(scfsi & 0x4)) {
+ for (i=0;i<5;i++)
+ *scf++ = getbits_fast(num0);
+ numbits += num0 * 5;
+ }
+ else {
+ scf += 5;
+ }
+
+ if(!(scfsi & 0x2)) {
+ for(i=0;i<5;i++)
+ *scf++ = getbits_fast(num1);
+ numbits += num1 * 5;
+ }
+ else {
+ scf += 5;
+ }
+
+ if(!(scfsi & 0x1)) {
+ for (i=0;i<5;i++)
+ *scf++ = getbits_fast(num1);
+ numbits += num1 * 5;
+ }
+ else {
+ scf += 5;
+ }
+ *scf++ = 0; /* no l[21] in original sources */
+ }
+ }
+ return numbits;
+}
+#endif
+
+
+static int III_get_scale_factors_2(int *scf,struct gr_info_s *gr_info,int i_stereo)
+{
+ unsigned char *pnt;
+ int i,j;
+ unsigned int slen;
+ int n = 0;
+ int numbits = 0;
+
+ static unsigned char stab[3][6][4] = {
+ { { 6, 5, 5,5 } , { 6, 5, 7,3 } , { 11,10,0,0} ,
+ { 7, 7, 7,0 } , { 6, 6, 6,3 } , { 8, 8,5,0} } ,
+ { { 9, 9, 9,9 } , { 9, 9,12,6 } , { 18,18,0,0} ,
+ {12,12,12,0 } , {12, 9, 9,6 } , { 15,12,9,0} } ,
+ { { 6, 9, 9,9 } , { 6, 9,12,6 } , { 15,18,0,0} ,
+ { 6,15,12,0 } , { 6,12, 9,6 } , { 6,18,9,0} } };
+
+ if(i_stereo) /* i_stereo AND second channel -> do_layer3() checks this */
+ slen = i_slen2[gr_info->scalefac_compress>>1];
+ else
+ slen = n_slen2[gr_info->scalefac_compress];
+
+ gr_info->preflag = (slen>>15) & 0x1;
+
+ n = 0;
+ if( gr_info->block_type == 2 ) {
+ n++;
+ if(gr_info->mixed_block_flag)
+ n++;
+ }
+
+ pnt = stab[n][(slen>>12)&0x7];
+
+ for(i=0;i<4;i++) {
+ int num = slen & 0x7;
+ slen >>= 3;
+ if(num) {
+ for(j=0;j<(int)(pnt[i]);j++)
+ *scf++ = getbits_fast(num);
+ numbits += pnt[i] * num;
+ }
+ else {
+ for(j=0;j<(int)(pnt[i]);j++)
+ *scf++ = 0;
+ }
+ }
+
+ n = (n << 1) + 1;
+ for(i=0;i<n;i++)
+ *scf++ = 0;
+
+ return numbits;
+}
+
+static int pretab1[22] = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0};
+static int pretab2[22] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+/*
+ * don't forget to apply the same changes to III_dequantize_sample_ms() !!!
+ */
+static int III_dequantize_sample(real xr[SBLIMIT][SSLIMIT],int *scf,
+ struct gr_info_s *gr_info,int sfreq,int part2bits)
+{
+ int shift = 1 + gr_info->scalefac_scale;
+ real *xrpnt = (real *) xr;
+ int l[3],l3;
+ int part2remain = gr_info->part2_3_length - part2bits;
+ int *me;
+
+ {
+ int bv = gr_info->big_values;
+ int region1 = gr_info->region1start;
+ int region2 = gr_info->region2start;
+
+ l3 = ((576>>1)-bv)>>1;
+/*
+ * we may lose the 'odd' bit here !!
+ * check this later again
+ */
+ if(bv <= region1) {
+ l[0] = bv; l[1] = 0; l[2] = 0;
+ }
+ else {
+ l[0] = region1;
+ if(bv <= region2) {
+ l[1] = bv - l[0]; l[2] = 0;
+ }
+ else {
+ l[1] = region2 - l[0]; l[2] = bv - region2;
+ }
+ }
+ }
+
+ if(gr_info->block_type == 2) {
+ /*
+ * decoding with short or mixed mode BandIndex table
+ */
+ int i,max[4];
+ int step=0,lwin=0,cb=0;
+ register real v = 0.0;
+ register int *m,mc;
+
+ if(gr_info->mixed_block_flag) {
+ max[3] = -1;
+ max[0] = max[1] = max[2] = 2;
+ m = map[sfreq][0];
+ me = mapend[sfreq][0];
+ }
+ else {
+ max[0] = max[1] = max[2] = max[3] = -1;
+ /* max[3] not really needed in this case */
+ m = map[sfreq][1];
+ me = mapend[sfreq][1];
+ }
+
+ mc = 0;
+ for(i=0;i<2;i++) {
+ int lp = l[i];
+ struct newhuff *h = ht+gr_info->table_select[i];
+ for(;lp;lp--,mc--) {
+ register int x,y;
+ if( (!mc) ) {
+ mc = *m++;
+ xrpnt = ((real *) xr) + (*m++);
+ lwin = *m++;
+ cb = *m++;
+ if(lwin == 3) {
+ v = gr_info->pow2gain[(*scf++) << shift];
+ step = 1;
+ }
+ else {
+ v = gr_info->full_gain[lwin][(*scf++) << shift];
+ step = 3;
+ }
+ }
+ {
+ register short *val = h->table;
+ while((y=*val++)<0) {
+ if (get1bit())
+ val -= y;
+ part2remain--;
+ }
+ x = y >> 4;
+ y &= 0xf;
+ }
+ if(x == 15) {
+ max[lwin] = cb;
+ part2remain -= h->linbits+1;
+ x += getbits(h->linbits);
+ if(get1bit())
+ *xrpnt = -ispow[x] * v;
+ else
+ *xrpnt = ispow[x] * v;
+ }
+ else if(x) {
+ max[lwin] = cb;
+ if(get1bit())
+ *xrpnt = -ispow[x] * v;
+ else
+ *xrpnt = ispow[x] * v;
+ part2remain--;
+ }
+ else
+ *xrpnt = 0.0;
+ xrpnt += step;
+ if(y == 15) {
+ max[lwin] = cb;
+ part2remain -= h->linbits+1;
+ y += getbits(h->linbits);
+ if(get1bit())
+ *xrpnt = -ispow[y] * v;
+ else
+ *xrpnt = ispow[y] * v;
+ }
+ else if(y) {
+ max[lwin] = cb;
+ if(get1bit())
+ *xrpnt = -ispow[y] * v;
+ else
+ *xrpnt = ispow[y] * v;
+ part2remain--;
+ }
+ else
+ *xrpnt = 0.0;
+ xrpnt += step;
+ }
+ }
+ for(;l3 && (part2remain > 0);l3--) {
+ struct newhuff *h = htc+gr_info->count1table_select;
+ register short *val = h->table,a;
+
+ while((a=*val++)<0) {
+ part2remain--;
+ if(part2remain < 0) {
+ part2remain++;
+ a = 0;
+ break;
+ }
+ if (get1bit())
+ val -= a;
+ }
+
+ for(i=0;i<4;i++) {
+ if(!(i & 1)) {
+ if(!mc) {
+ mc = *m++;
+ xrpnt = ((real *) xr) + (*m++);
+ lwin = *m++;
+ cb = *m++;
+ if(lwin == 3) {
+ v = gr_info->pow2gain[(*scf++) << shift];
+ step = 1;
+ }
+ else {
+ v = gr_info->full_gain[lwin][(*scf++) << shift];
+ step = 3;
+ }
+ }
+ mc--;
+ }
+ if( (a & (0x8>>i)) ) {
+ max[lwin] = cb;
+ part2remain--;
+ if(part2remain < 0) {
+ part2remain++;
+ break;
+ }
+ if(get1bit())
+ *xrpnt = -v;
+ else
+ *xrpnt = v;
+ }
+ else
+ *xrpnt = 0.0;
+ xrpnt += step;
+ }
+ }
+
+ while( m < me ) {
+ if(!mc) {
+ mc = *m++;
+ xrpnt = ((real *) xr) + *m++;
+ if( (*m++) == 3)
+ step = 1;
+ else
+ step = 3;
+ m++; /* cb */
+ }
+ mc--;
+ *xrpnt = 0.0;
+ xrpnt += step;
+ *xrpnt = 0.0;
+ xrpnt += step;
+/* we could add a little opt. here:
+ * if we finished a band for window 3 or a long band
+ * further bands could copied in a simple loop without a
+ * special 'map' decoding
+ */
+ }
+
+ gr_info->maxband[0] = max[0]+1;
+ gr_info->maxband[1] = max[1]+1;
+ gr_info->maxband[2] = max[2]+1;
+ gr_info->maxbandl = max[3]+1;
+
+ {
+ int rmax = max[0] > max[1] ? max[0] : max[1];
+ rmax = (rmax > max[2] ? rmax : max[2]) + 1;
+ gr_info->maxb = rmax ? shortLimit[sfreq][rmax] : longLimit[sfreq][max[3]+1];
+ }
+
+ }
+ else {
+ /*
+ * decoding with 'long' BandIndex table (block_type != 2)
+ */
+ int *pretab = gr_info->preflag ? pretab1 : pretab2;
+ int i,max = -1;
+ int cb = 0;
+ register int *m = map[sfreq][2];
+ register real v = 0.0;
+ register int mc = 0;
+#if 0
+ me = mapend[sfreq][2];
+#endif
+
+ /*
+ * long hash table values
+ */
+ for(i=0;i<3;i++) {
+ int lp = l[i];
+ struct newhuff *h = ht+gr_info->table_select[i];
+
+ for(;lp;lp--,mc--) {
+ int x,y;
+
+ if(!mc) {
+ mc = *m++;
+ v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift];
+ cb = *m++;
+ }
+ {
+ register short *val = h->table;
+ while((y=*val++)<0) {
+ if (get1bit())
+ val -= y;
+ part2remain--;
+ }
+ x = y >> 4;
+ y &= 0xf;
+ }
+ if (x == 15) {
+ max = cb;
+ part2remain -= h->linbits+1;
+ x += getbits(h->linbits);
+ if(get1bit())
+ *xrpnt++ = -ispow[x] * v;
+ else
+ *xrpnt++ = ispow[x] * v;
+ }
+ else if(x) {
+ max = cb;
+ if(get1bit())
+ *xrpnt++ = -ispow[x] * v;
+ else
+ *xrpnt++ = ispow[x] * v;
+ part2remain--;
+ }
+ else
+ *xrpnt++ = 0.0;
+
+ if (y == 15) {
+ max = cb;
+ part2remain -= h->linbits+1;
+ y += getbits(h->linbits);
+ if(get1bit())
+ *xrpnt++ = -ispow[y] * v;
+ else
+ *xrpnt++ = ispow[y] * v;
+ }
+ else if(y) {
+ max = cb;
+ if(get1bit())
+ *xrpnt++ = -ispow[y] * v;
+ else
+ *xrpnt++ = ispow[y] * v;
+ part2remain--;
+ }
+ else
+ *xrpnt++ = 0.0;
+ }
+ }
+
+ /*
+ * short (count1table) values
+ */
+ for(;l3 && (part2remain > 0);l3--) {
+ struct newhuff *h = htc+gr_info->count1table_select;
+ register short *val = h->table,a;
+
+ while((a=*val++)<0) {
+ part2remain--;
+ if(part2remain < 0) {
+ part2remain++;
+ a = 0;
+ break;
+ }
+ if (get1bit())
+ val -= a;
+ }
+
+ for(i=0;i<4;i++) {
+ if(!(i & 1)) {
+ if(!mc) {
+ mc = *m++;
+ cb = *m++;
+ v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift];
+ }
+ mc--;
+ }
+ if ( (a & (0x8>>i)) ) {
+ max = cb;
+ part2remain--;
+ if(part2remain < 0) {
+ part2remain++;
+ break;
+ }
+ if(get1bit())
+ *xrpnt++ = -v;
+ else
+ *xrpnt++ = v;
+ }
+ else
+ *xrpnt++ = 0.0;
+ }
+ }
+
+ /*
+ * zero part
+ */
+ for(i=(&xr[SBLIMIT][0]-xrpnt)>>1;i;i--) {
+ *xrpnt++ = 0.0;
+ *xrpnt++ = 0.0;
+ }
+
+ gr_info->maxbandl = max+1;
+ gr_info->maxb = longLimit[sfreq][gr_info->maxbandl];
+ }
+
+ while( part2remain > 16 ) {
+ getbits(16); /* Dismiss stuffing Bits */
+ part2remain -= 16;
+ }
+ if(part2remain > 0)
+ getbits(part2remain);
+ else if(part2remain < 0) {
+ fprintf(stderr,"mpg123: Can't rewind stream by %d bits!\n",-part2remain);
+ return 1; /* -> error */
+ }
+ return 0;
+}
+
+
+/*
+ * III_stereo: calculate real channel values for Joint-I-Stereo-mode
+ */
+static void III_i_stereo(real xr_buf[2][SBLIMIT][SSLIMIT],int *scalefac,
+ struct gr_info_s *gr_info,int sfreq,int ms_stereo,int lsf)
+{
+ real (*xr)[SBLIMIT*SSLIMIT] = (real (*)[SBLIMIT*SSLIMIT] ) xr_buf;
+ struct bandInfoStruct *bi = &bandInfo[sfreq];
+ real *tab1,*tab2;
+
+ if(lsf) {
+ int p = gr_info->scalefac_compress & 0x1;
+ if(ms_stereo) {
+ tab1 = pow1_2[p]; tab2 = pow2_2[p];
+ }
+ else {
+ tab1 = pow1_1[p]; tab2 = pow2_1[p];
+ }
+ }
+ else {
+ if(ms_stereo) {
+ tab1 = tan1_2; tab2 = tan2_2;
+ }
+ else {
+ tab1 = tan1_1; tab2 = tan2_1;
+ }
+ }
+
+ if (gr_info->block_type == 2)
+ {
+ int lwin,do_l = 0;
+ if( gr_info->mixed_block_flag )
+ do_l = 1;
+
+ for (lwin=0;lwin<3;lwin++) /* process each window */
+ {
+ /* get first band with zero values */
+ int is_p,sb,idx,sfb = gr_info->maxband[lwin]; /* sfb is minimal 3 for mixed mode */
+ if(sfb > 3)
+ do_l = 0;
+
+ for(;sfb<12;sfb++)
+ {
+ is_p = scalefac[sfb*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */
+ if(is_p != 7) {
+ real t1,t2;
+ sb = bi->shortDiff[sfb];
+ idx = bi->shortIdx[sfb] + lwin;
+ t1 = tab1[is_p]; t2 = tab2[is_p];
+ for (; sb > 0; sb--,idx+=3)
+ {
+ real v = xr[0][idx];
+ xr[0][idx] = v * t1;
+ xr[1][idx] = v * t2;
+ }
+ }
+ }
+
+/* in the original: copy 10 to 11 , here: copy 11 to 12
+maybe still wrong??? (copy 12 to 13?) */
+ is_p = scalefac[11*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */
+ sb = bi->shortDiff[12];
+ idx = bi->shortIdx[12] + lwin;
+
+ if(is_p != 7)
+ {
+ real t1,t2;
+ t1 = tab1[is_p]; t2 = tab2[is_p];
+ for ( ; sb > 0; sb--,idx+=3 )
+ {
+ real v = xr[0][idx];
+ xr[0][idx] = v * t1;
+ xr[1][idx] = v * t2;
+ }
+ }
+ } /* end for(lwin; .. ; . ) */
+
+ if (do_l)
+ {
+/* also check l-part, if ALL bands in the three windows are 'empty'
+ * and mode = mixed_mode
+ */
+ int sfb = gr_info->maxbandl;
+ int idx = bi->longIdx[sfb];
+
+ for ( ; sfb<8; sfb++ )
+ {
+ int sb = bi->longDiff[sfb];
+ int is_p = scalefac[sfb]; /* scale: 0-15 */
+ if(is_p != 7) {
+ real t1,t2;
+ t1 = tab1[is_p]; t2 = tab2[is_p];
+ for ( ; sb > 0; sb--,idx++)
+ {
+ real v = xr[0][idx];
+ xr[0][idx] = v * t1;
+ xr[1][idx] = v * t2;
+ }
+ }
+ else
+ idx += sb;
+ }
+ }
+ }
+ else /* ((gr_info->block_type != 2)) */
+ {
+ int sfb = gr_info->maxbandl;
+ int is_p,idx = bi->longIdx[sfb];
+ for ( ; sfb<21; sfb++)
+ {
+ int sb = bi->longDiff[sfb];
+ is_p = scalefac[sfb]; /* scale: 0-15 */
+ if(is_p != 7) {
+ real t1,t2;
+ t1 = tab1[is_p]; t2 = tab2[is_p];
+ for ( ; sb > 0; sb--,idx++)
+ {
+ real v = xr[0][idx];
+ xr[0][idx] = v * t1;
+ xr[1][idx] = v * t2;
+ }
+ }
+ else
+ idx += sb;
+ }
+
+ is_p = scalefac[20]; /* copy l-band 20 to l-band 21 */
+ if(is_p != 7)
+ {
+ int sb;
+ real t1 = tab1[is_p],t2 = tab2[is_p];
+
+ for ( sb = bi->longDiff[21]; sb > 0; sb--,idx++ )
+ {
+ real v = xr[0][idx];
+ xr[0][idx] = v * t1;
+ xr[1][idx] = v * t2;
+ }
+ }
+ } /* ... */
+}
+
+static void III_antialias(real xr[SBLIMIT][SSLIMIT],struct gr_info_s *gr_info)
+{
+ int sblim;
+
+ if(gr_info->block_type == 2)
+ {
+ if(!gr_info->mixed_block_flag)
+ return;
+ sblim = 1;
+ }
+ else {
+ sblim = gr_info->maxb-1;
+ }
+
+ /* 31 alias-reduction operations between each pair of sub-bands */
+ /* with 8 butterflies between each pair */
+
+ {
+ int sb;
+ real *xr1=(real *) xr[1];
+
+ for(sb=sblim;sb;sb--,xr1+=10)
+ {
+ int ss;
+ real *cs=aa_cs,*ca=aa_ca;
+ real *xr2 = xr1;
+
+ for(ss=7;ss>=0;ss--)
+ { /* upper and lower butterfly inputs */
+ register real bu = *--xr2,bd = *xr1;
+ *xr2 = (bu * (*cs) ) - (bd * (*ca) );
+ *xr1++ = (bd * (*cs++) ) + (bu * (*ca++) );
+ }
+ }
+ }
+}
+
+/*
+ DCT insipired by Jeff Tsay's DCT from the maplay package
+ this is an optimized version with manual unroll.
+
+ References:
+ [1] S. Winograd: "On Computing the Discrete Fourier Transform",
+ Mathematics of Computation, Volume 32, Number 141, January 1978,
+ Pages 175-199
+*/
+
+static void dct36(real *inbuf,real *o1,real *o2,real *wintab,real *tsbuf)
+{
+ {
+ register real *in = inbuf;
+
+ in[17]+=in[16]; in[16]+=in[15]; in[15]+=in[14];
+ in[14]+=in[13]; in[13]+=in[12]; in[12]+=in[11];
+ in[11]+=in[10]; in[10]+=in[9]; in[9] +=in[8];
+ in[8] +=in[7]; in[7] +=in[6]; in[6] +=in[5];
+ in[5] +=in[4]; in[4] +=in[3]; in[3] +=in[2];
+ in[2] +=in[1]; in[1] +=in[0];
+
+ in[17]+=in[15]; in[15]+=in[13]; in[13]+=in[11]; in[11]+=in[9];
+ in[9] +=in[7]; in[7] +=in[5]; in[5] +=in[3]; in[3] +=in[1];
+
+
+ {
+
+#define MACRO0(v) { \
+ real tmp; \
+ out2[9+(v)] = (tmp = sum0 + sum1) * w[27+(v)]; \
+ out2[8-(v)] = tmp * w[26-(v)]; } \
+ sum0 -= sum1; \
+ ts[SBLIMIT*(8-(v))] = out1[8-(v)] + sum0 * w[8-(v)]; \
+ ts[SBLIMIT*(9+(v))] = out1[9+(v)] + sum0 * w[9+(v)];
+#define MACRO1(v) { \
+ real sum0,sum1; \
+ sum0 = tmp1a + tmp2a; \
+ sum1 = (tmp1b + tmp2b) * tfcos36[(v)]; \
+ MACRO0(v); }
+#define MACRO2(v) { \
+ real sum0,sum1; \
+ sum0 = tmp2a - tmp1a; \
+ sum1 = (tmp2b - tmp1b) * tfcos36[(v)]; \
+ MACRO0(v); }
+
+ register const real *c = COS9;
+ register real *out2 = o2;
+ register real *w = wintab;
+ register real *out1 = o1;
+ register real *ts = tsbuf;
+
+ real ta33,ta66,tb33,tb66;
+
+ ta33 = in[2*3+0] * c[3];
+ ta66 = in[2*6+0] * c[6];
+ tb33 = in[2*3+1] * c[3];
+ tb66 = in[2*6+1] * c[6];
+
+ {
+ real tmp1a,tmp2a,tmp1b,tmp2b;
+ tmp1a = in[2*1+0] * c[1] + ta33 + in[2*5+0] * c[5] + in[2*7+0] * c[7];
+ tmp1b = in[2*1+1] * c[1] + tb33 + in[2*5+1] * c[5] + in[2*7+1] * c[7];
+ tmp2a = in[2*0+0] + in[2*2+0] * c[2] + in[2*4+0] * c[4] + ta66 + in[2*8+0] * c[8];
+ tmp2b = in[2*0+1] + in[2*2+1] * c[2] + in[2*4+1] * c[4] + tb66 + in[2*8+1] * c[8];
+
+ MACRO1(0);
+ MACRO2(8);
+ }
+
+ {
+ real tmp1a,tmp2a,tmp1b,tmp2b;
+ tmp1a = ( in[2*1+0] - in[2*5+0] - in[2*7+0] ) * c[3];
+ tmp1b = ( in[2*1+1] - in[2*5+1] - in[2*7+1] ) * c[3];
+ tmp2a = ( in[2*2+0] - in[2*4+0] - in[2*8+0] ) * c[6] - in[2*6+0] + in[2*0+0];
+ tmp2b = ( in[2*2+1] - in[2*4+1] - in[2*8+1] ) * c[6] - in[2*6+1] + in[2*0+1];
+
+ MACRO1(1);
+ MACRO2(7);
+ }
+
+ {
+ real tmp1a,tmp2a,tmp1b,tmp2b;
+ tmp1a = in[2*1+0] * c[5] - ta33 - in[2*5+0] * c[7] + in[2*7+0] * c[1];
+ tmp1b = in[2*1+1] * c[5] - tb33 - in[2*5+1] * c[7] + in[2*7+1] * c[1];
+ tmp2a = in[2*0+0] - in[2*2+0] * c[8] - in[2*4+0] * c[2] + ta66 + in[2*8+0] * c[4];
+ tmp2b = in[2*0+1] - in[2*2+1] * c[8] - in[2*4+1] * c[2] + tb66 + in[2*8+1] * c[4];
+
+ MACRO1(2);
+ MACRO2(6);
+ }
+
+ {
+ real tmp1a,tmp2a,tmp1b,tmp2b;
+ tmp1a = in[2*1+0] * c[7] - ta33 + in[2*5+0] * c[1] - in[2*7+0] * c[5];
+ tmp1b = in[2*1+1] * c[7] - tb33 + in[2*5+1] * c[1] - in[2*7+1] * c[5];
+ tmp2a = in[2*0+0] - in[2*2+0] * c[4] + in[2*4+0] * c[8] + ta66 - in[2*8+0] * c[2];
+ tmp2b = in[2*0+1] - in[2*2+1] * c[4] + in[2*4+1] * c[8] + tb66 - in[2*8+1] * c[2];
+
+ MACRO1(3);
+ MACRO2(5);
+ }
+
+ {
+ real sum0,sum1;
+ sum0 = in[2*0+0] - in[2*2+0] + in[2*4+0] - in[2*6+0] + in[2*8+0];
+ sum1 = (in[2*0+1] - in[2*2+1] + in[2*4+1] - in[2*6+1] + in[2*8+1] ) * tfcos36[4];
+ MACRO0(4);
+ }
+ }
+
+ }
+}
+
+/*
+ * new DCT12
+ */
+static void dct12(real *in,real *rawout1,real *rawout2,register real *wi,register real *ts)
+{
+#define DCT12_PART1 \
+ in5 = in[5*3]; \
+ in5 += (in4 = in[4*3]); \
+ in4 += (in3 = in[3*3]); \
+ in3 += (in2 = in[2*3]); \
+ in2 += (in1 = in[1*3]); \
+ in1 += (in0 = in[0*3]); \
+ \
+ in5 += in3; in3 += in1; \
+ \
+ in2 *= COS6_1; \
+ in3 *= COS6_1; \
+
+#define DCT12_PART2 \
+ in0 += in4 * COS6_2; \
+ \
+ in4 = in0 + in2; \
+ in0 -= in2; \
+ \
+ in1 += in5 * COS6_2; \
+ \
+ in5 = (in1 + in3) * tfcos12[0]; \
+ in1 = (in1 - in3) * tfcos12[2]; \
+ \
+ in3 = in4 + in5; \
+ in4 -= in5; \
+ \
+ in2 = in0 + in1; \
+ in0 -= in1;
+
+
+ {
+ real in0,in1,in2,in3,in4,in5;
+ register real *out1 = rawout1;
+ ts[SBLIMIT*0] = out1[0]; ts[SBLIMIT*1] = out1[1]; ts[SBLIMIT*2] = out1[2];
+ ts[SBLIMIT*3] = out1[3]; ts[SBLIMIT*4] = out1[4]; ts[SBLIMIT*5] = out1[5];
+
+ DCT12_PART1
+
+ {
+ real tmp0,tmp1 = (in0 - in4);
+ {
+ real tmp2 = (in1 - in5) * tfcos12[1];
+ tmp0 = tmp1 + tmp2;
+ tmp1 -= tmp2;
+ }
+ ts[(17-1)*SBLIMIT] = out1[17-1] + tmp0 * wi[11-1];
+ ts[(12+1)*SBLIMIT] = out1[12+1] + tmp0 * wi[6+1];
+ ts[(6 +1)*SBLIMIT] = out1[6 +1] + tmp1 * wi[1];
+ ts[(11-1)*SBLIMIT] = out1[11-1] + tmp1 * wi[5-1];
+ }
+
+ DCT12_PART2
+
+ ts[(17-0)*SBLIMIT] = out1[17-0] + in2 * wi[11-0];
+ ts[(12+0)*SBLIMIT] = out1[12+0] + in2 * wi[6+0];
+ ts[(12+2)*SBLIMIT] = out1[12+2] + in3 * wi[6+2];
+ ts[(17-2)*SBLIMIT] = out1[17-2] + in3 * wi[11-2];
+
+ ts[(6+0)*SBLIMIT] = out1[6+0] + in0 * wi[0];
+ ts[(11-0)*SBLIMIT] = out1[11-0] + in0 * wi[5-0];
+ ts[(6+2)*SBLIMIT] = out1[6+2] + in4 * wi[2];
+ ts[(11-2)*SBLIMIT] = out1[11-2] + in4 * wi[5-2];
+ }
+
+ in++;
+
+ {
+ real in0,in1,in2,in3,in4,in5;
+ register real *out2 = rawout2;
+
+ DCT12_PART1
+
+ {
+ real tmp0,tmp1 = (in0 - in4);
+ {
+ real tmp2 = (in1 - in5) * tfcos12[1];
+ tmp0 = tmp1 + tmp2;
+ tmp1 -= tmp2;
+ }
+ out2[5-1] = tmp0 * wi[11-1];
+ out2[0+1] = tmp0 * wi[6+1];
+ ts[(12+1)*SBLIMIT] += tmp1 * wi[1];
+ ts[(17-1)*SBLIMIT] += tmp1 * wi[5-1];
+ }
+
+ DCT12_PART2
+
+ out2[5-0] = in2 * wi[11-0];
+ out2[0+0] = in2 * wi[6+0];
+ out2[0+2] = in3 * wi[6+2];
+ out2[5-2] = in3 * wi[11-2];
+
+ ts[(12+0)*SBLIMIT] += in0 * wi[0];
+ ts[(17-0)*SBLIMIT] += in0 * wi[5-0];
+ ts[(12+2)*SBLIMIT] += in4 * wi[2];
+ ts[(17-2)*SBLIMIT] += in4 * wi[5-2];
+ }
+
+ in++;
+
+ {
+ real in0,in1,in2,in3,in4,in5;
+ register real *out2 = rawout2;
+ out2[12]=out2[13]=out2[14]=out2[15]=out2[16]=out2[17]=0.0;
+
+ DCT12_PART1
+
+ {
+ real tmp0,tmp1 = (in0 - in4);
+ {
+ real tmp2 = (in1 - in5) * tfcos12[1];
+ tmp0 = tmp1 + tmp2;
+ tmp1 -= tmp2;
+ }
+ out2[11-1] = tmp0 * wi[11-1];
+ out2[6 +1] = tmp0 * wi[6+1];
+ out2[0+1] += tmp1 * wi[1];
+ out2[5-1] += tmp1 * wi[5-1];
+ }
+
+ DCT12_PART2
+
+ out2[11-0] = in2 * wi[11-0];
+ out2[6 +0] = in2 * wi[6+0];
+ out2[6 +2] = in3 * wi[6+2];
+ out2[11-2] = in3 * wi[11-2];
+
+ out2[0+0] += in0 * wi[0];
+ out2[5-0] += in0 * wi[5-0];
+ out2[0+2] += in4 * wi[2];
+ out2[5-2] += in4 * wi[5-2];
+ }
+}
+
+/*
+ * III_hybrid
+ */
+static void III_hybrid(mpgaudio_t *mp,
+ real fsIn[SBLIMIT][SSLIMIT],
+ real tsOut[SSLIMIT][SBLIMIT],
+ int ch,struct gr_info_s *gr_info)
+{
+ real *tspnt = (real *) tsOut;
+ real (*block)[2][SBLIMIT*SSLIMIT] = mp->hybrid_block;
+ int *blc = mp->hybrid_blc;
+ real *rawout1,*rawout2;
+ int bt;
+ int sb = 0;
+
+ {
+ int b = blc[ch];
+ rawout1=block[b][ch];
+ b=-b+1;
+ rawout2=block[b][ch];
+ blc[ch] = b;
+ }
+
+
+ if(gr_info->mixed_block_flag) {
+ sb = 2;
+ dct36(fsIn[0],rawout1,rawout2,win[0],tspnt);
+ dct36(fsIn[1],rawout1+18,rawout2+18,win1[0],tspnt+1);
+ rawout1 += 36; rawout2 += 36; tspnt += 2;
+ }
+
+ bt = gr_info->block_type;
+ if(bt == 2) {
+ for (; sb<gr_info->maxb; sb+=2,tspnt+=2,rawout1+=36,rawout2+=36) {
+ dct12(fsIn[sb],rawout1,rawout2,win[2],tspnt);
+ dct12(fsIn[sb+1],rawout1+18,rawout2+18,win1[2],tspnt+1);
+ }
+ }
+ else {
+ for (; sb<gr_info->maxb; sb+=2,tspnt+=2,rawout1+=36,rawout2+=36) {
+ dct36(fsIn[sb],rawout1,rawout2,win[bt],tspnt);
+ dct36(fsIn[sb+1],rawout1+18,rawout2+18,win1[bt],tspnt+1);
+ }
+ }
+
+ for(;sb<SBLIMIT;sb++,tspnt++) {
+ int i;
+ for(i=0;i<SSLIMIT;i++) {
+ tspnt[i*SBLIMIT] = *rawout1++;
+ *rawout2++ = 0.0;
+ }
+ }
+}
+
+/*
+ * main layer3 handler
+ */
+void do_layer3(mpgaudio_t *mp, uint32_t pts)
+{
+ int gr, ch, ss,clip=0;
+ struct frame *fr = &mp->fr;
+ static int scalefacs[2][39]; /* max 39 for short[13][3] mode, mixed: 38, long: 22 */
+ struct III_sideinfo sideinfo;
+ int stereo = fr->stereo;
+ int single = fr->single;
+ int ms_stereo,i_stereo;
+ int sfreq = fr->sampling_frequency;
+ int stereo1,granules;
+ int num_bytes;
+
+ if(stereo == 1) { /* stream is mono */
+ stereo1 = 1;
+ single = 0;
+ }
+ else if(single >= 0) /* stream is stereo, but force to mono */
+ stereo1 = 1;
+ else
+ stereo1 = 2;
+
+ if(fr->mode == MPG_MD_JOINT_STEREO) {
+ ms_stereo = fr->mode_ext & 0x2;
+ i_stereo = fr->mode_ext & 0x1;
+ }
+ else
+ ms_stereo = i_stereo = 0;
+
+ if(fr->lsf) {
+ granules = 1;
+ III_get_side_info_2(&sideinfo,stereo,ms_stereo,sfreq,single);
+ }
+ else {
+ granules = 2;
+#ifdef MPEG1
+ III_get_side_info_1(&sideinfo,stereo,ms_stereo,sfreq,single);
+#else
+ fprintf(stderr,"Not supported\n");
+#endif
+ }
+
+ if(!set_pointer(mp, sideinfo.main_data_begin)) {
+ printf ("set pointer failed.\n");
+ return;
+ }
+
+ num_bytes = 0 ;
+
+ for (gr=0;gr<granules;gr++)
+ {
+ real hybridIn[2][SBLIMIT][SSLIMIT];
+ real hybridOut[2][SSLIMIT][SBLIMIT];
+
+ {
+ struct gr_info_s *gr_info = &(sideinfo.ch[0].gr[gr]);
+ long part2bits;
+ if(fr->lsf)
+ part2bits = III_get_scale_factors_2(scalefacs[0],gr_info,0);
+ else {
+#ifdef MPEG1
+ part2bits = III_get_scale_factors_1(scalefacs[0],gr_info);
+#else
+ fprintf(stderr,"Not supported\n");
+#endif
+ }
+ if(III_dequantize_sample(hybridIn[0], scalefacs[0],gr_info,sfreq,part2bits)) {
+ printf ("III_dequantize_sample failed.\n");
+ return;
+ }
+ }
+ if(stereo == 2) {
+ struct gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]);
+ long part2bits;
+ if(fr->lsf)
+ part2bits = III_get_scale_factors_2(scalefacs[1],gr_info,i_stereo);
+ else {
+#ifdef MPEG1
+ part2bits = III_get_scale_factors_1(scalefacs[1],gr_info);
+#else
+ fprintf(stderr,"Not supported\n");
+#endif
+ }
+
+ if(III_dequantize_sample(hybridIn[1],scalefacs[1],gr_info,sfreq,part2bits)) {
+ printf ("III_dequantize_sample failed.\n");
+ return;
+ }
+
+ if(ms_stereo) {
+ int i;
+ for(i=0;i<SBLIMIT*SSLIMIT;i++) {
+ real tmp0,tmp1;
+ tmp0 = ((real *) hybridIn[0])[i];
+ tmp1 = ((real *) hybridIn[1])[i];
+ ((real *) hybridIn[0])[i] = tmp0 + tmp1;
+ ((real *) hybridIn[1])[i] = tmp0 - tmp1;
+ }
+ }
+
+ if(i_stereo)
+ III_i_stereo(hybridIn,scalefacs[1],gr_info,sfreq,ms_stereo,fr->lsf);
+
+ if(ms_stereo || i_stereo || (single == 3) ) {
+ if(gr_info->maxb > sideinfo.ch[0].gr[gr].maxb)
+ sideinfo.ch[0].gr[gr].maxb = gr_info->maxb;
+ else
+ gr_info->maxb = sideinfo.ch[0].gr[gr].maxb;
+ }
+
+ switch(single) {
+ case 3:
+ {
+ register int i;
+ register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1];
+ for(i=0;i<SSLIMIT*gr_info->maxb;i++,in0++)
+ *in0 = (*in0 + *in1++); /* *0.5 done by pow-scale */
+ }
+ break;
+ case 1:
+ {
+ register int i;
+ register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1];
+ for(i=0;i<SSLIMIT*gr_info->maxb;i++)
+ *in0++ = *in1++;
+ }
+ break;
+ }
+ }
+
+ for(ch=0;ch<stereo1;ch++) {
+ struct gr_info_s *gr_info = &(sideinfo.ch[ch].gr[gr]);
+ III_antialias(hybridIn[ch],gr_info);
+ III_hybrid(mp, hybridIn[ch], hybridOut[ch], ch,gr_info);
+ }
+
+ for(ss=0;ss<SSLIMIT;ss++) {
+ if(single >= 0) {
+ clip += synth_1to1_mono(mp, hybridOut[0][ss],mp->osspace,&num_bytes);
+ }
+ else {
+ int p1 = num_bytes;
+ clip += synth_1to1(mp, hybridOut[0][ss],0,mp->osspace,&p1);
+ clip += synth_1to1(mp, hybridOut[1][ss],1,mp->osspace,&num_bytes);
+ }
+ }
+ }
+
+ if (!mp->is_output_initialized) {
+ mp->ao_output->open (16, fr->sample_rate,
+ stereo-1 ? AO_MODE_STEREO: AO_MODE_MONO);
+ mp->is_output_initialized = 1;
+
+ printf ("layer3\n");
+ }
+
+ mp->ao_output->write_audio_data ((int16_t*)mp->osspace, num_bytes/(stereo-1 ? 4:2), pts);
+}
+
+
diff --git a/src/libmpg123/main.c b/src/libmpg123/main.c
new file mode 100644
index 000000000..afe938802
--- /dev/null
+++ b/src/libmpg123/main.c
@@ -0,0 +1,29 @@
+
+#include "mpg123.h"
+#include "mpglib.h"
+
+char buf[16384];
+struct mpstr mp;
+
+void main(void)
+{
+ int size;
+ char out[8192];
+ int len,ret;
+
+
+ InitMP3(&mp);
+
+ while(1) {
+ len = read(0,buf,16384);
+ if(len <= 0)
+ break;
+ ret = decodeMP3(&mp,buf,len,out,8192,&size);
+ while(ret == MP3_OK) {
+ write(1,out,size);
+ ret = decodeMP3(&mp,NULL,0,out,8192,&size);
+ }
+ }
+
+}
+
diff --git a/src/libmpg123/mpg123.h b/src/libmpg123/mpg123.h
new file mode 100644
index 000000000..9e947aa13
--- /dev/null
+++ b/src/libmpg123/mpg123.h
@@ -0,0 +1,194 @@
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+
+#ifndef WIN32
+#include <sys/signal.h>
+#include <unistd.h>
+#endif
+
+#include <math.h>
+
+#ifdef _WIN32
+# undef WIN32
+# define WIN32
+
+# define M_PI 3.14159265358979323846
+# define M_SQRT2 1.41421356237309504880
+# define REAL_IS_FLOAT
+# define NEW_DCT9
+
+# define random rand
+# define srandom srand
+
+#endif
+
+#ifdef REAL_IS_FLOAT
+# define real float
+#elif defined(REAL_IS_LONG_DOUBLE)
+# define real long double
+#else
+# define real double
+#endif
+
+#ifdef __GNUC__
+#define INLINE inline
+#else
+#define INLINE
+#endif
+
+/* AUDIOBUFSIZE = n*64 with n=1,2,3 ... */
+#define AUDIOBUFSIZE 16384
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef FALSE
+#define TRUE 1
+#endif
+
+#define SBLIMIT 128
+#define SSLIMIT 18
+
+#define SCALE_BLOCK 12
+
+
+#define MPG_MD_STEREO 0
+#define MPG_MD_JOINT_STEREO 1
+#define MPG_MD_DUAL_CHANNEL 2
+#define MPG_MD_MONO 3
+
+#define MAXFRAMESIZE 1792
+
+
+/* Pre Shift fo 16 to 8 bit converter table */
+#define AUSHIFT (3)
+
+struct frame {
+ int stereo;
+ int jsbound;
+ int single;
+ int lsf;
+ int mpeg25;
+ int header_change;
+ int lay;
+ int error_protection;
+ int bitrate_index;
+ int sampling_frequency;
+ int sample_rate;
+ int padding;
+ int extension;
+ int mode;
+ int mode_ext;
+ int copyright;
+ int original;
+ int emphasis;
+ int framesize; /* computed framesize */
+
+ /* layer2 stuff */
+ int II_sblimit;
+ void *alloc;
+};
+
+struct parameter {
+ int quiet; /* shut up! */
+ int tryresync; /* resync stream after error */
+ int verbose; /* verbose level */
+ int checkrange;
+};
+
+#include "mpglib.h"
+
+extern unsigned int get1bit(void);
+extern unsigned int getbits(int);
+extern unsigned int getbits_fast(int);
+extern int set_pointer(mpgaudio_t *mp, long);
+
+extern unsigned char *mpg123_wordpointer;
+extern int mpg123_bitindex;
+
+extern void make_decode_tables(long scaleval);
+extern void do_layer3(mpgaudio_t *mp, uint32_t pts);
+extern void do_layer2(mpgaudio_t *mp, uint32_t pts);
+extern void do_layer1(mpgaudio_t *mp, uint32_t pts);
+extern int decode_header(struct frame *fr,unsigned long newhead);
+
+
+
+struct gr_info_s {
+ int scfsi;
+ unsigned part2_3_length;
+ unsigned big_values;
+ unsigned scalefac_compress;
+ unsigned block_type;
+ unsigned mixed_block_flag;
+ unsigned table_select[3];
+ unsigned subblock_gain[3];
+ unsigned maxband[3];
+ unsigned maxbandl;
+ unsigned maxb;
+ unsigned region1start;
+ unsigned region2start;
+ unsigned preflag;
+ unsigned scalefac_scale;
+ unsigned count1table_select;
+ real *full_gain[3];
+ real *pow2gain;
+};
+
+struct III_sideinfo
+{
+ unsigned main_data_begin;
+ unsigned private_bits;
+ struct {
+ struct gr_info_s gr[2];
+ } ch[2];
+};
+
+extern int synth_1to1 (mpgaudio_t *mp, real *,int,unsigned char *,int *);
+extern int synth_1to1_8bit (real *,int,unsigned char *,int *);
+extern int synth_1to1_mono (mpgaudio_t *mp, real *,unsigned char *,int *);
+extern int synth_1to1_mono2stereo (real *,unsigned char *,int *);
+extern int synth_1to1_8bit_mono (real *,unsigned char *,int *);
+extern int synth_1to1_8bit_mono2stereo (real *,unsigned char *,int *);
+
+extern int synth_2to1 (real *,int,unsigned char *,int *);
+extern int synth_2to1_8bit (real *,int,unsigned char *,int *);
+extern int synth_2to1_mono (real *,unsigned char *,int *);
+extern int synth_2to1_mono2stereo (real *,unsigned char *,int *);
+extern int synth_2to1_8bit_mono (real *,unsigned char *,int *);
+extern int synth_2to1_8bit_mono2stereo (real *,unsigned char *,int *);
+
+extern int synth_4to1 (real *,int,unsigned char *,int *);
+extern int synth_4to1_8bit (real *,int,unsigned char *,int *);
+extern int synth_4to1_mono (real *,unsigned char *,int *);
+extern int synth_4to1_mono2stereo (real *,unsigned char *,int *);
+extern int synth_4to1_8bit_mono (real *,unsigned char *,int *);
+extern int synth_4to1_8bit_mono2stereo (real *,unsigned char *,int *);
+
+extern int synth_ntom (real *,int,unsigned char *,int *);
+extern int synth_ntom_8bit (real *,int,unsigned char *,int *);
+extern int synth_ntom_mono (real *,unsigned char *,int *);
+extern int synth_ntom_mono2stereo (real *,unsigned char *,int *);
+extern int synth_ntom_8bit_mono (real *,unsigned char *,int *);
+extern int synth_ntom_8bit_mono2stereo (real *,unsigned char *,int *);
+
+extern void rewindNbits(int bits);
+extern int hsstell(void);
+extern int get_songlen(struct frame *fr,int no);
+
+extern void init_layer3(int);
+extern void init_layer2(void);
+extern void make_decode_tables(long scale);
+extern void make_conv16to8_table(int);
+extern void dct64(real *,real *,real *);
+
+extern void synth_ntom_set_step(long,long);
+
+extern unsigned char *conv16to8;
+extern long freqs[9];
+extern real muls[27][64];
+extern real decwin[512+32];
+extern real *pnts[5];
+
+extern struct parameter param;
diff --git a/src/libmpg123/mpglib.h b/src/libmpg123/mpglib.h
new file mode 100644
index 000000000..04b33a922
--- /dev/null
+++ b/src/libmpg123/mpglib.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2000 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ * xine version of libmpg123 interface
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: mpglib.h,v 1.1 2001/04/18 22:34:49 f1rmb Exp $
+ */
+
+#ifndef HAVE_MPGLIB_H
+#define HAVE_MPGLIB_H
+
+#include <inttypes.h>
+#include "audio_out.h"
+
+typedef struct mpstr {
+ unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */
+ int bsnum;
+ int bsize;
+ int framesize, framesize_old;
+
+ unsigned long header;
+ struct frame fr;
+
+ real hybrid_block[2][2][SBLIMIT*SSLIMIT];
+ int hybrid_blc[2];
+ real synth_buffs[2][2][0x110];
+ int synth_bo;
+
+ int is_output_initialized;
+ ao_functions_t *ao_output;
+ unsigned char osspace[8192];
+} mpgaudio_t;
+
+#ifndef BOOL
+#define BOOL int
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+mpgaudio_t *mpg_audio_init (ao_functions_t *ao_output);
+
+void mpg_audio_reset (mpgaudio_t *mp);
+
+void mpg_audio_decode_data (mpgaudio_t *mp, uint8_t *data, uint8_t *data_end,
+ uint32_t pts);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/libmpg123/tabinit.c b/src/libmpg123/tabinit.c
new file mode 100644
index 000000000..2efd2cd04
--- /dev/null
+++ b/src/libmpg123/tabinit.c
@@ -0,0 +1,80 @@
+
+#include <stdlib.h>
+
+#include "mpg123.h"
+
+real decwin[512+32];
+static real cos64[16],cos32[8],cos16[4],cos8[2],cos4[1];
+real *pnts[] = { cos64,cos32,cos16,cos8,cos4 };
+
+#if 0
+static unsigned char *conv16to8_buf = NULL;
+unsigned char *conv16to8;
+#endif
+
+static long intwinbase[] = {
+ 0, -1, -1, -1, -1, -1, -1, -2, -2, -2,
+ -2, -3, -3, -4, -4, -5, -5, -6, -7, -7,
+ -8, -9, -10, -11, -13, -14, -16, -17, -19, -21,
+ -24, -26, -29, -31, -35, -38, -41, -45, -49, -53,
+ -58, -63, -68, -73, -79, -85, -91, -97, -104, -111,
+ -117, -125, -132, -139, -147, -154, -161, -169, -176, -183,
+ -190, -196, -202, -208, -213, -218, -222, -225, -227, -228,
+ -228, -227, -224, -221, -215, -208, -200, -189, -177, -163,
+ -146, -127, -106, -83, -57, -29, 2, 36, 72, 111,
+ 153, 197, 244, 294, 347, 401, 459, 519, 581, 645,
+ 711, 779, 848, 919, 991, 1064, 1137, 1210, 1283, 1356,
+ 1428, 1498, 1567, 1634, 1698, 1759, 1817, 1870, 1919, 1962,
+ 2001, 2032, 2057, 2075, 2085, 2087, 2080, 2063, 2037, 2000,
+ 1952, 1893, 1822, 1739, 1644, 1535, 1414, 1280, 1131, 970,
+ 794, 605, 402, 185, -45, -288, -545, -814, -1095, -1388,
+ -1692, -2006, -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788,
+ -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, -7910, -8209,
+ -8491, -8755, -8998, -9219, -9416, -9585, -9727, -9838, -9916, -9959,
+ -9966, -9935, -9863, -9750, -9592, -9389, -9139, -8840, -8492, -8092,
+ -7640, -7134, -6574, -5959, -5288, -4561, -3776, -2935, -2037, -1082,
+ -70, 998, 2122, 3300, 4533, 5818, 7154, 8540, 9975, 11455,
+ 12980, 14548, 16155, 17799, 19478, 21189, 22929, 24694, 26482, 28289,
+ 30112, 31947, 33791, 35640, 37489, 39336, 41176, 43006, 44821, 46617,
+ 48390, 50137, 51853, 53534, 55178, 56778, 58333, 59838, 61289, 62684,
+ 64019, 65290, 66494, 67629, 68692, 69679, 70590, 71420, 72169, 72835,
+ 73415, 73908, 74313, 74630, 74856, 74992, 75038 };
+
+void make_decode_tables(long scaleval)
+{
+ int i,j,k,kr,divv;
+ real *table,*costab;
+
+
+ for(i=0;i<5;i++)
+ {
+ kr=0x10>>i; divv=0x40>>i;
+ costab = pnts[i];
+ for(k=0;k<kr;k++)
+ costab[k] = 1.0 / (2.0 * cos(M_PI * ((double) k * 2.0 + 1.0) / (double) divv));
+ }
+
+ table = decwin;
+ scaleval = -scaleval;
+ for(i=0,j=0;i<256;i++,j++,table+=32)
+ {
+ if(table < decwin+512+16)
+ table[16] = table[0] = (double) intwinbase[j] / 65536.0 * (double) scaleval;
+ if(i % 32 == 31)
+ table -= 1023;
+ if(i % 64 == 63)
+ scaleval = - scaleval;
+ }
+
+ for( /* i=256 */ ;i<512;i++,j--,table+=32)
+ {
+ if(table < decwin+512+16)
+ table[16] = table[0] = (double) intwinbase[j] / 65536.0 * (double) scaleval;
+ if(i % 32 == 31)
+ table -= 1023;
+ if(i % 64 == 63)
+ scaleval = - scaleval;
+ }
+}
+
+
diff --git a/src/libspudec/Makefile.am b/src/libspudec/Makefile.am
new file mode 100644
index 000000000..0a4928288
--- /dev/null
+++ b/src/libspudec/Makefile.am
@@ -0,0 +1,20 @@
+CFLAGS = @BUILD_LIB_STATIC@ @GLOBAL_CFLAGS@
+
+EXTRA_DIST =
+
+noinst_LTLIBRARIES = libspudec.la
+
+libspudec_la_SOURCES = #spudec.c
+
+noinst_HEADERS = spudec.h
+
+debug:
+ $(MAKE) CFLAGS="$(DEBUG_CFLAGS)"
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/libspudec/spudec.c b/src/libspudec/spudec.c
new file mode 100644
index 000000000..b8c661df5
--- /dev/null
+++ b/src/libspudec/spudec.c
@@ -0,0 +1,688 @@
+/*
+ * spudec.c
+ *
+ * Copyright (C) Rich Wareham <rjw57@cam.ac.uk> - Jan 2001
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation,
+ *
+ */
+
+#include "spudec.h"
+
+#include "xine.h"
+#include "utils.h"
+#include "metronom.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+typedef struct _spudec_globals {
+ vo_image_buffer_t *overlay;
+ vo_image_buffer_t *mask;
+ int width, height;
+ int format;
+
+ int bInitialised;
+
+ int state;
+
+ spudec_geometry geom;
+
+ /* The current packet we are assembling, not decoding */
+ unsigned char *packet;
+ int packet_size;
+ uint32_t pts; /* PTS of packet */
+
+ uint32_t lifetime; /* Lifetime of currently displayed SPU in pts */
+ uint32_t displayPTS; /* The PTS when the last SPU was displayed. */
+
+ uint32_t lastPTS;
+
+ clut_t *clut;
+} spudec_globals;
+
+static spudec_globals gSpudec;
+
+clut_t *palette[4] = {
+ NULL, NULL, NULL, NULL
+};
+
+uint8_t alpha[4] = {
+ 0xff, 0x00, 0x00, 0x00
+};
+
+#ifdef BIG_ENDIAN
+static uint32_t default_palette[32] = {
+ 0x80801000, 0x80801000, 0x80808400, 0x8080eb00,
+ 0x80801000, 0x80801000, 0x80808400, 0x8080eb00,
+ 0x80801000, 0x80801000, 0x80808400, 0x8080eb00,
+ 0x80801000, 0x80801000, 0x80808400, 0x8080eb00,
+};
+
+#else
+
+static uint32_t default_palette[32] = {
+ 0x00108080, 0x00108080, 0x00848080, 0x00eb8080,
+ 0x00108080, 0x00108080, 0x00848080, 0x00eb8080,
+ 0x00108080, 0x00108080, 0x00848080, 0x00eb8080,
+ 0x00108080, 0x00108080, 0x00848080, 0x00eb8080
+};
+#endif
+
+static clut_t* default_clut = (clut_t*) default_palette;
+
+/* Maximum packets we can keep in the queue. Should be fine */
+#define MAX_PACKETS 200
+
+typedef struct {
+ unsigned char *packet; /* The actual packet of data */
+ uint32_t pts; /* The PTS of the packet */
+ uint16_t size; /* The packet size */
+} spudec_packet;
+
+/* Implement the SPU packet queue as a ring queuefer */
+spudec_packet* spudec_packet_queue[MAX_PACKETS];
+int16_t spudec_queue_size = 0; /* Queue length (items) */
+int16_t spudec_queue_pos = 0; /* Start of queue position */
+
+/* Forward declarations */
+void spudec_process_packet(unsigned char *packet, int size);
+
+/* Pushes a packet on the end of the queue */
+void spudec_queue_packet(spudec_packet *packet) {
+ if(spudec_queue_size + 1 > MAX_PACKETS) {
+ /* Too many packets */
+ printf("spudec: Too many packets.\n");
+ return;
+ }
+
+ spudec_packet_queue[(spudec_queue_pos + spudec_queue_size) % MAX_PACKETS] = packet;
+ spudec_queue_size++;
+}
+
+/* Gets the next packet but does /not/ remove it */
+spudec_packet* spudec_peek_next_packet() {
+ if(spudec_queue_size <= 0) {
+ /* No packet in queue */
+ printf("spudec: No more packets.\n");
+ return NULL;
+ }
+
+ return spudec_packet_queue[spudec_queue_pos];
+}
+
+/* Like peek_next but removes the packet from the queue */
+spudec_packet* spudec_get_next_packet() {
+ spudec_packet *packet;
+
+ if((packet = spudec_peek_next_packet()) != NULL) {
+ spudec_queue_pos = (spudec_queue_pos + 1) % MAX_PACKETS;
+ spudec_queue_size --;
+ }
+
+ return packet;
+}
+
+void spudec_init(clut_t *clut) {
+ gSpudec.bInitialised = 1;
+
+ spudec_reset();
+
+ if(clut == NULL) {
+ gSpudec.clut = default_clut;
+ } else {
+ gSpudec.clut = clut;
+ }
+
+ palette[0] = palette[1] = palette[2] = palette[3] = &(gSpudec.clut[0]);
+}
+
+void spudec_tick()
+{
+ uint32_t pts;
+ if(!gSpudec.bInitialised)
+ return;
+
+ pts = metronom_got_spu_packet(0);
+
+ /* See if we have any SPUs queued */
+ if(spudec_queue_size != 0) {
+ spudec_packet *p;
+
+ p = spudec_peek_next_packet();
+ if(pts >= p->pts) {
+ /* Process */
+ p = spudec_get_next_packet();
+
+ spudec_process_packet(p->packet, p->size);
+ /* Assume it was displayed correctly */
+ gSpudec.displayPTS = p->pts;
+
+ free(p->packet);
+ free(p);
+ }
+ }
+
+ if((gSpudec.geom.bIsVisible) && (pts - gSpudec.lifetime >= gSpudec.displayPTS)) {
+ gSpudec.geom.bIsVisible = 0;
+ gSpudec.lifetime = 0;
+ gSpudec.lastPTS = pts;
+ return;
+ }
+
+ if(pts < gSpudec.lastPTS) {
+ /* Something screwey. */
+ gSpudec.lastPTS = pts;
+ return;
+ }
+
+ gSpudec.lastPTS = pts;
+}
+
+spudec_geometry* spudec_get_geometry()
+{
+ return &(gSpudec.geom);
+}
+
+int spudec_set_images(vo_image_buffer_t* overlay,
+ vo_image_buffer_t* mask,
+ int width, int height,
+ int format)
+{
+ if(format != IMGFMT_YV12) {
+ printf("Error, SPUDEC only supports YV12 overlays.\n");
+ gSpudec.bInitialised = 0;
+
+ return 0;
+ }
+
+ gSpudec.overlay = overlay;
+ gSpudec.mask = mask;
+ gSpudec.width = width;
+ gSpudec.height = height;
+ gSpudec.format = format;
+ gSpudec.geom.bIsVisible = 0;
+
+ /* Clear images initially */
+ if(gSpudec.format == IMGFMT_YV12) {
+ /* Set initial image to empty & clear mask */
+ memset(mask->mem[0], 0xff, (gSpudec.width*gSpudec.height));
+ memset(overlay->mem[0], 0x00, (gSpudec.width*gSpudec.height));
+ memset(mask->mem[1], 0xff, (gSpudec.width*gSpudec.height) >> 2);
+ memset(overlay->mem[1], 0x00, (gSpudec.width >> 1)*(gSpudec.height >> 1));
+ memset(mask->mem[2], 0xff, (gSpudec.width >> 1)*(gSpudec.height >> 1));
+ memset(overlay->mem[2], 0x00, (gSpudec.width >> 1)*(gSpudec.height >> 1));
+ }
+
+ gSpudec.geom.start_col = 0;
+ gSpudec.geom.end_col = gSpudec.width-1;
+ gSpudec.geom.start_row = 0;
+ gSpudec.geom.end_row = gSpudec.height-1;
+
+ return gSpudec.bInitialised = 1;
+}
+
+#define nibble(data, index) ((index & 1) ? data[index >> 1] & 0xf : (data[index >> 1] >> 4) & 0xf)
+
+void spudec_process_data(unsigned char *data, int size, int d1, int d2)
+{
+ /* This does the 'hard' work of processing the image data */
+
+ long off,line_base, line_base2,y,na,nb;
+ int n; /* The code word */
+
+ na = d1<<1;
+ nb = d2<<1;
+
+ /* Align on even row */
+ if (gSpudec.geom.start_row & 1) {
+ gSpudec.geom.start_row--;
+ gSpudec.geom.end_row--;
+ }
+ if (gSpudec.geom.start_col & 1) {
+ gSpudec.geom.start_col--;
+ gSpudec.geom.end_col--;
+ }
+ y = gSpudec.geom.start_row;
+
+ while(y <= gSpudec.geom.end_row) {
+ line_base = gSpudec.width * y + gSpudec.geom.start_col;
+ line_base2 = (gSpudec.width>>1) * (y>>1) + (gSpudec.geom.start_col >> 1);
+
+ off = 0;
+ do {
+ int num;
+ clut_t *col;
+
+ n = nibble(data, na);
+ na++;
+ if(n < 0x4) {
+ n = (n<<4) | nibble(data, na);
+ na++;
+ if(n < 0x10) {
+ n = (n<<4) | nibble(data, na);
+ na++;
+ if(n < 0x40) {
+ n = (n<<4) | nibble(data, na);
+ na++;
+ if(n < 0x100)
+ n = 0; /* Carriage return */
+ }
+ }
+ }
+ // printf("Code: 0x%04x\n",n);
+
+ num = n >> 2; col = palette[n & 0x3];
+ if(col == NULL) {
+ printf("Error in palette\n");
+ }
+
+ if(num != 0) {
+ if(alpha[n & 0x3] & 0x80) {
+ memset(&(gSpudec.mask->mem[0][line_base + off]), 0x00, num);
+ memset(&(gSpudec.overlay->mem[0][line_base + off]), col->y, num);
+ memset(&(gSpudec.mask->mem[1][line_base2 + (off>>1)]), 0x00, num>>1);
+ memset(&(gSpudec.overlay->mem[1][line_base2 + (off>>1)]), col->cr, num>>1);
+ memset(&(gSpudec.mask->mem[2][line_base2 + (off>>1)]), 0x00, num>>1);
+ memset(&(gSpudec.overlay->mem[2][line_base2 + (off>>1)]), col->cb, num>>1);
+ } else {
+ memset(&(gSpudec.mask->mem[0][line_base + off]), 0xff, num);
+ memset(&(gSpudec.overlay->mem[0][line_base + off]), 0x00, num);
+ memset(&(gSpudec.mask->mem[1][line_base2 + (off>>1)]), 0xff, num>>1);
+ memset(&(gSpudec.overlay->mem[1][line_base2 + (off>>1)]), 0x00, num>>1);
+ memset(&(gSpudec.mask->mem[2][line_base2 + (off>>1)]), 0xff, num>>1);
+ memset(&(gSpudec.overlay->mem[2][line_base2 + (off>>1)]), 0x00, num>>1);
+ }
+ }
+ off+=num;
+ } while((n != 0) && (off <= gSpudec.geom.end_col - gSpudec.geom.start_col));
+
+ if((n == 0) && (off <= gSpudec.geom.end_col - gSpudec.geom.start_col)) {
+ /* Clear to end of line if carriage return */
+ int len = gSpudec.geom.start_col + gSpudec.geom.end_col - off;
+ memset(&(gSpudec.mask->mem[0][line_base + off]), 0xff, len);
+ memset(&(gSpudec.overlay->mem[0][line_base + off]), 0x00, len);
+ memset(&(gSpudec.mask->mem[0][line_base + off]) + gSpudec.width, 0xff, len);
+ memset(&(gSpudec.overlay->mem[0][line_base + off]) + gSpudec.width, 0x00, len);
+ memset(&(gSpudec.mask->mem[1][line_base2 + (off>>1)]), 0xff, len>>1);
+ memset(&(gSpudec.overlay->mem[1][line_base2 + (off>>1)]), 0x00, len>>1);
+ memset(&(gSpudec.mask->mem[2][line_base2 + (off>>1)]), 0xff, len>>1);
+ memset(&(gSpudec.overlay->mem[2][line_base2 + (off>>1)]), 0x00, len>>1);
+ }
+
+ if((na & 1))
+ na ++; /* Re-align */
+
+ line_base += gSpudec.width;
+ y++;
+ if (y > gSpudec.geom.end_row)
+ break;
+
+ off = 0;
+ do {
+ int num;
+ clut_t *col;
+
+ n = nibble(data, nb);
+ nb++;
+ if(n < 0x4) {
+ n = (n<<4) | nibble(data, nb);
+ nb++;
+ if(n < 0x10) {
+ n = (n<<4) | nibble(data, nb);
+ nb++;
+ if(n < 0x40) {
+ n = (n<<4) | nibble(data, nb);
+ nb++;
+ if(n < 0x100)
+ n = 0; /* Carriage return */
+ }
+ }
+ }
+ // printf("Code: 0x%04x\n",n);
+
+ num = n >> 2; col = palette[n & 0x3];
+ if(col == NULL) {
+ printf("Error in palette\n");
+ }
+
+ if(num != 0) {
+ if(alpha[n & 0x3] & 0x80) {
+ memset(&(gSpudec.mask->mem[0][line_base + off]), 0x00, num);
+ memset(&(gSpudec.overlay->mem[0][line_base + off]), col->y, num);
+ } else {
+ memset(&(gSpudec.mask->mem[0][line_base + off]), 0xff, num);
+ memset(&(gSpudec.overlay->mem[0][line_base + off]), 0x00, num);
+ }
+ }
+ off+=num;
+ } while((n != 0) && (off <= gSpudec.geom.end_col - gSpudec.geom.start_col));
+
+ if((n == 0) && (off <= gSpudec.geom.end_col - gSpudec.geom.start_col)) {
+ /* Clear to end of line if carriage return */
+ int len = gSpudec.geom.start_col + gSpudec.geom.end_col - off;
+ memset(&(gSpudec.mask->mem[0][line_base + off]), 0xff, len);
+ memset(&(gSpudec.overlay->mem[0][line_base + off]), 0x00, len);
+ }
+
+ if((nb & 1))
+ nb ++; /* Re-align */
+
+ y++;
+ }
+}
+
+void spudec_process_control(unsigned char *control, int size, int* d1, int* d2)
+{
+ int off = 2;
+ int a,b; /* Temporary vars */
+
+ do {
+ int type = control[off];
+ off++;
+
+ switch(type) {
+ case 0x00:
+ /* Menu ID, 1 byte */
+ break;
+ case 0x01:
+ /* Start display */
+ gSpudec.geom.bIsVisible = 1;
+ break;
+ case 0x03:
+ /* Palette */
+ palette[3] = &(gSpudec.clut[(control[off] >> 4)]);
+ palette[2] = &(gSpudec.clut[control[off] & 0xf]);
+ palette[1] = &(gSpudec.clut[(control[off+1] >> 4)]);
+ palette[0] = &(gSpudec.clut[control[off+1] & 0xf]);
+ off+=2;
+ break;
+ case 0x04:
+ /* Alpha */
+ alpha[3] = control[off] & 0xf0;
+ alpha[2] = (control[off] & 0xf) << 4;
+ alpha[1] = control[off+1] & 0xf0;
+ alpha[0] = (control[off+1] & 0xf) << 4;
+ off+=2;
+ break;
+ case 0x05:
+ /* Co-ords */
+ a = (control[off] << 16) + (control[off+1] << 8) + control[off+2];
+ b = (control[off+3] << 16) + (control[off+4] << 8) + control[off+5];
+
+ gSpudec.geom.start_col = a >> 12;
+ gSpudec.geom.end_col = a & 0xfff;
+ gSpudec.geom.start_row = b >> 12;
+ gSpudec.geom.end_row = b & 0xfff;
+
+ off+=6;
+ break;
+ case 0x06:
+ /* Graphic lines */
+ *(d1) = (control[off] << 8) + control[off+1];
+ *(d2) = (control[off+2] << 8) + control[off+3];
+ off+=4;
+ break;
+ case 0xff:
+ /* All done, bye-bye */
+ return;
+ break;
+ default:
+ printf("spudec: Error determining control type 0x%02x.\n",type);
+ return;
+ break;
+ }
+
+ /* printf("spudec: Processsed control type 0x%02x.\n",type); */
+ } while(off < size);
+}
+
+void spudec_process_packet(unsigned char *packet, int size)
+{
+ int x0, x1;
+ int d1, d2;
+
+ /* Check packet */
+ if((packet[0] << 8) + packet[1] != size) {
+ printf("Packet size mismatch:\n");
+ printf("Packet reports size 0x%04x\n", (packet[0] << 8) + packet[1]);
+ printf("I reckon 0x%04x\n", size);
+ return;
+ }
+
+ x0 = (packet[2] << 8) + packet[3];
+ x1 = (packet[x0+2] << 8) + packet[x0+3];
+
+ /* /Another/ sanity check. */
+ if((packet[x1+2]<<8) + packet[x1+3] != x1) {
+ printf("spudec: Incorrect packet.\n");
+ return;
+ }
+
+ /* End sequence, FIXME: why do we need the division by 2? */
+ gSpudec.lifetime = (metronom_get_video_rate() >> 1)* ((packet[x1]<<8) + packet[x1+1]);
+
+ d1 = d2 = -1;
+ spudec_process_control(packet + x0 + 2, x1-x0-2, &d1, &d2);
+
+ if((d1 != -1) && (d2 != -1)) {
+ spudec_process_data(packet, x0, d1, d2);
+ }
+}
+
+void spudec_decode(unsigned char *data, int size, uint32_t pts) {
+ if(!gSpudec.bInitialised)
+ return;
+
+ if(gSpudec.packet == NULL) {
+ if(pts != 0) {
+ /* Allocate a packet buffer */
+ gSpudec.packet = xmalloc((data[0] << 8) + data[1]);
+ gSpudec.pts = pts;
+
+ if(gSpudec.packet == NULL) {
+ printf("Error allocating packet buffer.\n");
+ return;
+ }
+
+ gSpudec.packet_size = 0;
+ } else {
+ printf("spudec: Error, we are half way through a packet I don't know\n");
+ }
+ }
+
+ /* Prevent buffer overruns */
+ if(gSpudec.packet_size >= 2) { /* If the /packet/ knows how big it is */
+ if((gSpudec.packet_size + size) >
+ (gSpudec.packet[0]<<8) + gSpudec.packet[1]) {
+ printf("spudec: Mismatched buffer size (0x%04x to big), truncating.\n",
+ (gSpudec.packet_size + size) -
+ ((gSpudec.packet[0]<<8) + gSpudec.packet[1]));
+ size = (gSpudec.packet[0]<<8) + gSpudec.packet[1] - gSpudec.packet_size;
+ }
+ }
+
+
+ memcpy(gSpudec.packet + gSpudec.packet_size, data, size);
+ gSpudec.packet_size += size;
+
+ if(gSpudec.packet_size >= (gSpudec.packet[0]<<8) + gSpudec.packet[1]) {
+ /* If packet complete then queue */
+ spudec_packet *p;
+
+ p = xmalloc(sizeof(spudec_packet));
+ p->packet = gSpudec.packet;
+ p->size = gSpudec.packet_size;
+ p->pts = gSpudec.pts;
+
+ spudec_queue_packet(p);
+
+ gSpudec.packet = NULL;
+ gSpudec.packet_size = -1;
+ gSpudec.pts = 0;
+ }
+}
+
+void spudec_reset() {
+ /* Clear any packet being assembled */
+ if(gSpudec.packet != NULL) {
+ gSpudec.packet_size = 0;
+ free(gSpudec.packet);
+ gSpudec.packet = NULL;
+ gSpudec.pts = 0;
+ }
+
+ /* Remove any current subtitle */
+ gSpudec.geom.bIsVisible = 0;
+ gSpudec.lifetime = 0;
+
+ /* Clear packet queue */
+ while(spudec_queue_size > 0) {
+ spudec_packet *p = spudec_get_next_packet();
+
+ free(p->packet);
+ free(p);
+ }
+}
+
+void spudec_overlay_yuv (uint8_t *y, uint8_t *u, uint8_t *v) {
+
+ /*
+ * Mix in SPU
+ */
+
+ /* Tick SPUdec */
+ spudec_tick();
+
+ if(gVO.bOverlayImage) {
+ /* This code is pretty nasty but quite quick which is important here! */
+ /* APPROACH: Since 32bit processors hande data, well 32bits at a time,
+ * we overlay the image word by word rather than byte by byte and then
+ * tidy up the odd bytes at the end. This effectively cuts the number of
+ * loop itterations by a factor of 4. */
+
+ /* FIXME: Optimise for 64bit machines as well? */
+
+ if((gVO.spu_geom->bIsVisible) &&
+ (gVO.format == IMGFMT_YV12)) {
+ /* Overlay the image. */
+ long i, off;
+ uint8_t *img_l_8, *ovl_l_8, *msk_l_8;
+ uint32_t *img_l_32, *ovl_l_32, *msk_l_32;
+ uint8_t *img_y_8, *ovl_y_8, *msk_y_8;
+ uint32_t *img_y_32, *ovl_y_32, *msk_y_32;
+ uint8_t *img_v_8, *ovl_v_8, *msk_v_8;
+ uint32_t *img_v_32, *ovl_v_32, *msk_v_32;
+
+ img_l_8 = img->mem[0];
+ ovl_l_8 = gVO.overlay_image->mem[0];
+ msk_l_8 = gVO.mask_image->mem[0];
+ img_l_32 = ((uint32_t*)img->mem[0]);
+ ovl_l_32 = ((uint32_t*)gVO.overlay_image->mem[0]);
+ msk_l_32 = ((uint32_t*)gVO.mask_image->mem[0]);
+ img_y_8 = img->mem[1];
+ ovl_y_8 = gVO.overlay_image->mem[1];
+ msk_y_8 = gVO.mask_image->mem[1];
+ img_y_32 = ((uint32_t*)img->mem[1]);
+ ovl_y_32 = ((uint32_t*)gVO.overlay_image->mem[1]);
+ msk_y_32 = ((uint32_t*)gVO.mask_image->mem[1]);
+ img_v_8 = img->mem[2];
+ ovl_v_8 = gVO.overlay_image->mem[2];
+ msk_v_8 = gVO.mask_image->mem[2];
+ img_v_32 = ((uint32_t*)img->mem[2]);
+ ovl_v_32 = ((uint32_t*)gVO.overlay_image->mem[2]);
+ msk_v_32 = ((uint32_t*)gVO.mask_image->mem[2]);
+
+ /* luminance */
+ for(i=gVO.width*gVO.spu_geom->start_row;
+ i<=gVO.width*gVO.spu_geom->end_row; i+=gVO.width) {
+ /* i is address of begining of line. */
+
+ /* Firstly, draw the start odd bytes. */
+ for(off = i+gVO.spu_geom->start_col; (off & 3) != 0; off++) {
+ if(msk_l_8[off] != 0xff) {
+ img_l_8[off] &= msk_l_8[off];
+ img_l_8[off] |= ovl_l_8[off];
+ }
+ }
+
+ /* Now words */
+ for(; off<=i+gVO.spu_geom->end_col-3; off+=4) {
+ if(msk_l_32[off>>2] != 0xffffffff) {
+ img_l_32[off>>2] &= msk_l_32[off>>2];
+ img_l_32[off>>2] |= ovl_l_32[off>>2];
+ }
+ }
+ off -= 4;
+
+ /* Now end odd bytes */
+ for(; off<=i+gVO.spu_geom->end_col; off++) {
+ if(msk_l_8[off] != 0xff) {
+ img_l_8[off] &= msk_l_8[off];
+ img_l_8[off] |= ovl_l_8[off];
+ }
+ }
+ }
+ /* colour */
+ for(i=(gVO.width>>1)*(gVO.spu_geom->start_row>>1);
+ i<=(gVO.width>>1)*(gVO.spu_geom->end_row>>1); i+=(gVO.width)>>1) {
+ /* i is address of begining of line. */
+
+ /* Firstly, draw the start odd bytes. */
+ for(off = i+((gVO.spu_geom->start_col)>>1); (off & 3) != 0; off++) {
+ if(msk_y_8[off] != 0xff) {
+ img_y_8[off] &= msk_y_8[off];
+ img_y_8[off] |= ovl_y_8[off];
+ }
+ if(msk_v_8[off] != 0xff) {
+ img_v_8[off] &= msk_v_8[off];
+ img_v_8[off] |= ovl_v_8[off];
+ }
+ }
+
+ /* Now words */
+ for(; off<=i+((gVO.spu_geom->end_col)>>1)-3; off+=4) {
+ if(msk_y_32[off>>2] != 0xffffffff) {
+ img_y_32[off>>2] &= msk_y_32[off>>2];
+ img_y_32[off>>2] |= ovl_y_32[off>>2];
+ }
+ if(msk_v_32[off>>2] != 0xffffffff) {
+ img_v_32[off>>2] &= msk_v_32[off>>2];
+ img_v_32[off>>2] |= ovl_v_32[off>>2];
+ }
+ }
+ off -= 4;
+
+ /* Final end odd bytes */
+ for(; off<=i+((gVO.spu_geom->end_col)>>1); off++) {
+ if(msk_y_8[off] != 0xff) {
+ img_y_8[off] &= msk_y_8[off];
+ img_y_8[off] |= ovl_y_8[off];
+ }
+ if(msk_v_8[off] != 0xff) {
+ img_v_8[off] &= msk_v_8[off];
+ img_v_8[off] |= ovl_v_8[off];
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/libspudec/spudec.h b/src/libspudec/spudec.h
new file mode 100644
index 000000000..c20c934a0
--- /dev/null
+++ b/src/libspudec/spudec.h
@@ -0,0 +1,67 @@
+/*
+ * spudec.h
+ *
+ * Copyright (C) Rich Wareham <rjw57@cam.ac.uk> - Jan 2001
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Make; see the file COPYING. If not, write to
+ * the Free Software Foundation,
+ *
+ */
+
+#ifndef HAVE_SPUDEC_H
+#define HAVE_SPUDEC_H
+
+#include "metronom.h"
+#include "input/input_plugin.h"
+
+typedef struct spudec_s spudec_t;
+
+struct spudec_s {
+
+ /*
+ * reset spudec for a new stream
+ *
+ * clut : pointer to array of 16 cluts for palette info
+ */
+
+ void (*spudec_start) (spudec_t *this, clut_t *clut);
+
+ /*
+ * overlay functions: spudec decodes all subpicture data until
+ * it reaches the given vpts, then overlays the subpicture
+ */
+
+ void (*spudec_overlay_yuv) (spudec_t *this, uint32_t vpts,
+ uint8_t *y, uint8_t *u, uint8_t *v);
+ void (*spudec_overlay_rgb) (spudec_t *this, uint32_t vpts,
+ uint8_t *rgb_data, int mode);
+};
+
+/*
+ * generate a new subpicture decoder
+ *
+ * metronom : metronom for pts <-> vpts conversion
+ * spu_fifo : fifo buffer where subpicture packages arrive
+ */
+
+spudec_t *spudec_init (metronom_t *metronom, fifo_buffer_t *spu_fifo);
+
+#endif /* HAVE_SPUDEC_H */
+
+
+
+
+
diff --git a/src/libw32dll/Makefile.am b/src/libw32dll/Makefile.am
new file mode 100644
index 000000000..48c7ee604
--- /dev/null
+++ b/src/libw32dll/Makefile.am
@@ -0,0 +1,38 @@
+# CFLAGS = @BUILD_LIB_STATIC@ -I wine -D__WINE__ -Ddbg_printf=__vprintf -DTRACE=__vprintf -fno-omit-frame-pointer
+# CFLAGS = -I wine -D__WINE__ -Ddbg_printf=__vprintf -DTRACE=__vprintf -fno-omit-frame-pointer @X_CFLAGS@
+
+CFLAGS = @BUILD_LIB_STATIC@ -I wine -fno-omit-frame-pointer \
+ -DWIN32_PATH=\"@w32_path@\" -pipe
+
+SUBDIRS = wine
+
+if HAVE_W32DLL
+w32dll_lib = libw32dll.la
+endif
+
+noinst_LTLIBRARIES = $(w32dll_lib)
+
+libw32dll_la_SOURCES = afl.c elfdll.c module.c pe_resource.c \
+ resource.c win32.c driver.c ext.c \
+ pe_image.c registry.c vfl.c ##w32codec.c
+
+libw32dll_la_LIBADD = stubs.lo
+
+noinst_HEADERS = loader.h registry.h win32.h wineacm.h w32codec.h
+
+EXTRA_DIST = stubs.s
+
+stubs.lo: stubs.s
+ $(CC) -c $(top_srcdir)/src/libw32dll/stubs.s -o stubs.lo
+
+
+debug:
+ $(MAKE) CFLAGS="$(CFLAGS) -g -DSTATIC_WIN32_PATH"
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/libw32dll/afl.c b/src/libw32dll/afl.c
new file mode 100644
index 000000000..f8d5dd0e6
--- /dev/null
+++ b/src/libw32dll/afl.c
@@ -0,0 +1,765 @@
+/**************************************************************************
+
+
+ This file will contain an interface to ACM drivers.
+ Its content will be based mainly on wine/dlls/msacm32
+ actually, for audio decompression only the following functions
+ are needed:
+
+ acmStreamOpen ( takes formats of src and dest, returns stream handle )
+ acmStreamPrepareHeader ( takes stream handler and info on data )
+ acmStreamConvert ( the same as PrepareHeader )
+ acmStreamUnprepareHeader
+ acmStreamClose
+ acmStreamSize
+ maybe acmStreamReset
+
+ In future I'll also add functions for format enumeration,
+ but not right now.
+
+
+***************************************************************************/
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "wine/winbase.h"
+#include "wine/windef.h"
+#include "wine/winuser.h"
+#include "wine/vfw.h"
+#include "wine/winestring.h"
+#include "wine/driver.h"
+#include "wine/winerror.h"
+#include "wine/msacm.h"
+#include "wine/msacmdrv.h"
+#include "wine/debugtools.h"
+#include "wineacm.h"
+
+#pragma pack(1)
+#define OpenDriverA DrvOpen
+extern HDRVR VFWAPI DrvOpen(long);
+#define CloseDriver DrvClose
+extern HDRVR VFWAPI DrvClose(long);
+
+static PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has)
+{
+ return (PWINE_ACMSTREAM)has;
+}
+
+/***********************************************************************
+ * acmDriverAddA (MSACM32.2)
+ */
+MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
+ LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
+{
+ if (!phadid)
+ return MMSYSERR_INVALPARAM;
+
+ /* Check if any unknown flags */
+ if (fdwAdd &
+ ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
+ ACM_DRIVERADDF_GLOBAL))
+ return MMSYSERR_INVALFLAG;
+
+ /* Check if any incompatible flags */
+ if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) &&
+ (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND))
+ return MMSYSERR_INVALFLAG;
+
+ /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a
+ * LoadDriver on it, to be sure we can call SendDriverMessage on the
+ * hDrvr handle.
+ */
+ *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, hinstModule);
+
+ /* FIXME: lParam, dwPriority and fdwAdd ignored */
+
+ return MMSYSERR_NOERROR;
+}
+
+/***********************************************************************
+ * acmDriverClose (MSACM32.4)
+ */
+MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
+{
+ PWINE_ACMDRIVER p;
+ PWINE_ACMDRIVER* tp;
+
+ if (fdwClose)
+ return MMSYSERR_INVALFLAG;
+
+ p = MSACM_GetDriver(had);
+ if (!p)
+ return MMSYSERR_INVALHANDLE;
+
+ for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) {
+ if (*tp == p) {
+ *tp = (*tp)->pNextACMDriver;
+ break;
+ }
+ }
+
+ if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList)
+ CloseDriver(p->hDrvr);
+
+ HeapFree(MSACM_hHeap, 0, p);
+
+ return MMSYSERR_NOERROR;
+}
+
+/***********************************************************************
+ * acmDriverEnum (MSACM32.7)
+ */
+MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
+{
+ PWINE_ACMDRIVERID p;
+ DWORD fdwSupport;
+
+ if (!fnCallback) {
+ return MMSYSERR_INVALPARAM;
+ }
+
+ if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) {
+ return MMSYSERR_INVALFLAG;
+ }
+
+ for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) {
+ fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
+ if (!p->bEnabled) {
+ if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
+ fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
+ else
+ continue;
+ }
+ (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport);
+ }
+
+ return MMSYSERR_NOERROR;
+}
+
+/***********************************************************************
+ * acmDriverID (MSACM32.8)
+ */
+MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
+{
+ PWINE_ACMOBJ pao;
+
+ pao = MSACM_GetObj(hao);
+ if (!pao)
+ return MMSYSERR_INVALHANDLE;
+
+ if (!phadid)
+ return MMSYSERR_INVALPARAM;
+
+ if (fdwDriverID)
+ return MMSYSERR_INVALFLAG;
+
+ *phadid = (HACMDRIVERID) pao->pACMDriverID;
+
+ return MMSYSERR_NOERROR;
+}
+
+/***********************************************************************
+ * acmDriverMessage (MSACM32.9)
+ * FIXME
+ * Not implemented
+ */
+LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
+{
+ PWINE_ACMDRIVER pad = MSACM_GetDriver(had);
+ if (!pad)
+ return MMSYSERR_INVALPARAM;
+
+ /* FIXME: Check if uMsg legal */
+
+ if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2))
+ return MMSYSERR_NOTSUPPORTED;
+
+ return MMSYSERR_NOERROR;
+}
+
+
+/***********************************************************************
+ * acmDriverOpen (MSACM32.10)
+ */
+MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
+{
+ PWINE_ACMDRIVERID padid;
+ PWINE_ACMDRIVER pad;
+ ICOPEN icopen;
+ /* HDRVR hdrv; */
+
+
+
+ TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen);
+
+ if (!phad)
+ return MMSYSERR_INVALPARAM;
+
+ padid = MSACM_GetDriverID(hadid);
+ if (!padid)
+ return MMSYSERR_INVALHANDLE;
+
+ if (fdwOpen)
+ return MMSYSERR_INVALFLAG;
+
+ pad = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
+ if (!pad) return MMSYSERR_NOMEM;
+
+ pad->obj.pACMDriverID = padid;
+ icopen.fccType = mmioFOURCC('a', 'u', 'd', 'c');
+ icopen.fccHandler = (long)padid->pszFileName;
+ icopen.dwSize = sizeof(ICOPEN);
+ icopen.dwFlags = 0;
+
+ if (!padid->hInstModule)
+ pad->hDrvr = OpenDriverA((long)&icopen);
+ else
+ pad->hDrvr = padid->hInstModule;
+
+ if (!pad->hDrvr) {
+ HeapFree(MSACM_hHeap, 0, pad);
+ return MMSYSERR_ERROR;
+ }
+
+ pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc");
+
+ /* insert new pad at beg of list */
+ pad->pNextACMDriver = padid->pACMDriverList;
+ padid->pACMDriverList = pad;
+
+ /* FIXME: Create a WINE_ACMDRIVER32 */
+ *phad = (HACMDRIVER)pad;
+
+ return MMSYSERR_NOERROR;
+}
+
+/***********************************************************************
+ * acmDriverRemove (MSACM32.12)
+ */
+MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
+{
+ PWINE_ACMDRIVERID padid;
+
+ padid = MSACM_GetDriverID(hadid);
+ if (!padid)
+ return MMSYSERR_INVALHANDLE;
+
+ if (fdwRemove)
+ return MMSYSERR_INVALFLAG;
+
+ MSACM_UnregisterDriver(padid);
+
+ return MMSYSERR_NOERROR;
+}
+
+
+
+/**********************************************************************/
+
+HANDLE MSACM_hHeap = (HANDLE) NULL;
+PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL;
+PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL;
+
+/***********************************************************************
+ * MSACM_RegisterDriver32()
+ */
+PWINE_ACMDRIVERID MSACM_RegisterDriver(LPSTR pszDriverAlias, LPSTR pszFileName,
+ HINSTANCE hinstModule)
+//
+// File names are stored in driver.c. I reuse this variable to store driver ID
+// in it. If it's <0x10000, it is primary codec for corresponding format.
+//
+{
+ PWINE_ACMDRIVERID padid;
+
+ TRACE("('%s', '%x', 0x%08x)\n", pszDriverAlias, pszFileName, hinstModule);
+
+ padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID));
+ padid->pszDriverAlias = (char*)malloc(strlen(pszDriverAlias)+1);
+ strcpy(padid->pszDriverAlias, pszDriverAlias);
+// 1~strdup(pszDriverAlias);
+ padid->pszFileName = pszFileName;
+ padid->hInstModule = hinstModule;
+ padid->bEnabled = TRUE;
+ padid->pACMDriverList = NULL;
+ padid->pNextACMDriverID = NULL;
+ padid->pPrevACMDriverID = MSACM_pLastACMDriverID;
+ if (MSACM_pLastACMDriverID)
+ MSACM_pLastACMDriverID->pNextACMDriverID = padid;
+ MSACM_pLastACMDriverID = padid;
+ if (!MSACM_pFirstACMDriverID)
+ MSACM_pFirstACMDriverID = padid;
+
+ return padid;
+}
+
+/***********************************************************************
+ * MSACM_RegisterAllDrivers32()
+ */
+void MSACM_RegisterAllDrivers(void)
+{
+ /* LPSTR pszBuffer; */
+ /* DWORD dwBufferLength; */
+
+ if (MSACM_pFirstACMDriverID)
+ return;
+
+ MSACM_RegisterDriver("divxa32", (LPSTR)0x161, 0); // DivX/WMA [07]
+ MSACM_RegisterDriver("msadp32", (LPSTR)0x2, 0); // MS ADPCM [08]
+ MSACM_RegisterDriver("l3codeca", (LPSTR)0x55, 0); // MPEG Layer-3 [12]
+// MSACM_RegisterDriver("imaadp32", (LPSTR)0x11, 0); // IMA ADPCM [13]
+// MSACM_RegisterDriver("msgsm32", (LPSTR)0x32, 0); // MS GSM 6.10 [14]
+}
+
+/***********************************************************************
+ * MSACM_UnregisterDriver32()
+ */
+PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p)
+{
+ PWINE_ACMDRIVERID pNextACMDriverID;
+
+ while (p->pACMDriverList)
+ acmDriverClose((HACMDRIVER) p->pACMDriverList, 0);
+
+ if (p->pszDriverAlias)
+ HeapFree(MSACM_hHeap, 0, p->pszDriverAlias);
+// if (p->pszFileName)
+// HeapFree(MSACM_hHeap, 0, p->pszFileName);
+
+ if (p == MSACM_pFirstACMDriverID)
+ MSACM_pFirstACMDriverID = p->pNextACMDriverID;
+ if (p == MSACM_pLastACMDriverID)
+ MSACM_pLastACMDriverID = p->pPrevACMDriverID;
+
+ if (p->pPrevACMDriverID)
+ p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID;
+ if (p->pNextACMDriverID)
+ p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID;
+
+ pNextACMDriverID = p->pNextACMDriverID;
+
+ HeapFree(MSACM_hHeap, 0, p);
+
+ return pNextACMDriverID;
+}
+
+/***********************************************************************
+ * MSACM_UnregisterAllDrivers32()
+ * FIXME
+ * Where should this function be called?
+ */
+void MSACM_UnregisterAllDrivers(void)
+{
+ PWINE_ACMDRIVERID p;
+
+ for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p));
+}
+
+/***********************************************************************
+ * MSACM_GetDriverID32()
+ */
+PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID)
+{
+ return (PWINE_ACMDRIVERID)hDriverID;
+}
+
+/***********************************************************************
+ * MSACM_GetDriver32()
+ */
+PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver)
+{
+ return (PWINE_ACMDRIVER)hDriver;
+}
+
+/***********************************************************************
+ * MSACM_GetObj32()
+ */
+PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj)
+{
+ return (PWINE_ACMOBJ)hObj;
+}
+
+
+
+/***********************************************************************
+ * acmStreamOpen (MSACM32.40)
+ */
+MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
+ PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
+ DWORD dwInstance, DWORD fdwOpen)
+{
+ PWINE_ACMSTREAM was;
+ PWINE_ACMDRIVER wad;
+ MMRESULT ret;
+ int wfxSrcSize;
+ int wfxDstSize;
+
+ TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n",
+ phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);
+
+ TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
+ pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec,
+ pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);
+
+ TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
+ pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec,
+ pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize);
+
+#define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize))
+ wfxSrcSize = SIZEOF_WFX(pwfxSrc);
+ wfxDstSize = SIZEOF_WFX(pwfxDst);
+#undef SIZEOF_WFX
+
+ was = HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0));
+ if (was == NULL)
+ return MMSYSERR_NOMEM;
+
+ was->drvInst.cbStruct = sizeof(was->drvInst);
+ was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
+ memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize);
+ was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize);
+ memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize);
+ if (pwfltr) {
+ was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize);
+ memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER));
+ } else {
+ was->drvInst.pwfltr = NULL;
+ }
+ was->drvInst.dwCallback = dwCallback;
+ was->drvInst.dwInstance = dwInstance;
+ was->drvInst.fdwOpen = fdwOpen;
+ was->drvInst.fdwDriver = 0L;
+ was->drvInst.dwDriver = 0L;
+ was->drvInst.has = (HACMSTREAM)was;
+
+ if (had) {
+ if (!(wad = MSACM_GetDriver(had))) {
+ ret = MMSYSERR_INVALPARAM;
+ goto errCleanUp;
+ }
+
+ was->obj.pACMDriverID = wad->obj.pACMDriverID;
+ was->pDrv = wad;
+ was->hAcmDriver = 0; /* not to close it in acmStreamClose */
+
+ ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
+ if (ret != MMSYSERR_NOERROR)
+ goto errCleanUp;
+ } else {
+ PWINE_ACMDRIVERID wadi;
+ /* short drv_tag; */
+ ret = ACMERR_NOTPOSSIBLE;
+/* if(pwfxSrc->wFormatTag==1)//compression
+ drv_tag=pwfxDst->wFormatTag;
+ else
+ if(pwfxDst->wFormatTag==1)//decompression
+ drv_tag=pwfxSrc->wFormatTag;
+ else
+ goto errCleanUp;
+
+ ret=acmDriverOpen2(drv_tag);
+ if (ret == MMSYSERR_NOERROR) {
+ if ((wad = MSACM_GetDriver(had)) != 0) {
+ was->obj.pACMDriverID = wad->obj.pACMDriverID;
+ was->pDrv = wad;
+ was->hAcmDriver = had;
+
+ ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
+ if (ret == MMSYSERR_NOERROR) {
+ if (fdwOpen & ACM_STREAMOPENF_QUERY) {
+ acmDriverClose(had, 0L);
+ }
+ break;
+ }
+ }
+ acmDriverClose(had, 0L);*/
+ if(MSACM_pFirstACMDriverID==NULL)
+ MSACM_RegisterAllDrivers();
+
+ for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID) {
+ ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L);
+ if (ret == MMSYSERR_NOERROR) {
+ if ((wad = MSACM_GetDriver(had)) != 0) {
+ was->obj.pACMDriverID = wad->obj.pACMDriverID;
+ was->pDrv = wad;
+ was->hAcmDriver = had;
+
+ ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L);
+ if (ret == MMSYSERR_NOERROR) {
+ if (fdwOpen & ACM_STREAMOPENF_QUERY) {
+ acmDriverClose(had, 0L);
+ }
+ break;
+ }
+ }
+ // no match, close this acm driver and try next one
+ acmDriverClose(had, 0L);
+ }
+ }
+ if (ret != MMSYSERR_NOERROR) {
+ ret = ACMERR_NOTPOSSIBLE;
+ goto errCleanUp;
+ }
+ }
+ ret = MMSYSERR_NOERROR;
+ if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) {
+ if (phas)
+ *phas = (HACMSTREAM)was;
+ TRACE("=> (%d)\n", ret);
+ return ret;
+ }
+errCleanUp:
+ if (phas)
+ *phas = (HACMSTREAM)0;
+ HeapFree(MSACM_hHeap, 0, was);
+ TRACE("=> (%d)\n", ret);
+ return ret;
+}
+
+
+MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
+{
+ PWINE_ACMSTREAM was;
+ MMRESULT ret;
+
+ TRACE("(0x%08x, %ld)\n", has, fdwClose);
+
+ if ((was = ACM_GetStream(has)) == NULL) {
+ return MMSYSERR_INVALHANDLE;
+ }
+ ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
+ if (ret == MMSYSERR_NOERROR) {
+ if (was->hAcmDriver)
+ acmDriverClose(was->hAcmDriver, 0L);
+ HeapFree(MSACM_hHeap, 0, was);
+ }
+ TRACE("=> (%d)\n", ret);
+ return ret;
+}
+
+/***********************************************************************
+ * acmStreamConvert (MSACM32.38)
+ */
+MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash,
+ DWORD fdwConvert)
+{
+ PWINE_ACMSTREAM was;
+ MMRESULT ret = MMSYSERR_NOERROR;
+ PACMDRVSTREAMHEADER padsh;
+
+ TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert);
+
+ if ((was = ACM_GetStream(has)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
+ return MMSYSERR_INVALPARAM;
+
+ if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
+ return ACMERR_UNPREPARED;
+
+ /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
+ * size. some fields are private to msacm internals, and are exposed
+ * in ACMSTREAMHEADER in the dwReservedDriver array
+ */
+ padsh = (PACMDRVSTREAMHEADER)pash;
+
+ /* check that pointers have not been modified */
+ if (padsh->pbPreparedSrc != padsh->pbSrc ||
+ padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
+ padsh->pbPreparedDst != padsh->pbDst ||
+ padsh->cbPreparedDstLength < padsh->cbDstLength) {
+ return MMSYSERR_INVALPARAM;
+ }
+
+ padsh->fdwConvert = fdwConvert;
+
+ ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh);
+ if (ret == MMSYSERR_NOERROR) {
+ padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE;
+ }
+ TRACE("=> (%d)\n", ret);
+ return ret;
+}
+
+
+/***********************************************************************
+ * acmStreamPrepareHeader (MSACM32.41)
+ */
+MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
+ DWORD fdwPrepare)
+{
+ PWINE_ACMSTREAM was;
+ MMRESULT ret = MMSYSERR_NOERROR;
+ PACMDRVSTREAMHEADER padsh;
+
+ TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare);
+
+ if ((was = ACM_GetStream(has)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
+ return MMSYSERR_INVALPARAM;
+ if (fdwPrepare)
+ ret = MMSYSERR_INVALFLAG;
+
+ if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE)
+ return MMSYSERR_NOERROR;
+
+ /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
+ * size. some fields are private to msacm internals, and are exposed
+ * in ACMSTREAMHEADER in the dwReservedDriver array
+ */
+ padsh = (PACMDRVSTREAMHEADER)pash;
+
+ padsh->fdwConvert = fdwPrepare;
+ padsh->padshNext = NULL;
+ padsh->fdwDriver = padsh->dwDriver = 0L;
+
+ padsh->fdwPrepared = 0;
+ padsh->dwPrepared = 0;
+ padsh->pbPreparedSrc = 0;
+ padsh->cbPreparedSrcLength = 0;
+ padsh->pbPreparedDst = 0;
+ padsh->cbPreparedDstLength = 0;
+
+ ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
+ if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
+ ret = MMSYSERR_NOERROR;
+ padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE);
+ padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED;
+ padsh->fdwPrepared = padsh->fdwStatus;
+ padsh->dwPrepared = 0;
+ padsh->pbPreparedSrc = padsh->pbSrc;
+ padsh->cbPreparedSrcLength = padsh->cbSrcLength;
+ padsh->pbPreparedDst = padsh->pbDst;
+ padsh->cbPreparedDstLength = padsh->cbDstLength;
+ } else {
+ padsh->fdwPrepared = 0;
+ padsh->dwPrepared = 0;
+ padsh->pbPreparedSrc = 0;
+ padsh->cbPreparedSrcLength = 0;
+ padsh->pbPreparedDst = 0;
+ padsh->cbPreparedDstLength = 0;
+ }
+ TRACE("=> (%d)\n", ret);
+ return ret;
+}
+
+/***********************************************************************
+ * acmStreamReset (MSACM32.42)
+ */
+MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset)
+{
+ PWINE_ACMSTREAM was;
+ MMRESULT ret = MMSYSERR_NOERROR;
+
+ TRACE("(0x%08x, %ld)\n", has, fdwReset);
+
+ if (fdwReset) {
+ ret = MMSYSERR_INVALFLAG;
+ } else if ((was = ACM_GetStream(has)) == NULL) {
+ return MMSYSERR_INVALHANDLE;
+ } else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) {
+ ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0);
+ }
+ TRACE("=> (%d)\n", ret);
+ return ret;
+}
+
+/***********************************************************************
+ * acmStreamSize (MSACM32.43)
+ */
+MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput,
+ LPDWORD pdwOutputBytes, DWORD fdwSize)
+{
+ PWINE_ACMSTREAM was;
+ ACMDRVSTREAMSIZE adss;
+ MMRESULT ret;
+
+ TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize);
+
+ if ((was = ACM_GetStream(has)) == NULL) {
+ return MMSYSERR_INVALHANDLE;
+ }
+ if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) {
+ return MMSYSERR_INVALFLAG;
+ }
+
+ *pdwOutputBytes = 0L;
+
+ switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
+ case ACM_STREAMSIZEF_DESTINATION:
+ adss.cbDstLength = cbInput;
+ adss.cbSrcLength = 0;
+ break;
+ case ACM_STREAMSIZEF_SOURCE:
+ adss.cbSrcLength = cbInput;
+ adss.cbDstLength = 0;
+ break;
+ default:
+ return MMSYSERR_INVALFLAG;
+ }
+
+ adss.cbStruct = sizeof(adss);
+ adss.fdwSize = fdwSize;
+ ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE,
+ (DWORD)&was->drvInst, (DWORD)&adss);
+ if (ret == MMSYSERR_NOERROR) {
+ switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) {
+ case ACM_STREAMSIZEF_DESTINATION:
+ *pdwOutputBytes = adss.cbSrcLength;
+ break;
+ case ACM_STREAMSIZEF_SOURCE:
+ *pdwOutputBytes = adss.cbDstLength;
+ break;
+ }
+ }
+ TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes);
+ return ret;
+}
+
+/***********************************************************************
+ * acmStreamUnprepareHeader (MSACM32.44)
+ */
+MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
+ DWORD fdwUnprepare)
+{
+ PWINE_ACMSTREAM was;
+ MMRESULT ret = MMSYSERR_NOERROR;
+ PACMDRVSTREAMHEADER padsh;
+
+ TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare);
+
+ if ((was = ACM_GetStream(has)) == NULL)
+ return MMSYSERR_INVALHANDLE;
+ if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
+ return MMSYSERR_INVALPARAM;
+
+ if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
+ return ACMERR_UNPREPARED;
+
+ /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
+ * size. some fields are private to msacm internals, and are exposed
+ * in ACMSTREAMHEADER in the dwReservedDriver array
+ */
+ padsh = (PACMDRVSTREAMHEADER)pash;
+
+ /* check that pointers have not been modified */
+ if (padsh->pbPreparedSrc != padsh->pbSrc ||
+ padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
+ padsh->pbPreparedDst != padsh->pbDst ||
+ padsh->cbPreparedDstLength < padsh->cbDstLength) {
+ return MMSYSERR_INVALPARAM;
+ }
+
+ padsh->fdwConvert = fdwUnprepare;
+
+ ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh);
+ if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) {
+ ret = MMSYSERR_NOERROR;
+ padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED);
+ }
+ TRACE("=> (%d)\n", ret);
+ return ret;
+}
diff --git a/src/libw32dll/driver.c b/src/libw32dll/driver.c
new file mode 100644
index 000000000..3e108c660
--- /dev/null
+++ b/src/libw32dll/driver.c
@@ -0,0 +1,182 @@
+#include "config.h"
+#include <stdio.h>
+
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#else
+#include <stdlib.h>
+#endif
+
+#include "wine/driver.h"
+#include "wine/pe_image.h"
+#include "wine/winreg.h"
+#include "wine/vfw.h"
+#include "registry.h"
+
+#ifdef __FreeBSD__
+#include <sys/time.h>
+#endif
+
+//#define WIN32_PATH "/usr/lib/win32"
+
+#define STORE_ALL \
+ __asm__ ( \
+ "push %%ebx\n\t" \
+ "push %%ecx\n\t" \
+ "push %%edx\n\t" \
+ "push %%esi\n\t" \
+ "push %%edi\n\t"::)
+
+#define REST_ALL \
+ __asm__ ( \
+ "pop %%edi\n\t" \
+ "pop %%esi\n\t" \
+ "pop %%edx\n\t" \
+ "pop %%ecx\n\t" \
+ "pop %%ebx\n\t"::)
+
+
+
+typedef struct {
+ UINT uDriverSignature;
+ HINSTANCE hDriverModule;
+ DRIVERPROC DriverProc;
+ DWORD dwDriverID;
+} DRVR;
+
+typedef DRVR *PDRVR;
+typedef DRVR *NPDRVR;
+typedef DRVR *LPDRVR;
+
+static DWORD dwDrvID = 0;
+
+
+LRESULT WINAPI SendDriverMessage( HDRVR hDriver, UINT message,
+ LPARAM lParam1, LPARAM lParam2 )
+{
+ DRVR* module=(DRVR*)hDriver;
+ int result;
+#ifdef DETAILED_OUT
+ printf("SendDriverMessage: driver %X, message %X, arg1 %X, arg2 %X\n", hDriver, message, lParam1, lParam2);
+#endif
+ if(module==0)return -1;
+ if(module->hDriverModule==0)return -1;
+ if(module->DriverProc==0)return -1;
+ STORE_ALL;
+ result=module->DriverProc(module->dwDriverID,1,message,lParam1,lParam2);
+ REST_ALL;
+#ifdef DETAILED_OUT
+ printf("\t\tResult: %X\n", result);
+#endif
+ return result;
+}
+
+static NPDRVR DrvAlloc(HDRVR*lpDriver, LPUINT lpDrvResult)
+{
+ NPDRVR npDriver;
+ /* allocate and lock handle */
+ if (lpDriver)
+ {
+ if ( (*lpDriver = (HDRVR) malloc(sizeof(DRVR))) )
+ {
+ if ((npDriver = (NPDRVR) *lpDriver))
+ {
+ *lpDrvResult = MMSYSERR_NOERROR;
+ return (npDriver);
+ }
+ free((NPDRVR)*lpDriver);
+ }
+ return (*lpDrvResult = MMSYSERR_NOMEM, (NPDRVR) 0);
+ }
+ return (*lpDrvResult = MMSYSERR_INVALPARAM, (NPDRVR) 0);
+}
+
+
+static void DrvFree(HDRVR hDriver)
+{
+ int i;
+ if(hDriver)
+ if(((DRVR*)hDriver)->hDriverModule)
+ if(((DRVR*)hDriver)->DriverProc)
+ (((DRVR*)hDriver)->DriverProc)(((DRVR*)hDriver)->dwDriverID, hDriver, DRV_CLOSE, 0, 0);
+ if(hDriver) {
+ if(((DRVR*)hDriver)->hDriverModule)
+ if(((DRVR*)hDriver)->DriverProc)
+ (((DRVR*)hDriver)->DriverProc)(0, hDriver, DRV_FREE, 0, 0);
+ FreeLibrary(((DRVR*)hDriver)->hDriverModule);
+ free((NPDRVR)hDriver);
+ return;
+ }
+}
+
+void DrvClose(HDRVR hdrvr)
+{
+ DrvFree(hdrvr);
+}
+
+
+#ifndef STATIC_WIN32_PATH
+char* def_path=WIN32_PATH; // path to codecs
+#else
+char* def_path="/usr/lib/win32"; // path to codecs
+#endif
+char* win32_codec_name=NULL; // must be set before calling DrvOpen() !!!
+
+HDRVR
+DrvOpen(LPARAM lParam2)
+{
+ ICOPEN *icopen=lParam2;
+ UINT uDrvResult;
+ HDRVR hDriver;
+ NPDRVR npDriver;
+ char unknown[0x24];
+// char* codec_name=icopen->fccHandler;
+
+ if (!(npDriver = DrvAlloc(&hDriver, &uDrvResult)))
+ return ((HDRVR) 0);
+
+ if (!(npDriver->hDriverModule = expLoadLibraryA(win32_codec_name))) {
+ printf("Can't open library %s\n", win32_codec_name);
+ DrvFree(hDriver);
+ return ((HDRVR) 0);
+ }
+
+ if (!(npDriver->DriverProc = (DRIVERPROC)
+ GetProcAddress(npDriver->hDriverModule, "DriverProc"))) {
+ printf("Library %s is not a valid codec\n", win32_codec_name);
+ FreeLibrary(npDriver->hDriverModule);
+ DrvFree(hDriver);
+ return ((HDRVR) 0);
+ }
+
+ //TRACE("DriverProc == %X\n", npDriver->DriverProc);
+ npDriver->dwDriverID = ++dwDrvID;
+
+ STORE_ALL;
+ (npDriver->DriverProc)(0, hDriver, DRV_LOAD, 0, 0);
+ REST_ALL;
+ //TRACE("DRV_LOAD Ok!\n");
+ STORE_ALL;
+ (npDriver->DriverProc)(0, hDriver, DRV_ENABLE, 0, 0);
+ REST_ALL;
+ //TRACE("DRV_ENABLE Ok!\n");
+
+ // open driver
+ STORE_ALL;
+ npDriver->dwDriverID=(npDriver->DriverProc)(npDriver->dwDriverID, hDriver, DRV_OPEN,
+ (LPARAM) (LPSTR) unknown, lParam2);
+ REST_ALL;
+
+ //TRACE("DRV_OPEN Ok!(%X)\n", npDriver->dwDriverID);
+
+ if (uDrvResult)
+ {
+ DrvFree(hDriver);
+ hDriver = (HDRVR) 0;
+ }
+
+ printf("Successfully loaded codec %s\n",win32_codec_name);
+
+ return (hDriver);
+}
+
diff --git a/src/libw32dll/elfdll.c b/src/libw32dll/elfdll.c
new file mode 100644
index 000000000..3b6923668
--- /dev/null
+++ b/src/libw32dll/elfdll.c
@@ -0,0 +1,305 @@
+/*
+ * Elf-dll loader functions
+ *
+ * Copyright 1999 Bertho A. Stultiens
+ */
+#include "config.h"
+
+#ifdef HAVE_LIBDL
+
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+#include "wine/config.h"
+#include "wine/windef.h"
+//#include "wine/global.h"
+//#include "wine/process.h"
+#include "wine/module.h"
+#include "wine/heap.h"
+#include "wine/elfdll.h"
+#include "wine/debugtools.h"
+#include "wine/winerror.h"
+
+//DEFAULT_DEBUG_CHANNEL(elfdll)
+
+#include <dlfcn.h>
+
+struct modref_list_t;
+
+typedef struct modref_list_t
+{
+ WINE_MODREF* wm;
+ struct modref_list_t *next;
+ struct modref_list_t *prev;
+}
+modref_list;
+
+
+//WINE_MODREF *local_wm=NULL;
+extern modref_list* local_wm;
+
+
+/*------------------ HACKS -----------------*/
+extern DWORD fixup_imports(WINE_MODREF *wm);
+extern void dump_exports(HMODULE hModule);
+/*---------------- END HACKS ---------------*/
+
+//char *extra_ld_library_path = "/usr/lib/win32";
+extern char* def_path;
+
+struct elfdll_image
+{
+ HMODULE pe_module_start;
+ DWORD pe_module_size;
+};
+
+
+/****************************************************************************
+ * ELFDLL_dlopen
+ *
+ * Wrapper for dlopen to search the EXTRA_LD_LIBRARY_PATH from wine.conf
+ * manually because libdl.so caches the environment and does not accept our
+ * changes.
+ */
+void *ELFDLL_dlopen(const char *libname, int flags)
+{
+ char buffer[256];
+ int namelen;
+ void *handle;
+ char *ldpath;
+
+ /* First try the default path search of dlopen() */
+ handle = dlopen(libname, flags);
+ if(handle)
+ return handle;
+
+ /* Now try to construct searches through our extra search-path */
+ namelen = strlen(libname);
+ ldpath = def_path;
+ while(ldpath && *ldpath)
+ {
+ int len;
+ char *cptr;
+ char *from;
+
+ from = ldpath;
+ cptr = strchr(ldpath, ':');
+ if(!cptr)
+ {
+ len = strlen(ldpath);
+ ldpath = NULL;
+ }
+ else
+ {
+ len = cptr - ldpath;
+ ldpath = cptr + 1;
+ }
+
+ if(len + namelen + 1 >= sizeof(buffer))
+ {
+ ERR("Buffer overflow! Check EXTRA_LD_LIBRARY_PATH or increase buffer size.\n");
+ return NULL;
+ }
+
+ strncpy(buffer, from, len);
+ if(len)
+ {
+ buffer[len] = '/';
+ strcpy(buffer + len + 1, libname);
+ }
+ else
+ strcpy(buffer + len, libname);
+
+ TRACE("Trying dlopen('%s', %d)\n", buffer, flags);
+
+ handle = dlopen(buffer, flags);
+ if(handle)
+ return handle;
+ }
+ return NULL;
+}
+
+
+/****************************************************************************
+ * get_sobasename (internal)
+ *
+ */
+static LPSTR get_sobasename(LPCSTR path, LPSTR name)
+{
+ char *cptr;
+
+ /* Strip the path from the library name */
+ if((cptr = strrchr(path, '/')))
+ {
+ char *cp = strrchr(cptr+1, '\\');
+ if(cp && cp > cptr)
+ cptr = cp;
+ }
+ else
+ cptr = strrchr(path, '\\');
+
+ if(!cptr)
+ cptr = (char *)path; /* No '/' nor '\\' in path */
+ else
+ cptr++;
+
+ strcpy(name, cptr);
+ cptr = strrchr(name, '.');
+ if(cptr)
+ *cptr = '\0'; /* Strip extension */
+
+ /* Convert to lower case.
+ * This must be done manually because it is not sure that
+ * other modules are accessible.
+ */
+ for(cptr = name; *cptr; cptr++)
+ *cptr = tolower(*cptr);
+
+ return name;
+}
+
+
+/****************************************************************************
+ * ELFDLL_CreateModref (internal)
+ *
+ * INPUT
+ * hModule - the header from the elf-dll's data-segment
+ * path - requested path from original call
+ *
+ * OUTPUT
+ * A WINE_MODREF pointer to the new object
+ *
+ * BUGS
+ * - Does not handle errors due to dependencies correctly
+ * - path can be wrong
+ */
+#define RVA(base, va) (((DWORD)base) + ((DWORD)va))
+
+static WINE_MODREF *ELFDLL_CreateModref(HMODULE hModule, LPCSTR path)
+{
+// IMAGE_NT_HEADERS *nt = PE_HEADER(hModule);
+ IMAGE_DATA_DIRECTORY *dir;
+ IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL;
+ WINE_MODREF *wm;
+ int len;
+ HANDLE procheap = GetProcessHeap();
+
+ wm = (WINE_MODREF *)HeapAlloc(procheap, HEAP_ZERO_MEMORY, sizeof(*wm));
+ if(!wm)
+ return NULL;
+
+ wm->module = hModule;
+ wm->type = MODULE32_ELF; /* FIXME */
+
+// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT;
+// if(dir->Size)
+// wm->binfmt.pe.pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(hModule, dir->VirtualAddress);
+
+// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT;
+// if(dir->Size)
+// pe_import = wm->binfmt.pe.pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(hModule, dir->VirtualAddress);
+
+// dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE;
+// if(dir->Size)
+// wm->binfmt.pe.pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(hModule, dir->VirtualAddress);
+
+
+ wm->filename = malloc(strlen(path)+1);
+ strcpy(wm->filename, path);
+ wm->modname = strrchr( wm->filename, '\\' );
+ if (!wm->modname) wm->modname = wm->filename;
+ else wm->modname++;
+/*
+ len = GetShortPathNameA( wm->filename, NULL, 0 );
+ wm->short_filename = (char *)HeapAlloc( procheap, 0, len+1 );
+ GetShortPathNameA( wm->filename, wm->short_filename, len+1 );
+ wm->short_modname = strrchr( wm->short_filename, '\\' );
+ if (!wm->short_modname) wm->short_modname = wm->short_filename;
+ else wm->short_modname++;
+*/
+ /* Link MODREF into process list */
+
+// EnterCriticalSection( &PROCESS_Current()->crit_section );
+
+ if(local_wm)
+ {
+ local_wm->next=malloc(sizeof(modref_list));
+ local_wm->next->prev=local_wm;
+ local_wm->next->next=NULL;
+ local_wm->next->wm=wm;
+ local_wm=local_wm->next;
+ }
+ else
+ {
+ local_wm=malloc(sizeof(modref_list));
+ local_wm->next=local_wm->prev=NULL;
+ local_wm->wm=wm;
+ }
+
+// LeaveCriticalSection( &PROCESS_Current()->crit_section );
+ return wm;
+}
+
+/****************************************************************************
+ * ELFDLL_LoadLibraryExA (internal)
+ *
+ * Implementation of elf-dll loading for PE modules
+ */
+WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR path, DWORD flags)
+{
+ LPVOID dlhandle;
+ struct elfdll_image *image;
+ char name[129];
+ char soname[129];
+ WINE_MODREF *wm;
+
+ get_sobasename(path, name);
+ strcpy(soname, name);
+ strcat(soname, ".so");
+
+ /* Try to open the elf-dll */
+ dlhandle = ELFDLL_dlopen(soname, RTLD_LAZY);
+ if(!dlhandle)
+ {
+ WARN("Could not load %s (%s)\n", soname, dlerror());
+ SetLastError( ERROR_FILE_NOT_FOUND );
+ return NULL;
+ }
+
+ /* Get the 'dllname_elfdll_image' variable */
+/* strcpy(soname, name);
+ strcat(soname, "_elfdll_image");
+ image = (struct elfdll_image *)dlsym(dlhandle, soname);
+ if(!image)
+ {
+ ERR("Could not get elfdll image descriptor %s (%s)\n", soname, dlerror());
+ dlclose(dlhandle);
+ SetLastError( ERROR_BAD_FORMAT );
+ return NULL;
+ }
+
+*/
+ wm = ELFDLL_CreateModref((int)dlhandle, path);
+ if(!wm)
+ {
+ ERR("Could not create WINE_MODREF for %s\n", path);
+ dlclose(dlhandle);
+ SetLastError( ERROR_OUTOFMEMORY );
+ return NULL;
+ }
+
+ return wm;
+}
+
+
+/****************************************************************************
+ * ELFDLL_UnloadLibrary (internal)
+ *
+ * Unload an elf-dll completely from memory and deallocate the modref
+ */
+void ELFDLL_UnloadLibrary(WINE_MODREF *wm)
+{
+}
+
+#endif /*HAVE_LIBDL*/
diff --git a/src/libw32dll/ext.c b/src/libw32dll/ext.c
new file mode 100644
index 000000000..f7817dd44
--- /dev/null
+++ b/src/libw32dll/ext.c
@@ -0,0 +1,565 @@
+/********************************************************
+ *
+ *
+ * Stub functions for Wine module
+ *
+ *
+ ********************************************************/
+#include "config.h"
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#else
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdarg.h>
+#include "wine/windef.h"
+//#include "wine/winbase.h"
+int dbg_header_err( const char *dbg_channel, const char *func )
+{
+ return 0;
+}
+int dbg_header_warn( const char *dbg_channel, const char *func )
+{
+ return 0;
+}
+int dbg_header_fixme( const char *dbg_channel, const char *func )
+{
+ return 0;
+}
+int dbg_header_trace( const char *dbg_channel, const char *func )
+{
+ return 0;
+}
+int dbg_vprintf( const char *format, ... )
+{
+ return 0;
+}
+int __vprintf( const char *format, ... )
+{
+#ifdef DETAILED_OUT
+ va_list va;
+ va_start(va, format);
+ vprintf(format, va);
+ va_end(va);
+ fflush(stdout);
+#endif
+ return 0;
+}
+
+int GetProcessHeap()
+{
+ return 1;
+}
+
+void* HeapAlloc(int heap, int flags, int size)
+{
+ if(flags & 0x8)
+ return calloc(size, 1);
+ else
+ return malloc(size);
+}
+
+int HeapFree(int heap, int flags, void* mem)
+{
+ free(mem);
+ return 1;
+}
+
+static int last_error;
+
+int GetLastError()
+{
+ return last_error;
+}
+
+int SetLastError(int error)
+{
+ return last_error=error;
+}
+
+int ReadFile(int handle, void* mem, unsigned long size, long* result, long flags)
+{
+ *result=read(handle, mem, size);
+ return *result;
+}
+int lstrcmpiA(const char* c1, const char* c2)
+{
+ return strcasecmp(c1,c2);
+}
+int lstrcpynA(char* dest, const char* src, int num)
+{
+ return strncmp(dest,src,num);
+}
+int lstrlenA(const char* s)
+{
+ return strlen(s);
+}
+int lstrlenW(const short* s)
+{
+ int l;
+ if(!s)
+ return 0;
+ l=0;
+ while(s[l])
+ l++;
+ return l;
+}
+int lstrcpynWtoA(char* dest, const char* src, int count)
+{
+ int moved=0;
+ if((dest==0) || (src==0))
+ return 0;
+ while(moved<count)
+ {
+ *dest=*src;
+ moved++;
+ if(*src==0)
+ return moved;
+ src++;
+ dest++;
+ }
+}
+int wcsnicmp(const unsigned short* s1, const unsigned short* s2, int n)
+{
+ if(s1==0)
+ return;
+ if(s2==0)
+ return;
+ while(n>0)
+ {
+ if(*s1<*s2)
+ return -1;
+ else
+ if(*s1>*s2)
+ return 1;
+ else
+ if(*s1==0)
+ return 0;
+ s1++;
+ s2++;
+ n--;
+ }
+ return 0;
+}
+
+
+int IsBadReadPtr(void* data, int size)
+{
+ if(size==0)
+ return 0;
+ if(data==NULL)
+ return 1;
+ return 0;
+}
+char* HEAP_strdupA(const char* string)
+{
+// return strdup(string);
+ char* answ=malloc(strlen(string)+1);
+ strcpy(answ, string);
+ return answ;
+}
+short* HEAP_strdupAtoW(void* heap, void* hz, const char* string)
+{
+ int size, i;
+ short* answer;
+ if(string==0)
+ return 0;
+ size=strlen(string);
+ answer=malloc(size+size+2);
+ for(i=0; i<=size; i++)
+ answer[i]=(short)string[i];
+ return answer;
+}
+char* HEAP_strdupWtoA(void* heap, void* hz, const short* string)
+{
+ int size, i;
+ char* answer;
+ if(string==0)
+ return 0;
+ size=0;
+ while(string[size])
+ size++;
+ answer=malloc(size+2);
+ for(i=0; i<=size; i++)
+ answer[i]=(char)string[i];
+ return answer;
+}
+
+/***********************************************************************
+ * FILE_dommap
+ */
+
+//#define MAP_PRIVATE
+//#define MAP_SHARED
+#undef MAP_ANON
+LPVOID FILE_dommap( int unix_handle, LPVOID start,
+ DWORD size_high, DWORD size_low,
+ DWORD offset_high, DWORD offset_low,
+ int prot, int flags )
+{
+ int fd = -1;
+ int pos;
+ LPVOID ret;
+
+ if (size_high || offset_high)
+ printf("offsets larger than 4Gb not supported\n");
+
+ if (unix_handle == -1)
+ {
+#ifdef MAP_ANON
+// printf("Anonymous\n");
+ flags |= MAP_ANON;
+#else
+ static int fdzero = -1;
+
+ if (fdzero == -1)
+ {
+ if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1)
+ {
+ perror( "/dev/zero: open" );
+ exit(1);
+ }
+ }
+ fd = fdzero;
+#endif /* MAP_ANON */
+ /* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */
+#ifdef MAP_SHARED
+ flags &= ~MAP_SHARED;
+#endif
+#ifdef MAP_PRIVATE
+ flags |= MAP_PRIVATE;
+#endif
+ }
+ else fd = unix_handle;
+// printf("fd %x, start %x, size %x, pos %x, prot %x\n",fd,start,size_low, offset_low, prot);
+// if ((ret = mmap( start, size_low, prot,
+// flags, fd, offset_low )) != (LPVOID)-1)
+ if ((ret = mmap( start, size_low, prot,
+ MAP_PRIVATE | MAP_FIXED, fd, offset_low )) != (LPVOID)-1)
+ {
+// printf("address %08x\n", *(int*)ret);
+// printf("%x\n", ret);
+ return ret;
+ }
+
+// printf("mmap %d\n", errno);
+
+ /* mmap() failed; if this is because the file offset is not */
+ /* page-aligned (EINVAL), or because the underlying filesystem */
+ /* does not support mmap() (ENOEXEC), we do it by hand. */
+
+ if (unix_handle == -1) return ret;
+ if ((errno != ENOEXEC) && (errno != EINVAL)) return ret;
+ if (prot & PROT_WRITE)
+ {
+ /* We cannot fake shared write mappings */
+#ifdef MAP_SHARED
+ if (flags & MAP_SHARED) return ret;
+#endif
+#ifdef MAP_PRIVATE
+ if (!(flags & MAP_PRIVATE)) return ret;
+#endif
+ }
+/* printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/
+ /* Reserve the memory with an anonymous mmap */
+ ret = FILE_dommap( -1, start, size_high, size_low, 0, 0,
+ PROT_READ | PROT_WRITE, flags );
+ if (ret == (LPVOID)-1)
+// {
+// perror(
+ return ret;
+ /* Now read in the file */
+ if ((pos = lseek( fd, offset_low, SEEK_SET )) == -1)
+ {
+ FILE_munmap( ret, size_high, size_low );
+// printf("lseek\n");
+ return (LPVOID)-1;
+ }
+ read( fd, ret, size_low );
+ lseek( fd, pos, SEEK_SET ); /* Restore the file pointer */
+ mprotect( ret, size_low, prot ); /* Set the right protection */
+// printf("address %08x\n", *(int*)ret);
+ return ret;
+}
+
+
+/***********************************************************************
+ * FILE_munmap
+ */
+int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low )
+{
+ if (size_high)
+ printf("offsets larger than 4Gb not supported\n");
+ return munmap( start, size_low );
+}
+static int mapping_size=0;
+
+struct file_mapping_s;
+typedef struct file_mapping_s
+{
+ int mapping_size;
+ char* name;
+ HANDLE handle;
+ struct file_mapping_s* next;
+ struct file_mapping_s* prev;
+}file_mapping;
+static file_mapping* fm=0;
+
+
+
+#define PAGE_NOACCESS 0x01
+#define PAGE_READONLY 0x02
+#define PAGE_READWRITE 0x04
+#define PAGE_WRITECOPY 0x08
+#define PAGE_EXECUTE 0x10
+#define PAGE_EXECUTE_READ 0x20
+#define PAGE_EXECUTE_READWRITE 0x40
+#define PAGE_EXECUTE_WRITECOPY 0x80
+#define PAGE_GUARD 0x100
+#define PAGE_NOCACHE 0x200
+
+HANDLE CreateFileMappingA(int hFile, void* lpAttr,
+DWORD flProtect, DWORD dwMaxHigh, DWORD dwMaxLow, const char* name)
+{
+ unsigned int len;
+ HANDLE answer;
+ int anon=0;
+ int mmap_access=0;
+ if(hFile<0)
+ {
+ anon=1;
+ hFile=open("/dev/zero", O_RDWR);
+ if(hFile<0)
+ return 0;
+ }
+ if(!anon)
+ {
+ len=lseek(hFile, 0, SEEK_END);
+ lseek(hFile, 0, SEEK_SET);
+ }
+ else len=dwMaxLow;
+
+ if(flProtect & PAGE_READONLY)
+ mmap_access |=PROT_READ;
+ else
+ mmap_access |=PROT_READ|PROT_WRITE;
+
+ answer=(HANDLE)mmap(NULL, len, mmap_access, MAP_PRIVATE, hFile, 0);
+ if(anon)
+ close(hFile);
+ if(answer!=(HANDLE)-1)
+ {
+ if(fm==0)
+ {
+ fm=malloc(sizeof(file_mapping));
+ fm->prev=NULL;
+ }
+ else
+ {
+ fm->next=malloc(sizeof(file_mapping));
+ fm->next->prev=fm;
+ fm=fm->next;
+ }
+ fm->next=NULL;
+ fm->handle=answer;
+ if(name)
+ {
+ fm->name=malloc(strlen(name)+1);
+ strcpy(fm->name, name);
+ }
+ else
+ fm->name=NULL;
+ fm->mapping_size=len;
+
+ if(anon)
+ close(hFile);
+ return answer;
+ }
+ return (HANDLE)0;
+}
+int UnmapViewOfFile(HANDLE handle)
+{
+ file_mapping* p;
+ int result;
+ if(fm==0)
+ return (HANDLE)0;
+ for(p=fm; p; p=p->next)
+ {
+ if(p->handle==handle)
+ {
+ result=munmap((void*)handle, p->mapping_size);
+ if(p->next)p->next->prev=p->prev;
+ if(p->prev)p->prev->next=p->next;
+ if(p->name)
+ free(p->name);
+ if(p==fm)
+ fm=p->prev;
+ free(p);
+ return result;
+ }
+ }
+ return 0;
+}
+//static int va_size=0;
+struct virt_alloc_s;
+typedef struct virt_alloc_s
+{
+ int mapping_size;
+ char* address;
+ struct virt_alloc_s* next;
+ struct virt_alloc_s* prev;
+ int state;
+}virt_alloc;
+static virt_alloc* vm=0;
+#define MEM_COMMIT 0x00001000
+#define MEM_RESERVE 0x00002000
+
+void* VirtualAlloc(void* address, DWORD size, DWORD type, DWORD protection)
+{
+ void* answer;
+ int fd=open("/dev/zero", O_RDWR);
+ size=(size+0xffff)&(~0xffff);
+// printf("VirtualAlloc(0x%08X, %d)\n", address
+ if(address!=0)
+ {
+ //check whether we can allow to allocate this
+ virt_alloc* str=vm;
+ while(str)
+ {
+ if((unsigned)address>=(unsigned)str->address+str->mapping_size)
+ {
+ str=str->prev;
+ continue;
+ }
+ if((unsigned)address+size<(unsigned)str->address)
+ {
+ str=str->prev;
+ continue;
+ }
+ if(str->state==0)
+ {
+#warning FIXME
+ if(((unsigned)address+size<(unsigned)str->address+str->mapping_size) && (type & MEM_COMMIT))
+ {
+ close(fd);
+ return address; //returning previously reserved memory
+ }
+ return NULL;
+ }
+ close(fd);
+ return NULL;
+ }
+ answer=mmap(address, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_FIXED | MAP_PRIVATE, fd, 0);
+ }
+ else
+ answer=mmap(address, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE, fd, 0);
+// answer=FILE_dommap(-1, address, 0, size, 0, 0,
+// PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
+ close(fd);
+ if(answer==(void*)-1)
+ {
+ printf("Error no %d\n", errno);
+ printf("VirtualAlloc(0x%08X, %d) failed\n", address, size);
+ return NULL;
+ }
+ else
+ {
+ virt_alloc *new_vm=malloc(sizeof(virt_alloc));
+ new_vm->mapping_size=size;
+ new_vm->address=answer;
+ new_vm->prev=vm;
+ if(type == MEM_RESERVE)
+ new_vm->state=0;
+ else
+ new_vm->state=1;
+ if(vm)
+ vm->next=new_vm;
+ vm=new_vm;
+ vm->next=0;
+// if(va_size!=0)
+// printf("Multiple VirtualAlloc!\n");
+// printf("answer=0x%08x\n", answer);
+ return answer;
+ }
+}
+int VirtualFree(void* address, int t1, int t2)//not sure
+{
+ virt_alloc* str=vm;
+ int answer;
+ while(str)
+ {
+ if(address!=str->address)
+ {
+ str=str->prev;
+ continue;
+ }
+ answer=munmap(str->address, str->mapping_size);
+ if(str->next)str->next->prev=str->prev;
+ if(str->prev)str->prev->next=str->next;
+ if(vm==str)vm=0;
+ free(str);
+ return 0;
+ }
+ return -1;
+}
+
+int WideCharToMultiByte(unsigned int codepage, long flags, const short* src,
+ int srclen,char* dest, int destlen, const char* defch, int* used_defch)
+{
+ int i;
+ if(src==0)
+ return 0;
+ for(i=0; i<srclen; i++)
+ printf("%c", src[i]);
+ printf("\n");
+ if(dest==0)
+ {
+ for(i=0; i<srclen; i++)
+ {
+ src++;
+ if(*src==0)
+ return i+1;
+ }
+ return srclen+1;
+ }
+ if(used_defch)
+ *used_defch=0;
+ for(i=0; i<min(srclen, destlen); i++)
+ {
+ *dest=(char)*src;
+ dest++;
+ src++;
+ if(*src==0)
+ return i+1;
+ }
+ return min(srclen, destlen);
+}
+int MultiByteToWideChar(unsigned int codepage,long flags, const char* src, int srclen,
+ short* dest, int destlen)
+{
+ return 0;
+}
+HANDLE OpenFileMappingA(long access, long prot, char* name)
+{
+ file_mapping* p;
+ if(fm==0)
+ return (HANDLE)0;
+ if(name==0)
+ return (HANDLE)0;
+ for(p=fm; p; p=p->prev)
+ {
+ if(p->name==0)
+ continue;
+ if(strcmp(p->name, name)==0)
+ return p->handle;
+ }
+ return 0;
+}
diff --git a/src/libw32dll/loader.h b/src/libw32dll/loader.h
new file mode 100644
index 000000000..f94fe0044
--- /dev/null
+++ b/src/libw32dll/loader.h
@@ -0,0 +1,286 @@
+/********************************************************
+
+ Win32 binary loader interface
+ Copyright 2000 Eugene Smith (divx@euro.ru)
+ Shamelessly stolen from Wine project
+
+*********************************************************/
+
+#ifndef _LOADER_H
+#define _LOADER_H
+#include <wine/windef.h>
+#include <wine/driver.h>
+#include <wine/mmreg.h>
+#include <wine/vfw.h>
+#include <wine/msacm.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void SetCodecPath(const char* path);
+unsigned int _GetPrivateProfileIntA(const char* appname, const char* keyname, int default_value, const char* filename);
+int _GetPrivateProfileStringA(const char* appname, const char* keyname,
+ const char* def_val, char* dest, unsigned int len, const char* filename);
+int _WritePrivateProfileStringA(const char* appname, const char* keyname,
+ const char* string, const char* filename);
+
+
+/**********************************************
+
+ MS VFW ( Video For Windows ) interface
+
+**********************************************/
+
+long VFWAPIV ICCompress(
+ HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpData,
+ LPBITMAPINFOHEADER lpbiInput,void* lpBits,long* lpckid,
+ long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality,
+ LPBITMAPINFOHEADER lpbiPrev,void* lpPrev
+);
+
+long VFWAPIV ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits);
+
+WIN_BOOL VFWAPI ICInfo(long fccType, long fccHandler, ICINFO * lpicinfo);
+LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo, long cb);
+HIC VFWAPI ICOpen(long fccType, long fccHandler, UINT wMode);
+HIC VFWAPI ICOpenFunction(long fccType, long fccHandler, unsigned int wMode, void* lpfnHandler);
+
+LRESULT VFWAPI ICClose(HIC hic);
+LRESULT VFWAPI ICSendMessage(HIC hic, unsigned int msg, long dw1, long dw2);
+HIC VFWAPI ICLocate(long fccType, long fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, short wFlags);
+
+int VFWAPI ICDoSomething();
+
+#define ICCompressGetFormat(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic,ICM_COMPRESS_GET_FORMAT,(long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ )
+
+#define ICCompressGetFormatSize(hic,lpbi) ICCompressGetFormat(hic,lpbi,NULL)
+
+#define ICGetDefaultKeyFrameRate(hic,lpint) \
+ ICSendMessage( \
+ hic, ICM_GETDEFAULTKEYFRAMERATE, \
+ (long)(void*)(lpint), \
+ 0 )
+
+#define ICGetDefaultQuality(hic,lpint) \
+ ICSendMessage( \
+ hic, ICM_GETDEFAULTQUALITY, \
+ (long)(void*)(lpint), \
+ 0 )
+
+
+#define ICCompressBegin(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic, ICM_COMPRESS_BEGIN, (long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ )
+
+#define ICCompressGetSize(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic, ICM_COMPRESS_GET_SIZE, (long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ )
+
+#define ICCompressQuery(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic, ICM_COMPRESS_QUERY, (long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ )
+
+
+#define ICCompressEnd(hic) ICSendMessage(hic, ICM_COMPRESS_END, 0, 0)
+
+
+
+#define ICDecompressBegin(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic, ICM_DECOMPRESS_BEGIN, (long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ )
+
+#define ICDecompressQuery(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic,ICM_DECOMPRESS_QUERY, (long)(void*)(lpbiInput), \
+ (long) (void*)(lpbiOutput) \
+ )
+
+#define ICDecompressGetFormat(hic, lpbiInput, lpbiOutput) \
+ ((long)ICSendMessage( \
+ hic,ICM_DECOMPRESS_GET_FORMAT, (long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ ))
+
+#define ICDecompressGetFormatSize(hic, lpbi) \
+ ICDecompressGetFormat(hic, lpbi, NULL)
+
+#define ICDecompressGetPalette(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic, ICM_DECOMPRESS_GET_PALETTE, (long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ )
+
+#define ICDecompressSetPalette(hic,lpbiPalette) \
+ ICSendMessage( \
+ hic,ICM_DECOMPRESS_SET_PALETTE, \
+ (long)(void*)(lpbiPalette),0 \
+ )
+
+#define ICDecompressEnd(hic) ICSendMessage(hic, ICM_DECOMPRESS_END, 0, 0)
+
+
+/*****************************************************
+
+ MS ACM ( Audio Compression Manager ) interface
+
+******************************************************/
+
+
+MMRESULT WINAPI acmDriverAddA(
+ PHACMDRIVERID phadid, HINSTANCE hinstModule,
+ LPARAM lParam, DWORD dwPriority, DWORD fdwAdd
+);
+MMRESULT WINAPI acmDriverAddW(
+ PHACMDRIVERID phadid, HINSTANCE hinstModule,
+ LPARAM lParam, DWORD dwPriority, DWORD fdwAdd
+);
+MMRESULT WINAPI acmDriverClose(
+ HACMDRIVER had, DWORD fdwClose
+);
+MMRESULT WINAPI acmDriverDetailsA(
+ HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmDriverDetailsW(
+ HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmDriverEnum(
+ ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmDriverID(
+ HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID
+);
+LRESULT WINAPI acmDriverMessage(
+ HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2
+);
+MMRESULT WINAPI acmDriverOpen(
+ PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen
+);
+MMRESULT WINAPI acmDriverPriority(
+ HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority
+);
+MMRESULT WINAPI acmDriverRemove(
+ HACMDRIVERID hadid, DWORD fdwRemove
+);
+MMRESULT WINAPI acmFilterChooseA(
+ PACMFILTERCHOOSEA pafltrc
+);
+MMRESULT WINAPI acmFilterChooseW(
+ PACMFILTERCHOOSEW pafltrc
+);
+MMRESULT WINAPI acmFilterDetailsA(
+ HACMDRIVER had, PACMFILTERDETAILSA pafd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFilterDetailsW(
+ HACMDRIVER had, PACMFILTERDETAILSW pafd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFilterEnumA(
+ HACMDRIVER had, PACMFILTERDETAILSA pafd,
+ ACMFILTERENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFilterEnumW(
+ HACMDRIVER had, PACMFILTERDETAILSW pafd,
+ ACMFILTERENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFilterTagDetailsA(
+ HACMDRIVER had, PACMFILTERTAGDETAILSA paftd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFilterTagDetailsW(
+ HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFilterTagEnumA(
+ HACMDRIVER had, PACMFILTERTAGDETAILSA paftd,
+ ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFilterTagEnumW(
+ HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
+ ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFormatChooseA(
+ PACMFORMATCHOOSEA pafmtc
+);
+MMRESULT WINAPI acmFormatChooseW(
+ PACMFORMATCHOOSEW pafmtc
+);
+MMRESULT WINAPI acmFormatDetailsA(
+ HACMDRIVER had, PACMFORMATDETAILSA pafd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFormatDetailsW(
+ HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFormatEnumA(
+ HACMDRIVER had, PACMFORMATDETAILSA pafd,
+ ACMFORMATENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFormatEnumW(
+ HACMDRIVER had, PACMFORMATDETAILSW pafd,
+ ACMFORMATENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFormatSuggest(
+ HACMDRIVER had, PWAVEFORMATEX pwfxSrc, PWAVEFORMATEX pwfxDst,
+ DWORD cbwfxDst, DWORD fdwSuggest
+);
+MMRESULT WINAPI acmFormatTagDetailsA(
+ HACMDRIVER had, PACMFORMATTAGDETAILSA paftd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFormatTagDetailsW(
+ HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFormatTagEnumA(
+ HACMDRIVER had, PACMFORMATTAGDETAILSA paftd,
+ ACMFORMATTAGENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFormatTagEnumW(
+ HACMDRIVER had, PACMFORMATTAGDETAILSW paftd,
+ ACMFORMATTAGENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+DWORD WINAPI acmGetVersion(
+);
+MMRESULT WINAPI acmMetrics(
+ HACMOBJ hao, UINT uMetric, LPVOID pMetric
+);
+MMRESULT WINAPI acmStreamClose(
+ HACMSTREAM has, DWORD fdwClose
+);
+MMRESULT WINAPI acmStreamConvert(
+ HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwConvert
+);
+MMRESULT WINAPI acmStreamMessage(
+ HACMSTREAM has, UINT uMsg, LPARAM lParam1, LPARAM lParam2
+);
+MMRESULT WINAPI acmStreamOpen(
+ PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
+ PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
+ DWORD dwInstance, DWORD fdwOpen
+);
+MMRESULT WINAPI acmStreamPrepareHeader(
+ HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwPrepare
+);
+MMRESULT WINAPI acmStreamReset(
+ HACMSTREAM has, DWORD fdwReset
+);
+MMRESULT WINAPI acmStreamSize(
+ HACMSTREAM has, DWORD cbInput,
+ LPDWORD pdwOutputBytes, DWORD fdwSize
+);
+MMRESULT WINAPI acmStreamUnprepareHeader(
+ HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwUnprepare
+);
+void MSACM_RegisterAllDrivers(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __LOADER_H */
+
diff --git a/src/libw32dll/module.c b/src/libw32dll/module.c
new file mode 100644
index 000000000..48165afda
--- /dev/null
+++ b/src/libw32dll/module.c
@@ -0,0 +1,618 @@
+/*
+ * Modules
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+#include "config.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+#include <sys/types.h>
+/*
+#ifdef __linux__
+#include <asm/unistd.h>
+#include <asm/ldt.h>
+#else
+#define LDT_ENTRIES 8192
+#define LDT_ENTRY_SIZE 8
+
+struct modify_ldt_ldt_s {
+ unsigned int entry_number;
+ unsigned long base_addr;
+ unsigned int limit;
+ unsigned int seg_32bit:1;
+ unsigned int contents:2;
+ unsigned int read_exec_only:1;
+ unsigned int limit_in_pages:1;
+ unsigned int seg_not_present:1;
+ unsigned int useable:1;
+};
+
+#define MODIFY_LDT_CONTENTS_DATA 0
+#define MODIFY_LDT_CONTENTS_STACK 1
+#define MODIFY_LDT_CONTENTS_CODE 2
+#define __NR_modify_ldt 123
+#endif
+
+*/
+#include "wine/windef.h"
+#include "wine/winerror.h"
+#include "wine/heap.h"
+#include "wine/module.h"
+#include "wine/pe_image.h"
+#include "wine/debugtools.h"
+
+struct modref_list_t;
+
+typedef struct modref_list_t
+{
+ WINE_MODREF* wm;
+ struct modref_list_t *next;
+ struct modref_list_t *prev;
+}
+modref_list;
+
+
+/***********************************************************************
+ * LDT_EntryToBytes
+ *
+ * Convert an ldt_entry structure to the raw bytes of the descriptor.
+ */
+/*static void LDT_EntryToBytes( unsigned long *buffer, const struct modify_ldt_ldt_s *content )
+{
+ *buffer++ = ((content->base_addr & 0x0000ffff) << 16) |
+ (content->limit & 0x0ffff);
+ *buffer = (content->base_addr & 0xff000000) |
+ ((content->base_addr & 0x00ff0000)>>16) |
+ (content->limit & 0xf0000) |
+ (content->contents << 10) |
+ ((content->read_exec_only == 0) << 9) |
+ ((content->seg_32bit != 0) << 22) |
+ ((content->limit_in_pages != 0) << 23) |
+ 0xf000;
+}
+*/
+
+//
+// funcs:
+//
+// 0 read LDT
+// 1 write old mode
+// 0x11 write
+//
+/*
+static int modify_ldt( int func, struct modify_ldt_ldt_s *ptr,
+ unsigned long count )
+{
+ int res;
+#ifdef __PIC__
+ __asm__ __volatile__( "pushl %%ebx\n\t"
+ "movl %2,%%ebx\n\t"
+ "int $0x80\n\t"
+ "popl %%ebx"
+ : "=a" (res)
+ : "0" (__NR_modify_ldt),
+ "r" (func),
+ "c" (ptr),
+ "d" (sizeof(struct modify_ldt_ldt_s)*count) );
+#else
+ __asm__ __volatile__("int $0x80"
+ : "=a" (res)
+ : "0" (__NR_modify_ldt),
+ "b" (func),
+ "c" (ptr),
+ "d" (sizeof(struct modify_ldt_ldt_s)*count) );
+#endif
+ if (res >= 0) return res;
+ errno = -res;
+ return -1;
+}
+static int fs_installed=0;
+static char* fs_seg=0;
+static int install_fs()
+{
+ struct modify_ldt_ldt_s array;
+ int fd;
+ int ret;
+ void* prev_struct;
+
+ if(fs_installed)
+ return 0;
+
+ fd=open("/dev/zero", O_RDWR);
+ fs_seg=mmap((void*)0xbf000000, 0x30000, PROT_READ | PROT_WRITE, MAP_PRIVATE,
+ fd, 0);
+ if(fs_seg==0)
+ {
+ printf("ERROR: Couldn't allocate memory for fs segment\n");
+ return -1;
+ }
+ array.base_addr=((int)fs_seg+0xffff) & 0xffff0000;
+ array.entry_number=0x1;
+ array.limit=array.base_addr+getpagesize()-1;
+ array.seg_32bit=1;
+ array.read_exec_only=0;
+ array.seg_not_present=0;
+ array.contents=MODIFY_LDT_CONTENTS_DATA;
+ array.limit_in_pages=0;
+#ifdef linux
+ ret=modify_ldt(0x1, &array, 1);
+ if(ret<0)
+ {
+ perror("install_fs");
+ MESSAGE("Couldn't install fs segment, expect segfault\n");
+ }
+#endif
+
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+ {
+ long d[2];
+
+ LDT_EntryToBytes( d, &array );
+ ret = i386_set_ldt(0x1, (union descriptor *)d, 1);
+ if (ret < 0)
+ {
+ perror("install_fs");
+ MESSAGE("Did you reconfigure the kernel with \"options USER_LDT\"?\n");
+ }
+ }
+#endif
+ __asm__
+ (
+ "movl $0xf,%eax\n\t"
+// "pushw %ax\n\t"
+ "movw %ax, %fs\n\t"
+ );
+ prev_struct=malloc(8);
+ *(void**)array.base_addr=prev_struct;
+ printf("prev_struct: 0x%X\n", prev_struct);
+ close(fd);
+
+ fs_installed=1;
+ return 0;
+};
+static int uninstall_fs()
+{
+ printf("Uninstalling FS segment\n");
+ if(fs_seg==0)
+ return -1;
+ munmap(fs_seg, 0x30000);
+ fs_installed=0;
+ return 0;
+}
+
+*/
+//WINE_MODREF *local_wm=NULL;
+modref_list* local_wm=NULL;
+
+WINE_MODREF *MODULE_FindModule(LPCSTR m)
+{
+ modref_list* list=local_wm;
+ TRACE("Module %s request\n", m);
+ if(list==NULL)
+ return NULL;
+ while(strcmp(m, list->wm->filename))
+ {
+// printf("%s: %x\n", list->wm->filename, list->wm->module);
+ list=list->prev;
+ if(list==NULL)
+ return NULL;
+ }
+ TRACE("Resolved to %s\n", list->wm->filename);
+ return list->wm;
+}
+
+void MODULE_RemoveFromList(WINE_MODREF *mod)
+{
+ modref_list* list=local_wm;
+ if(list==0)
+ return;
+ if(mod==0)
+ return;
+ if((list->prev==NULL)&&(list->next==NULL))
+ {
+ free(list);
+ local_wm=NULL;
+// uninstall_fs();
+ return;
+ }
+ for(;list;list=list->prev)
+ {
+ if(list->wm==mod)
+ {
+ if(list->prev)
+ list->prev->next=list->next;
+ if(list->next)
+ list->next->prev=list->prev;
+ if(list==local_wm)
+ local_wm=list->prev;
+ free(list);
+ return;
+ }
+ }
+}
+
+WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m)
+{
+ modref_list* list=local_wm;
+ TRACE("Module %X request\n", m);
+ if(list==NULL)
+ return NULL;
+ while(m!=list->wm->module)
+ {
+// printf("Checking list %X wm %X module %X\n",
+// list, list->wm, list->wm->module);
+ list=list->prev;
+ if(list==NULL)
+ return NULL;
+ }
+ TRACE("LookupHMODULE hit %X\n", list->wm);
+ return list->wm;
+}
+
+/*************************************************************************
+ * MODULE_InitDll
+ */
+static WIN_BOOL MODULE_InitDll( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
+{
+ WIN_BOOL retv = TRUE;
+
+ static LPCSTR typeName[] = { "PROCESS_DETACH", "PROCESS_ATTACH",
+ "THREAD_ATTACH", "THREAD_DETACH" };
+ assert( wm );
+
+
+ /* Skip calls for modules loaded with special load flags */
+
+ if ( ( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS )
+ || ( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) )
+ return TRUE;
+
+
+ TRACE("(%s,%s,%p) - CALL\n", wm->modname, typeName[type], lpReserved );
+
+ /* Call the initialization routine */
+ switch ( wm->type )
+ {
+ case MODULE32_PE:
+ retv = PE_InitDLL( wm, type, lpReserved );
+ break;
+
+ case MODULE32_ELF:
+ /* no need to do that, dlopen() already does */
+ break;
+
+ default:
+ ERR("wine_modref type %d not handled.\n", wm->type );
+ retv = FALSE;
+ break;
+ }
+
+ /* The state of the module list may have changed due to the call
+ to PE_InitDLL. We cannot assume that this module has not been
+ deleted. */
+ TRACE("(%p,%s,%p) - RETURN %d\n", wm, typeName[type], lpReserved, retv );
+
+ return retv;
+}
+
+/*************************************************************************
+ * MODULE_DllProcessAttach
+ *
+ * Send the process attach notification to all DLLs the given module
+ * depends on (recursively). This is somewhat complicated due to the fact that
+ *
+ * - we have to respect the module dependencies, i.e. modules implicitly
+ * referenced by another module have to be initialized before the module
+ * itself can be initialized
+ *
+ * - the initialization routine of a DLL can itself call LoadLibrary,
+ * thereby introducing a whole new set of dependencies (even involving
+ * the 'old' modules) at any time during the whole process
+ *
+ * (Note that this routine can be recursively entered not only directly
+ * from itself, but also via LoadLibrary from one of the called initialization
+ * routines.)
+ *
+ * Furthermore, we need to rearrange the main WINE_MODREF list to allow
+ * the process *detach* notifications to be sent in the correct order.
+ * This must not only take into account module dependencies, but also
+ * 'hidden' dependencies created by modules calling LoadLibrary in their
+ * attach notification routine.
+ *
+ * The strategy is rather simple: we move a WINE_MODREF to the head of the
+ * list after the attach notification has returned. This implies that the
+ * detach notifications are called in the reverse of the sequence the attach
+ * notifications *returned*.
+ *
+ * NOTE: Assumes that the process critical section is held!
+ *
+ */
+WIN_BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved )
+{
+ WIN_BOOL retv = TRUE;
+ /* int i; */
+ assert( wm );
+
+ /* prevent infinite recursion in case of cyclical dependencies */
+ if ( ( wm->flags & WINE_MODREF_MARKER )
+ || ( wm->flags & WINE_MODREF_PROCESS_ATTACHED ) )
+ return retv;
+
+ TRACE("(%s,%p) - START\n", wm->modname, lpReserved );
+
+ /* Tag current MODREF to prevent recursive loop */
+ wm->flags |= WINE_MODREF_MARKER;
+
+ /* Recursively attach all DLLs this one depends on */
+/* for ( i = 0; retv && i < wm->nDeps; i++ )
+ if ( wm->deps[i] )
+ retv = MODULE_DllProcessAttach( wm->deps[i], lpReserved );
+*/
+ /* Call DLL entry point */
+
+ //local_wm=wm;
+ if(local_wm)
+ {
+ local_wm->next=malloc(sizeof(modref_list));
+ local_wm->next->prev=local_wm;
+ local_wm->next->next=NULL;
+ local_wm->next->wm=wm;
+ local_wm=local_wm->next;
+ }
+ else
+ {
+ local_wm=malloc(sizeof(modref_list));
+ local_wm->next=local_wm->prev=NULL;
+ local_wm->wm=wm;
+ }
+ /* Remove recursion flag */
+ wm->flags &= ~WINE_MODREF_MARKER;
+
+ if ( retv )
+ {
+ retv = MODULE_InitDll( wm, DLL_PROCESS_ATTACH, lpReserved );
+ if ( retv )
+ wm->flags |= WINE_MODREF_PROCESS_ATTACHED;
+ }
+
+
+ TRACE("(%s,%p) - END\n", wm->modname, lpReserved );
+
+ return retv;
+}
+
+/*************************************************************************
+ * MODULE_DllProcessDetach
+ *
+ * Send DLL process detach notifications. See the comment about calling
+ * sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag
+ * is set, only DLLs with zero refcount are notified.
+ */
+void MODULE_DllProcessDetach( WINE_MODREF* wm, WIN_BOOL bForceDetach, LPVOID lpReserved )
+{
+// WINE_MODREF *wm=local_wm;
+ wm->flags &= ~WINE_MODREF_PROCESS_ATTACHED;
+ MODULE_InitDll( wm, DLL_PROCESS_DETACH, lpReserved );
+}
+
+
+/***********************************************************************
+ * LoadLibraryExA (KERNEL32)
+ */
+HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags)
+{
+ WINE_MODREF *wm;
+
+ if(!libname)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+// if(fs_installed==0)
+// install_fs();
+
+
+ wm = MODULE_LoadLibraryExA( libname, hfile, flags );
+ if ( wm )
+ {
+ if ( !MODULE_DllProcessAttach( wm, NULL ) )
+ {
+ WARN_(module)("Attach failed for module '%s', \n", libname);
+ MODULE_FreeLibrary(wm);
+ SetLastError(ERROR_DLL_INIT_FAILED);
+ MODULE_RemoveFromList(wm);
+ wm = NULL;
+ }
+ }
+
+ return wm ? wm->module : 0;
+}
+
+
+/***********************************************************************
+ * MODULE_LoadLibraryExA (internal)
+ *
+ * Load a PE style module according to the load order.
+ *
+ * The HFILE parameter is not used and marked reserved in the SDK. I can
+ * only guess that it should force a file to be mapped, but I rather
+ * ignore the parameter because it would be extremely difficult to
+ * integrate this with different types of module represenations.
+ *
+ */
+WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags )
+{
+ DWORD err = GetLastError();
+ WINE_MODREF *pwm;
+ /* int i; */
+// module_loadorder_t *plo;
+
+
+ SetLastError( ERROR_FILE_NOT_FOUND );
+ TRACE("Trying native dll '%s'\n", libname);
+ pwm = PE_LoadLibraryExA(libname, flags);
+#ifdef HAVE_LIBDL
+ if(!pwm)
+ {
+ TRACE("Trying ELF dll '%s'\n", libname);
+ pwm=(WINE_MODREF*)ELFDLL_LoadLibraryExA(libname, flags);
+ }
+#endif
+// printf("0x%08x\n", pwm);
+// break;
+ if(pwm)
+ {
+ /* Initialize DLL just loaded */
+ TRACE("Loaded module '%s' at 0x%08x, \n", libname, pwm->module);
+ /* Set the refCount here so that an attach failure will */
+ /* decrement the dependencies through the MODULE_FreeLibrary call. */
+ pwm->refCount++;
+
+ SetLastError( err ); /* restore last error */
+ return pwm;
+ }
+
+
+ WARN("Failed to load module '%s'; error=0x%08lx, \n", libname, GetLastError());
+ return NULL;
+}
+
+/***********************************************************************
+ * LoadLibraryA (KERNEL32)
+ */
+HMODULE WINAPI LoadLibraryA(LPCSTR libname) {
+ return LoadLibraryExA(libname,0,0);
+}
+
+
+/***********************************************************************
+ * FreeLibrary
+ */
+WIN_BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
+{
+ WIN_BOOL retv = FALSE;
+ WINE_MODREF *wm;
+
+ wm=MODULE32_LookupHMODULE(hLibModule);
+// wm=local_wm;
+
+ if ( !wm || !hLibModule )
+ {
+ SetLastError( ERROR_INVALID_HANDLE );
+ return 0;
+ }
+ else
+ retv = MODULE_FreeLibrary( wm );
+
+ MODULE_RemoveFromList(wm);
+
+ return retv;
+}
+
+/***********************************************************************
+ * MODULE_DecRefCount
+ *
+ * NOTE: Assumes that the process critical section is held!
+ */
+static void MODULE_DecRefCount( WINE_MODREF *wm )
+{
+ int i;
+
+ if ( wm->flags & WINE_MODREF_MARKER )
+ return;
+
+ if ( wm->refCount <= 0 )
+ return;
+
+ --wm->refCount;
+ TRACE("(%s) refCount: %d\n", wm->modname, wm->refCount );
+
+ if ( wm->refCount == 0 )
+ {
+ wm->flags |= WINE_MODREF_MARKER;
+
+ for ( i = 0; i < wm->nDeps; i++ )
+ if ( wm->deps[i] )
+ MODULE_DecRefCount( wm->deps[i] );
+
+ wm->flags &= ~WINE_MODREF_MARKER;
+ }
+}
+
+/***********************************************************************
+ * MODULE_FreeLibrary
+ *
+ * NOTE: Assumes that the process critical section is held!
+ */
+WIN_BOOL MODULE_FreeLibrary( WINE_MODREF *wm )
+{
+ TRACE("(%s) - START\n", wm->modname );
+
+ /* Recursively decrement reference counts */
+ //MODULE_DecRefCount( wm );
+
+ /* Call process detach notifications */
+ MODULE_DllProcessDetach( wm, FALSE, NULL );
+
+ PE_UnloadLibrary(wm);
+
+ TRACE("END\n");
+
+ return TRUE;
+}
+
+/***********************************************************************
+ * GetProcAddress (KERNEL32.257)
+ */
+FARPROC WINAPI GetProcAddress( HMODULE hModule, LPCSTR function )
+{
+ return MODULE_GetProcAddress( hModule, function, TRUE );
+}
+
+/***********************************************************************
+ * MODULE_GetProcAddress (internal)
+ */
+FARPROC MODULE_GetProcAddress(
+ HMODULE hModule, /* [in] current module handle */
+ LPCSTR function, /* [in] function to be looked up */
+ WIN_BOOL snoop )
+{
+ WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
+// WINE_MODREF *wm=local_wm;
+ FARPROC retproc;
+
+ if (HIWORD(function))
+ TRACE_(win32)("(%08lx,%s)\n",(DWORD)hModule,function);
+ else
+ TRACE_(win32)("(%08lx,%p)\n",(DWORD)hModule,function);
+ if (!wm) {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return (FARPROC)0;
+ }
+ switch (wm->type)
+ {
+ case MODULE32_PE:
+ retproc = PE_FindExportedFunction( wm, function, snoop );
+ if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND);
+ return retproc;
+#ifdef HAVE_LIBDL
+ case MODULE32_ELF:
+ retproc = (FARPROC) dlsym( wm->module, function);
+ if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND);
+ return retproc;
+#endif
+ default:
+ ERR("wine_modref type %d not handled.\n",wm->type);
+ SetLastError(ERROR_INVALID_HANDLE);
+ return (FARPROC)0;
+ }
+}
+
diff --git a/src/libw32dll/pe_image.c b/src/libw32dll/pe_image.c
new file mode 100644
index 000000000..45fee075c
--- /dev/null
+++ b/src/libw32dll/pe_image.c
@@ -0,0 +1,936 @@
+/*
+ * Copyright 1994 Eric Youndale & Erik Bos
+ * Copyright 1995 Martin von Löwis
+ * Copyright 1996-98 Marcus Meissner
+ *
+ * based on Eric Youndale's pe-test and:
+ *
+ * ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP
+ * make that:
+ * ftp.microsoft.com:/developr/MSDN/OctCD/PEFILE.ZIP
+ */
+/* Notes:
+ * Before you start changing something in this file be aware of the following:
+ *
+ * - There are several functions called recursively. In a very subtle and
+ * obscure way. DLLs can reference each other recursively etc.
+ * - If you want to enhance, speed up or clean up something in here, think
+ * twice WHY it is implemented in that strange way. There is usually a reason.
+ * Though sometimes it might just be lazyness ;)
+ * - In PE_MapImage, right before fixup_imports() all external and internal
+ * state MUST be correct since this function can be called with the SAME image
+ * AGAIN. (Thats recursion for you.) That means MODREF.module and
+ * NE_MODULE.module32.
+ * - Sometimes, we can't use Linux mmap() to mmap() the images directly.
+ *
+ * The problem is, that there is not direct 1:1 mapping from a diskimage and
+ * a memoryimage. The headers at the start are mapped linear, but the sections
+ * are not. Older x86 pe binaries are 512 byte aligned in file and 4096 byte
+ * aligned in memory. Linux likes them 4096 byte aligned in memory (due to
+ * x86 pagesize, this cannot be fixed without a rather large kernel rewrite)
+ * and 'blocksize' file-aligned (offsets). Since we have 512/1024/2048 (CDROM)
+ * and other byte blocksizes, we can't always do this. We *can* do this for
+ * newer pe binaries produced by MSVC 5 and later, since they are also aligned
+ * to 4096 byte boundaries on disk.
+ */
+#include "config.h"
+#include "wine/config.h"
+
+#include <errno.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#include "wine/windef.h"
+#include "wine/winbase.h"
+#include "wine/winerror.h"
+#include "wine/heap.h"
+#include "wine/pe_image.h"
+#include "wine/module.h"
+#include "wine/debugtools.h"
+
+#include "win32.h"
+
+#define RVA(x) ((void *)((char *)load_addr+(unsigned int)(x)))
+
+#define AdjustPtr(ptr,delta) ((char *)(ptr) + (delta))
+
+extern void* LookupExternal(const char* library, int ordinal);
+extern void* LookupExternalByName(const char* library, const char* name);
+
+void dump_exports( HMODULE hModule )
+{
+ char *Module;
+ int i, j;
+ u_short *ordinal;
+ u_long *function,*functions;
+ u_char **name;
+ unsigned int load_addr = hModule;
+
+ DWORD rva_start = PE_HEADER(hModule)->OptionalHeader
+ .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+ DWORD rva_end = rva_start + PE_HEADER(hModule)->OptionalHeader
+ .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
+ IMAGE_EXPORT_DIRECTORY *pe_exports = (IMAGE_EXPORT_DIRECTORY*)RVA(rva_start);
+
+ Module = (char*)RVA(pe_exports->Name);
+ TRACE("*******EXPORT DATA*******\n");
+ TRACE("Module name is %s, %ld functions, %ld names\n",
+ Module, pe_exports->NumberOfFunctions, pe_exports->NumberOfNames);
+
+ ordinal=(u_short*) RVA(pe_exports->AddressOfNameOrdinals);
+ functions=function=(u_long*) RVA(pe_exports->AddressOfFunctions);
+ name=(u_char**) RVA(pe_exports->AddressOfNames);
+
+ TRACE(" Ord RVA Addr Name\n" );
+ for (i=0;i<pe_exports->NumberOfFunctions;i++, function++)
+ {
+ if (!*function) continue;
+ if (TRACE_ON(win32))
+ {
+ DPRINTF( "%4ld %08lx %p", i + pe_exports->Base, *function, RVA(*function) );
+
+ for (j = 0; j < pe_exports->NumberOfNames; j++)
+ if (ordinal[j] == i)
+ {
+ DPRINTF( " %s", (char*)RVA(name[j]) );
+ break;
+ }
+ if ((*function >= rva_start) && (*function <= rva_end))
+ DPRINTF(" (forwarded -> %s)", (char *)RVA(*function));
+ DPRINTF("\n");
+ }
+ }
+}
+
+/* Look up the specified function or ordinal in the exportlist:
+ * If it is a string:
+ * - look up the name in the Name list.
+ * - look up the ordinal with that index.
+ * - use the ordinal as offset into the functionlist
+ * If it is a ordinal:
+ * - use ordinal-pe_export->Base as offset into the functionlist
+ */
+FARPROC PE_FindExportedFunction(
+ WINE_MODREF *wm,
+ LPCSTR funcName,
+ WIN_BOOL snoop )
+{
+ u_short * ordinals;
+ u_long * function;
+ u_char ** name, *ename = NULL;
+ int i, ordinal;
+ PE_MODREF *pem = &(wm->binfmt.pe);
+ IMAGE_EXPORT_DIRECTORY *exports = pem->pe_export;
+ unsigned int load_addr = wm->module;
+ u_long rva_start, rva_end, addr;
+ char * forward;
+
+ if (HIWORD(funcName))
+ TRACE("(%s)\n",funcName);
+ else
+ TRACE("(%d)\n",(int)funcName);
+ if (!exports) {
+ /* Not a fatal problem, some apps do
+ * GetProcAddress(0,"RegisterPenApp") which triggers this
+ * case.
+ */
+ WARN("Module %08x(%s)/MODREF %p doesn't have a exports table.\n",wm->module,wm->modname,pem);
+ return NULL;
+ }
+ ordinals= (u_short*) RVA(exports->AddressOfNameOrdinals);
+ function= (u_long*) RVA(exports->AddressOfFunctions);
+ name = (u_char **) RVA(exports->AddressOfNames);
+ forward = NULL;
+ rva_start = PE_HEADER(wm->module)->OptionalHeader
+ .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
+ rva_end = rva_start + PE_HEADER(wm->module)->OptionalHeader
+ .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
+
+ if (HIWORD(funcName))
+ {
+
+ int min = 0, max = exports->NumberOfNames - 1;
+ while (min <= max)
+ {
+ int res, pos = (min + max) / 2;
+ ename = RVA(name[pos]);
+ if (!(res = strcmp( ename, funcName )))
+ {
+ ordinal = ordinals[pos];
+ goto found;
+ }
+ if (res > 0) max = pos - 1;
+ else min = pos + 1;
+ }
+
+ for (i = 0; i < exports->NumberOfNames; i++)
+ {
+ ename = RVA(name[i]);
+ if (!strcmp( ename, funcName ))
+ {
+ ERR( "%s.%s required a linear search\n", wm->modname, funcName );
+ ordinal = ordinals[i];
+ goto found;
+ }
+ }
+ return NULL;
+ }
+ else
+ {
+ ordinal = LOWORD(funcName) - exports->Base;
+ if (snoop && name)
+ {
+ for (i = 0; i < exports->NumberOfNames; i++)
+ if (ordinals[i] == ordinal)
+ {
+ ename = RVA(name[i]);
+ break;
+ }
+ }
+ }
+
+ found:
+ if (ordinal >= exports->NumberOfFunctions)
+ {
+ TRACE(" ordinal %ld out of range!\n", ordinal + exports->Base );
+ return NULL;
+ }
+ addr = function[ordinal];
+ if (!addr) return NULL;
+ if ((addr < rva_start) || (addr >= rva_end))
+ {
+ FARPROC proc = RVA(addr);
+ if (snoop)
+ {
+ if (!ename) ename = "@";
+// proc = SNOOP_GetProcAddress(wm->module,ename,ordinal,proc);
+ TRACE("SNOOP_GetProcAddress n/a\n");
+
+ }
+ return proc;
+ }
+ else
+ {
+ WINE_MODREF *wm;
+ char *forward = RVA(addr);
+ char module[256];
+ char *end = strchr(forward, '.');
+
+ if (!end) return NULL;
+ if (end - forward >= sizeof(module)) return NULL;
+ memcpy( module, forward, end - forward );
+ module[end-forward] = 0;
+ if (!(wm = MODULE_FindModule( module )))
+ {
+ ERR("module not found for forward '%s'\n", forward );
+ return NULL;
+ }
+ return MODULE_GetProcAddress( wm->module, end + 1, snoop );
+ }
+}
+
+DWORD fixup_imports( WINE_MODREF *wm )
+{
+ IMAGE_IMPORT_DESCRIPTOR *pe_imp;
+ PE_MODREF *pem;
+ unsigned int load_addr = wm->module;
+ int i,characteristics_detection=1;
+ char *modname;
+
+ assert(wm->type==MODULE32_PE);
+ pem = &(wm->binfmt.pe);
+ if (pem->pe_export)
+ modname = (char*) RVA(pem->pe_export->Name);
+ else
+ modname = "<unknown>";
+
+
+ TRACE("Dumping imports list\n");
+
+
+ pe_imp = pem->pe_import;
+ if (!pe_imp) return 0;
+
+ /* We assume that we have at least one import with !0 characteristics and
+ * detect broken imports with all characteristsics 0 (notably Borland) and
+ * switch the detection off for them.
+ */
+ for (i = 0; pe_imp->Name ; pe_imp++) {
+ if (!i && !pe_imp->u.Characteristics)
+ characteristics_detection = 0;
+ if (characteristics_detection && !pe_imp->u.Characteristics)
+ break;
+ i++;
+ }
+ if (!i) return 0;
+
+
+ wm->nDeps = i;
+ wm->deps = HeapAlloc( GetProcessHeap(), 0, i*sizeof(WINE_MODREF *) );
+
+ /* load the imported modules. They are automatically
+ * added to the modref list of the process.
+ */
+
+ for (i = 0, pe_imp = pem->pe_import; pe_imp->Name ; pe_imp++) {
+ WINE_MODREF *wmImp;
+ IMAGE_IMPORT_BY_NAME *pe_name;
+ PIMAGE_THUNK_DATA import_list,thunk_list;
+ char *name = (char *) RVA(pe_imp->Name);
+
+ if (characteristics_detection && !pe_imp->u.Characteristics)
+ break;
+
+//#warning FIXME: here we should fill imports
+ TRACE("Loading imports for %s.dll\n", name);
+
+ if (pe_imp->u.OriginalFirstThunk != 0) {
+ TRACE("Microsoft style imports used\n");
+ import_list =(PIMAGE_THUNK_DATA) RVA(pe_imp->u.OriginalFirstThunk);
+ thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk);
+
+ while (import_list->u1.Ordinal) {
+ if (IMAGE_SNAP_BY_ORDINAL(import_list->u1.Ordinal)) {
+ int ordinal = IMAGE_ORDINAL(import_list->u1.Ordinal);
+
+// TRACE("--- Ordinal %s,%d\n", name, ordinal);
+
+ thunk_list->u1.Function=LookupExternal(
+ name, ordinal);
+ } else {
+ pe_name = (PIMAGE_IMPORT_BY_NAME)RVA(import_list->u1.AddressOfData);
+// TRACE("--- %s %s.%d\n", pe_name->Name, name, pe_name->Hint);
+ thunk_list->u1.Function=LookupExternalByName(
+ name, pe_name->Name);
+ }
+ import_list++;
+ thunk_list++;
+ }
+ } else {
+ TRACE("Borland style imports used\n");
+ thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk);
+ while (thunk_list->u1.Ordinal) {
+ if (IMAGE_SNAP_BY_ORDINAL(thunk_list->u1.Ordinal)) {
+
+ int ordinal = IMAGE_ORDINAL(thunk_list->u1.Ordinal);
+
+ TRACE("--- Ordinal %s.%d\n",name,ordinal);
+ thunk_list->u1.Function=LookupExternal(
+ name, ordinal);
+ } else {
+ pe_name=(PIMAGE_IMPORT_BY_NAME) RVA(thunk_list->u1.AddressOfData);
+ TRACE("--- %s %s.%d\n",
+ pe_name->Name,name,pe_name->Hint);
+ thunk_list->u1.Function=LookupExternalByName(
+ name, pe_name->Name);
+ }
+ thunk_list++;
+ }
+ }
+
+
+ }
+ return 0;
+}
+
+static int calc_vma_size( HMODULE hModule )
+{
+ int i,vma_size = 0;
+ IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(hModule);
+
+ TRACE("Dump of segment table\n");
+ TRACE(" Name VSz Vaddr SzRaw Fileadr *Reloc *Lineum #Reloc #Linum Char\n");
+ for (i = 0; i< PE_HEADER(hModule)->FileHeader.NumberOfSections; i++)
+ {
+ TRACE("%8s: %4.4lx %8.8lx %8.8lx %8.8lx %8.8lx %8.8lx %4.4x %4.4x %8.8lx\n",
+ pe_seg->Name,
+ pe_seg->Misc.VirtualSize,
+ pe_seg->VirtualAddress,
+ pe_seg->SizeOfRawData,
+ pe_seg->PointerToRawData,
+ pe_seg->PointerToRelocations,
+ pe_seg->PointerToLinenumbers,
+ pe_seg->NumberOfRelocations,
+ pe_seg->NumberOfLinenumbers,
+ pe_seg->Characteristics);
+ vma_size=max(vma_size, pe_seg->VirtualAddress+pe_seg->SizeOfRawData);
+ vma_size=max(vma_size, pe_seg->VirtualAddress+pe_seg->Misc.VirtualSize);
+ pe_seg++;
+ }
+ return vma_size;
+}
+
+static void do_relocations( unsigned int load_addr, IMAGE_BASE_RELOCATION *r )
+{
+ int delta = load_addr - PE_HEADER(load_addr)->OptionalHeader.ImageBase;
+ int hdelta = (delta >> 16) & 0xFFFF;
+ int ldelta = delta & 0xFFFF;
+
+ if(delta == 0)
+
+ return;
+ while(r->VirtualAddress)
+ {
+ char *page = (char*) RVA(r->VirtualAddress);
+ int count = (r->SizeOfBlock - 8)/2;
+ int i;
+ TRACE_(fixup)("%x relocations for page %lx\n",
+ count, r->VirtualAddress);
+
+ for(i=0;i<count;i++)
+ {
+ int offset = r->TypeOffset[i] & 0xFFF;
+ int type = r->TypeOffset[i] >> 12;
+// TRACE_(fixup)("patching %x type %x\n", offset, type);
+ switch(type)
+ {
+ case IMAGE_REL_BASED_ABSOLUTE: break;
+ case IMAGE_REL_BASED_HIGH:
+ *(short*)(page+offset) += hdelta;
+ break;
+ case IMAGE_REL_BASED_LOW:
+ *(short*)(page+offset) += ldelta;
+ break;
+ case IMAGE_REL_BASED_HIGHLOW:
+ *(int*)(page+offset) += delta;
+
+ break;
+ case IMAGE_REL_BASED_HIGHADJ:
+ FIXME("Don't know what to do with IMAGE_REL_BASED_HIGHADJ\n");
+ break;
+ case IMAGE_REL_BASED_MIPS_JMPADDR:
+ FIXME("Is this a MIPS machine ???\n");
+ break;
+ default:
+ FIXME("Unknown fixup type\n");
+ break;
+ }
+ }
+ r = (IMAGE_BASE_RELOCATION*)((char*)r + r->SizeOfBlock);
+ }
+}
+
+
+
+
+
+/**********************************************************************
+ * PE_LoadImage
+ * Load one PE format DLL/EXE into memory
+ *
+ * Unluckily we can't just mmap the sections where we want them, for
+ * (at least) Linux does only support offsets which are page-aligned.
+ *
+ * BUT we have to map the whole image anyway, for Win32 programs sometimes
+ * want to access them. (HMODULE32 point to the start of it)
+ */
+HMODULE PE_LoadImage( int handle, LPCSTR filename, WORD *version )
+{
+ HMODULE hModule;
+ HANDLE mapping;
+
+ IMAGE_NT_HEADERS *nt;
+ IMAGE_SECTION_HEADER *pe_sec;
+ IMAGE_DATA_DIRECTORY *dir;
+ BY_HANDLE_FILE_INFORMATION bhfi;
+ int i, rawsize, lowest_va, vma_size, file_size = 0;
+ DWORD load_addr = 0, aoep, reloc = 0;
+// struct get_read_fd_request *req = get_req_buffer();
+ int unix_handle = handle;
+ int page_size = getpagesize();
+
+
+// if ( GetFileInformationByHandle( hFile, &bhfi ) )
+// file_size = bhfi.nFileSizeLow;
+ file_size=lseek(handle, 0, SEEK_END);
+ lseek(handle, 0, SEEK_SET);
+
+//#warning fix CreateFileMappingA
+ mapping = CreateFileMappingA( handle, NULL, PAGE_READONLY | SEC_COMMIT,
+ 0, 0, NULL );
+ if (!mapping)
+ {
+ WARN("CreateFileMapping error %ld\n", GetLastError() );
+ return 0;
+ }
+// hModule = (HMODULE)MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 );
+ hModule=(HMODULE)mapping;
+// CloseHandle( mapping );
+ if (!hModule)
+ {
+ WARN("MapViewOfFile error %ld\n", GetLastError() );
+ return 0;
+ }
+ if ( *(WORD*)hModule !=IMAGE_DOS_SIGNATURE)
+ {
+ WARN("%s image doesn't have DOS signature, but 0x%04x\n", filename,*(WORD*)hModule);
+ goto error;
+ }
+
+ nt = PE_HEADER( hModule );
+
+
+ if ( nt->Signature != IMAGE_NT_SIGNATURE )
+ {
+ WARN("%s image doesn't have PE signature, but 0x%08lx\n", filename, nt->Signature );
+ goto error;
+ }
+
+
+ if ( nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 )
+ {
+ MESSAGE("Trying to load PE image for unsupported architecture (");
+ switch (nt->FileHeader.Machine)
+ {
+ case IMAGE_FILE_MACHINE_UNKNOWN: MESSAGE("Unknown"); break;
+ case IMAGE_FILE_MACHINE_I860: MESSAGE("I860"); break;
+ case IMAGE_FILE_MACHINE_R3000: MESSAGE("R3000"); break;
+ case IMAGE_FILE_MACHINE_R4000: MESSAGE("R4000"); break;
+ case IMAGE_FILE_MACHINE_R10000: MESSAGE("R10000"); break;
+ case IMAGE_FILE_MACHINE_ALPHA: MESSAGE("Alpha"); break;
+ case IMAGE_FILE_MACHINE_POWERPC: MESSAGE("PowerPC"); break;
+ default: MESSAGE("Unknown-%04x", nt->FileHeader.Machine); break;
+ }
+ MESSAGE(")\n");
+ goto error;
+ }
+
+
+ pe_sec = PE_SECTIONS( hModule );
+ rawsize = 0; lowest_va = 0x10000;
+ for (i = 0; i < nt->FileHeader.NumberOfSections; i++)
+ {
+ if (lowest_va > pe_sec[i].VirtualAddress)
+ lowest_va = pe_sec[i].VirtualAddress;
+ if (pe_sec[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
+ continue;
+ if (pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData > rawsize)
+ rawsize = pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData;
+ }
+
+
+ if ( file_size && file_size < rawsize )
+ {
+ ERR("PE module is too small (header: %d, filesize: %d), "
+ "probably truncated download?\n",
+ rawsize, file_size );
+ goto error;
+ }
+
+
+ aoep = nt->OptionalHeader.AddressOfEntryPoint;
+ if (aoep && (aoep < lowest_va))
+ FIXME("VIRUS WARNING: '%s' has an invalid entrypoint (0x%08lx) "
+ "below the first virtual address (0x%08x) "
+ "(possibly infected by Tchernobyl/SpaceFiller virus)!\n",
+ filename, aoep, lowest_va );
+
+
+ /* FIXME: Hack! While we don't really support shared sections yet,
+ * this checks for those special cases where the whole DLL
+ * consists only of shared sections and is mapped into the
+ * shared address space > 2GB. In this case, we assume that
+ * the module got mapped at its base address. Thus we simply
+ * check whether the module has actually been mapped there
+ * and use it, if so. This is needed to get Win95 USER32.DLL
+ * to work (until we support shared sections properly).
+ */
+
+ if ( nt->OptionalHeader.ImageBase & 0x80000000 )
+ {
+ HMODULE sharedMod = (HMODULE)nt->OptionalHeader.ImageBase;
+ IMAGE_NT_HEADERS *sharedNt = (PIMAGE_NT_HEADERS)
+ ( (LPBYTE)sharedMod + ((LPBYTE)nt - (LPBYTE)hModule) );
+
+ /* Well, this check is not really comprehensive,
+ but should be good enough for now ... */
+ if ( !IsBadReadPtr( (LPBYTE)sharedMod, sizeof(IMAGE_DOS_HEADER) )
+ && memcmp( (LPBYTE)sharedMod, (LPBYTE)hModule, sizeof(IMAGE_DOS_HEADER) ) == 0
+ && !IsBadReadPtr( sharedNt, sizeof(IMAGE_NT_HEADERS) )
+ && memcmp( sharedNt, nt, sizeof(IMAGE_NT_HEADERS) ) == 0 )
+ {
+ UnmapViewOfFile( (LPVOID)hModule );
+ return sharedMod;
+ }
+ }
+
+
+
+ load_addr = nt->OptionalHeader.ImageBase;
+ vma_size = calc_vma_size( hModule );
+
+ load_addr = (DWORD)VirtualAlloc( (void*)load_addr, vma_size,
+ MEM_RESERVE | MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE );
+ if (load_addr == 0)
+ {
+
+ FIXME("We need to perform base relocations for %s\n", filename);
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BASERELOC;
+ if (dir->Size)
+ reloc = dir->VirtualAddress;
+ else
+ {
+ FIXME( "FATAL: Need to relocate %s, but no relocation records present (%s). Try to run that file directly !\n",
+ filename,
+ (nt->FileHeader.Characteristics&IMAGE_FILE_RELOCS_STRIPPED)?
+ "stripped during link" : "unknown reason" );
+ goto error;
+ }
+
+ /* FIXME: If we need to relocate a system DLL (base > 2GB) we should
+ * really make sure that the *new* base address is also > 2GB.
+ * Some DLLs really check the MSB of the module handle :-/
+ */
+ if ( nt->OptionalHeader.ImageBase & 0x80000000 )
+ ERR( "Forced to relocate system DLL (base > 2GB). This is not good.\n" );
+
+ load_addr = (DWORD)VirtualAlloc( NULL, vma_size,
+ MEM_RESERVE | MEM_COMMIT,
+ PAGE_EXECUTE_READWRITE );
+ if (!load_addr) {
+ FIXME_(win32)(
+ "FATAL: Couldn't load module %s (out of memory, %d needed)!\n", filename, vma_size);
+ goto error;
+ }
+ }
+
+ TRACE("Load addr is %lx (base %lx), range %x\n",
+ load_addr, nt->OptionalHeader.ImageBase, vma_size );
+ TRACE_(segment)("Loading %s at %lx, range %x\n",
+ filename, load_addr, vma_size );
+
+#if 0
+
+ *(PIMAGE_DOS_HEADER)load_addr = *(PIMAGE_DOS_HEADER)hModule;
+ *PE_HEADER( load_addr ) = *nt;
+ memcpy( PE_SECTIONS(load_addr), PE_SECTIONS(hModule),
+ sizeof(IMAGE_SECTION_HEADER) * nt->FileHeader.NumberOfSections );
+
+
+ memcpy( load_addr, hModule, lowest_fa );
+#endif
+
+ if ((void*)FILE_dommap( handle, (void *)load_addr, 0, nt->OptionalHeader.SizeOfHeaders,
+ 0, 0, PROT_EXEC | PROT_WRITE | PROT_READ,
+ MAP_PRIVATE | MAP_FIXED ) != (void*)load_addr)
+ {
+ ERR_(win32)( "Critical Error: failed to map PE header to necessary address.\n");
+ goto error;
+ }
+
+
+ pe_sec = PE_SECTIONS( hModule );
+ for (i = 0; i < nt->FileHeader.NumberOfSections; i++, pe_sec++)
+ {
+ if (!pe_sec->SizeOfRawData || !pe_sec->PointerToRawData) continue;
+ TRACE("%s: mmaping section %s at %p off %lx size %lx/%lx\n",
+ filename, pe_sec->Name, (void*)RVA(pe_sec->VirtualAddress),
+ pe_sec->PointerToRawData, pe_sec->SizeOfRawData, pe_sec->Misc.VirtualSize );
+ if ((void*)FILE_dommap( unix_handle, (void*)RVA(pe_sec->VirtualAddress),
+ 0, pe_sec->SizeOfRawData, 0, pe_sec->PointerToRawData,
+ PROT_EXEC | PROT_WRITE | PROT_READ,
+ MAP_PRIVATE | MAP_FIXED ) != (void*)RVA(pe_sec->VirtualAddress))
+ {
+
+ ERR_(win32)( "Critical Error: failed to map PE section to necessary address.\n");
+ goto error;
+ }
+ if ((pe_sec->SizeOfRawData < pe_sec->Misc.VirtualSize) &&
+ (pe_sec->SizeOfRawData & (page_size-1)))
+ {
+ DWORD end = (pe_sec->SizeOfRawData & ~(page_size-1)) + page_size;
+ if (end > pe_sec->Misc.VirtualSize) end = pe_sec->Misc.VirtualSize;
+ TRACE("clearing %p - %p\n",
+ RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData,
+ RVA(pe_sec->VirtualAddress) + end );
+ memset( (char*)RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, 0,
+ end - pe_sec->SizeOfRawData );
+ }
+ }
+
+
+ if ( reloc )
+ do_relocations( load_addr, (IMAGE_BASE_RELOCATION *)RVA(reloc) );
+
+
+ *version = ( (nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 )
+ | (nt->OptionalHeader.MinorSubsystemVersion & 0xff);
+
+
+ UnmapViewOfFile( (LPVOID)hModule );
+ return (HMODULE)load_addr;
+
+error:
+ if (unix_handle != -1) close( unix_handle );
+ if (load_addr) VirtualFree( (LPVOID)load_addr, 0, MEM_RELEASE );
+ UnmapViewOfFile( (LPVOID)hModule );
+ return 0;
+}
+
+/**********************************************************************
+ * PE_CreateModule
+ *
+ * Create WINE_MODREF structure for loaded HMODULE32, link it into
+ * process modref_list, and fixup all imports.
+ *
+ * Note: hModule must point to a correctly allocated PE image,
+ * with base relocations applied; the 16-bit dummy module
+ * associated to hModule must already exist.
+ *
+ * Note: This routine must always be called in the context of the
+ * process that is to own the module to be created.
+ */
+WINE_MODREF *PE_CreateModule( HMODULE hModule,
+ LPCSTR filename, DWORD flags, WIN_BOOL builtin )
+{
+ DWORD load_addr = (DWORD)hModule;
+ IMAGE_NT_HEADERS *nt = PE_HEADER(hModule);
+ IMAGE_DATA_DIRECTORY *dir;
+ IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL;
+ IMAGE_EXPORT_DIRECTORY *pe_export = NULL;
+ IMAGE_RESOURCE_DIRECTORY *pe_resource = NULL;
+ WINE_MODREF *wm;
+ int result;
+
+
+
+
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT;
+ if (dir->Size)
+ pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(dir->VirtualAddress);
+
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT;
+ if (dir->Size)
+ pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(dir->VirtualAddress);
+
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE;
+ if (dir->Size)
+ pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(dir->VirtualAddress);
+
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXCEPTION;
+ if (dir->Size) FIXME("Exception directory ignored\n" );
+
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_SECURITY;
+ if (dir->Size) FIXME("Security directory ignored\n" );
+
+
+
+
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DEBUG;
+ if (dir->Size) TRACE("Debug directory ignored\n" );
+
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COPYRIGHT;
+ if (dir->Size) FIXME("Copyright string ignored\n" );
+
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_GLOBALPTR;
+ if (dir->Size) FIXME("Global Pointer (MIPS) ignored\n" );
+
+
+
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG;
+ if (dir->Size) FIXME("Load Configuration directory ignored\n" );
+
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT;
+ if (dir->Size) TRACE("Bound Import directory ignored\n" );
+
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IAT;
+ if (dir->Size) TRACE("Import Address Table directory ignored\n" );
+
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT;
+ if (dir->Size)
+ {
+ TRACE("Delayed import, stub calls LoadLibrary\n" );
+ /*
+ * Nothing to do here.
+ */
+
+#ifdef ImgDelayDescr
+ /*
+ * This code is useful to observe what the heck is going on.
+ */
+ {
+ ImgDelayDescr *pe_delay = NULL;
+ pe_delay = (PImgDelayDescr)RVA(dir->VirtualAddress);
+ TRACE_(delayhlp)("pe_delay->grAttrs = %08x\n", pe_delay->grAttrs);
+ TRACE_(delayhlp)("pe_delay->szName = %s\n", pe_delay->szName);
+ TRACE_(delayhlp)("pe_delay->phmod = %08x\n", pe_delay->phmod);
+ TRACE_(delayhlp)("pe_delay->pIAT = %08x\n", pe_delay->pIAT);
+ TRACE_(delayhlp)("pe_delay->pINT = %08x\n", pe_delay->pINT);
+ TRACE_(delayhlp)("pe_delay->pBoundIAT = %08x\n", pe_delay->pBoundIAT);
+ TRACE_(delayhlp)("pe_delay->pUnloadIAT = %08x\n", pe_delay->pUnloadIAT);
+ TRACE_(delayhlp)("pe_delay->dwTimeStamp = %08x\n", pe_delay->dwTimeStamp);
+ }
+#endif
+ }
+
+ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR;
+ if (dir->Size) FIXME("Unknown directory 14 ignored\n" );
+
+ dir = nt->OptionalHeader.DataDirectory+15;
+ if (dir->Size) FIXME("Unknown directory 15 ignored\n" );
+
+
+
+
+ wm = (WINE_MODREF *)HeapAlloc( GetProcessHeap(),
+ HEAP_ZERO_MEMORY, sizeof(*wm) );
+ wm->module = hModule;
+
+ if ( builtin )
+ wm->flags |= WINE_MODREF_INTERNAL;
+ if ( flags & DONT_RESOLVE_DLL_REFERENCES )
+ wm->flags |= WINE_MODREF_DONT_RESOLVE_REFS;
+ if ( flags & LOAD_LIBRARY_AS_DATAFILE )
+ wm->flags |= WINE_MODREF_LOAD_AS_DATAFILE;
+
+ wm->type = MODULE32_PE;
+ wm->binfmt.pe.pe_export = pe_export;
+ wm->binfmt.pe.pe_import = pe_import;
+ wm->binfmt.pe.pe_resource = pe_resource;
+ wm->binfmt.pe.tlsindex = -1;
+
+ wm->filename = malloc(strlen(filename)+1);
+ strcpy(wm->filename, filename );
+ wm->modname = strrchr( wm->filename, '\\' );
+ if (!wm->modname) wm->modname = wm->filename;
+ else wm->modname++;
+
+ if ( pe_export )
+ dump_exports( hModule );
+
+ /* Fixup Imports */
+
+ if ( pe_import
+ && !( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE )
+ && !( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS )
+ && fixup_imports( wm ) )
+ {
+ /* remove entry from modref chain */
+ return NULL;
+ }
+
+ return wm;
+
+ return wm;
+}
+
+/******************************************************************************
+ * The PE Library Loader frontend.
+ * FIXME: handle the flags.
+ */
+WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags)
+{
+ HMODULE hModule32;
+ WINE_MODREF *wm;
+ char filename[256];
+ int hFile;
+ WORD version = 0;
+
+
+ strncpy(filename, name, sizeof(filename));
+ hFile=open(filename, O_RDONLY);
+ if(hFile==-1)
+ return NULL;
+
+
+ hModule32 = PE_LoadImage( hFile, filename, &version );
+ if (!hModule32)
+ {
+ SetLastError( ERROR_OUTOFMEMORY );
+ return NULL;
+ }
+
+ if ( !(wm = PE_CreateModule( hModule32, filename, flags, FALSE )) )
+ {
+ ERR( "can't load %s\n", filename );
+ SetLastError( ERROR_OUTOFMEMORY );
+ return NULL;
+ }
+ close(hFile);
+ return wm;
+}
+
+
+/*****************************************************************************
+ * PE_UnloadLibrary
+ *
+ * Unload the library unmapping the image and freeing the modref structure.
+ */
+void PE_UnloadLibrary(WINE_MODREF *wm)
+{
+ TRACE(" unloading %s\n", wm->filename);
+
+ HeapFree( GetProcessHeap(), 0, wm->filename );
+ HeapFree( GetProcessHeap(), 0, wm->short_filename );
+ HeapFree( GetProcessHeap(), 0, wm );
+}
+
+/*****************************************************************************
+ * Load the PE main .EXE. All other loading is done by PE_LoadLibraryExA
+ * FIXME: this function should use PE_LoadLibraryExA, but currently can't
+ * due to the PROCESS_Create stuff.
+ */
+
+/* Called if the library is loaded or freed.
+ * NOTE: if a thread attaches a DLL, the current thread will only do
+ * DLL_PROCESS_ATTACH. Only new created threads do DLL_THREAD_ATTACH
+ * (SDK)
+ */
+WIN_BOOL PE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved )
+{
+ WIN_BOOL retv = TRUE;
+ assert( wm->type == MODULE32_PE );
+
+
+ if ((PE_HEADER(wm->module)->FileHeader.Characteristics & IMAGE_FILE_DLL) &&
+ (PE_HEADER(wm->module)->OptionalHeader.AddressOfEntryPoint)
+ ) {
+ DLLENTRYPROC entry ;
+ entry = (void*)PE_FindExportedFunction(wm, "DllMain", 0);
+ if(entry==NULL)
+ entry = (void*)RVA_PTR( wm->module,OptionalHeader.AddressOfEntryPoint );
+
+ TRACE_(relay)("CallTo32(entryproc=%p,module=%08x,type=%ld,res=%p)\n",
+ entry, wm->module, type, lpReserved );
+ printf("Entering DllMain(");
+ switch(type)
+ {
+ case DLL_PROCESS_DETACH:
+ printf("DLL_PROCESS_DETACH) ");
+ break;
+ case DLL_PROCESS_ATTACH:
+ printf("DLL_PROCESS_ATTACH) ");
+ break;
+ case DLL_THREAD_DETACH:
+ printf("DLL_THREAD_DETACH) ");
+ break;
+ case DLL_THREAD_ATTACH:
+ printf("DLL_THREAD_ATTACH) ");
+ break;
+ }
+ printf("for %s\n", wm->filename);
+ retv = entry( wm->module, type, lpReserved );
+ }
+
+ return retv;
+}
+
+static LPVOID
+_fixup_address(PIMAGE_OPTIONAL_HEADER opt,int delta,LPVOID addr) {
+ if ( ((DWORD)addr>opt->ImageBase) &&
+ ((DWORD)addr<opt->ImageBase+opt->SizeOfImage)
+ )
+
+ return (LPVOID)(((DWORD)addr)+delta);
+ else
+
+ return addr;
+}
diff --git a/src/libw32dll/pe_resource.c b/src/libw32dll/pe_resource.c
new file mode 100644
index 000000000..86c342ef7
--- /dev/null
+++ b/src/libw32dll/pe_resource.c
@@ -0,0 +1,391 @@
+/*
+ * PE (Portable Execute) File Resources
+ *
+ * Copyright 1995 Thomas Sandford
+ * Copyright 1996 Martin von Loewis
+ *
+ * Based on the Win16 resource handling code in loader/resource.c
+ * Copyright 1993 Robert J. Amstadt
+ * Copyright 1995 Alexandre Julliard
+ * Copyright 1997 Marcus Meissner
+ */
+#include "config.h"
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include "wine/winestring.h"
+#include "wine/windef.h"
+#include "wine/pe_image.h"
+#include "wine/module.h"
+#include "wine/heap.h"
+//#include "task.h"
+//#include "process.h"
+//#include "stackframe.h"
+#include "wine/debugtools.h"
+
+/**********************************************************************
+ * HMODULE32toPE_MODREF
+ *
+ * small helper function to get a PE_MODREF from a passed HMODULE32
+ */
+static PE_MODREF*
+HMODULE32toPE_MODREF(HMODULE hmod) {
+ WINE_MODREF *wm;
+
+ wm = MODULE32_LookupHMODULE( hmod );
+ if (!wm || wm->type!=MODULE32_PE)
+ return NULL;
+ return &(wm->binfmt.pe);
+}
+
+/**********************************************************************
+ * GetResDirEntryW
+ *
+ * Helper function - goes down one level of PE resource tree
+ *
+ */
+PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr,
+ LPCWSTR name,DWORD root,
+ WIN_BOOL allowdefault)
+{
+ int entrynum;
+ PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable;
+ int namelen;
+
+ if (HIWORD(name)) {
+ if (name[0]=='#') {
+ char buf[10];
+
+ lstrcpynWtoA(buf,name+1,10);
+ return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault);
+ }
+ entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
+ (BYTE *) resdirptr +
+ sizeof(IMAGE_RESOURCE_DIRECTORY));
+ namelen = lstrlenW(name);
+ for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++)
+ {
+ PIMAGE_RESOURCE_DIR_STRING_U str =
+ (PIMAGE_RESOURCE_DIR_STRING_U) (root +
+ entryTable[entrynum].u1.s.NameOffset);
+ if(namelen != str->Length)
+ continue;
+ if(wcsnicmp(name,str->NameString,str->Length)==0)
+ return (PIMAGE_RESOURCE_DIRECTORY) (
+ root +
+ entryTable[entrynum].u2.s.OffsetToDirectory);
+ }
+ return NULL;
+ } else {
+ entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) (
+ (BYTE *) resdirptr +
+ sizeof(IMAGE_RESOURCE_DIRECTORY) +
+ resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY));
+ for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++)
+ if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name)
+ return (PIMAGE_RESOURCE_DIRECTORY) (
+ root +
+ entryTable[entrynum].u2.s.OffsetToDirectory);
+ /* just use first entry if no default can be found */
+ if (allowdefault && !name && resdirptr->NumberOfIdEntries)
+ return (PIMAGE_RESOURCE_DIRECTORY) (
+ root +
+ entryTable[0].u2.s.OffsetToDirectory);
+ return NULL;
+ }
+}
+
+/**********************************************************************
+ * GetResDirEntryA
+ */
+PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr,
+ LPCSTR name, DWORD root,
+ WIN_BOOL allowdefault )
+{
+ PIMAGE_RESOURCE_DIRECTORY retv;
+ LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name )
+ : (LPWSTR)name;
+
+ retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault );
+
+ if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW );
+
+ return retv;
+}
+
+/**********************************************************************
+ * PE_FindResourceEx32W
+ */
+HANDLE PE_FindResourceExW(
+ WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang
+) {
+ PIMAGE_RESOURCE_DIRECTORY resdirptr;
+ DWORD root;
+ HANDLE result;
+ PE_MODREF *pem = &(wm->binfmt.pe);
+
+ if (!pem || !pem->pe_resource)
+ return 0;
+
+ resdirptr = pem->pe_resource;
+ root = (DWORD) resdirptr;
+ if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL)
+ return 0;
+ if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL)
+ return 0;
+ result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE);
+ /* Try LANG_NEUTRAL, too */
+ if(!result)
+ return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE);
+ return result;
+}
+
+
+/**********************************************************************
+ * PE_LoadResource32
+ */
+HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc )
+{
+ if (!hRsrc || !wm || wm->type!=MODULE32_PE)
+ return 0;
+ return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData);
+}
+
+
+/**********************************************************************
+ * PE_SizeofResource32
+ */
+DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc )
+{
+ /* we don't need hModule */
+ if (!hRsrc)
+ return 0;
+ return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size;
+}
+
+/**********************************************************************
+ * PE_EnumResourceTypes32A
+ */
+WIN_BOOL
+PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) {
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
+ int i;
+ PIMAGE_RESOURCE_DIRECTORY resdir;
+ PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
+ WIN_BOOL ret;
+ HANDLE heap = GetProcessHeap();
+
+ if (!pem || !pem->pe_resource)
+ return FALSE;
+
+ resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
+ et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+ ret = FALSE;
+ for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+ LPSTR name;
+
+ if (et[i].u1.s.NameIsString)
+ name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
+ else
+ name = (LPSTR)(int)et[i].u1.Id;
+ ret = lpfun(hmod,name,lparam);
+ if (HIWORD(name))
+ HeapFree(heap,0,name);
+ if (!ret)
+ break;
+ }
+ return ret;
+}
+
+/**********************************************************************
+ * PE_EnumResourceTypes32W
+ */
+WIN_BOOL
+PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) {
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
+ int i;
+ PIMAGE_RESOURCE_DIRECTORY resdir;
+ PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
+ WIN_BOOL ret;
+
+ if (!pem || !pem->pe_resource)
+ return FALSE;
+
+ resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
+ et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+ ret = FALSE;
+ for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+ LPWSTR type;
+ if (et[i].u1.s.NameIsString)
+ type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
+ else
+ type = (LPWSTR)(int)et[i].u1.Id;
+
+ ret = lpfun(hmod,type,lparam);
+ if (!ret)
+ break;
+ }
+ return ret;
+}
+
+/**********************************************************************
+ * PE_EnumResourceNames32A
+ */
+WIN_BOOL
+PE_EnumResourceNamesA(
+ HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam
+) {
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
+ int i;
+ PIMAGE_RESOURCE_DIRECTORY resdir;
+ PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
+ WIN_BOOL ret;
+ HANDLE heap = GetProcessHeap();
+ LPWSTR typeW;
+
+ if (!pem || !pem->pe_resource)
+ return FALSE;
+ resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
+ if (HIWORD(type))
+ typeW = HEAP_strdupAtoW(heap,0,type);
+ else
+ typeW = (LPWSTR)type;
+ resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
+ if (HIWORD(typeW))
+ HeapFree(heap,0,typeW);
+ if (!resdir)
+ return FALSE;
+ et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+ ret = FALSE;
+ for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+ LPSTR name;
+
+ if (et[i].u1.s.NameIsString)
+ name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset));
+ else
+ name = (LPSTR)(int)et[i].u1.Id;
+ ret = lpfun(hmod,type,name,lparam);
+ if (HIWORD(name)) HeapFree(heap,0,name);
+ if (!ret)
+ break;
+ }
+ return ret;
+}
+
+/**********************************************************************
+ * PE_EnumResourceNames32W
+ */
+WIN_BOOL
+PE_EnumResourceNamesW(
+ HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam
+) {
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
+ int i;
+ PIMAGE_RESOURCE_DIRECTORY resdir;
+ PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
+ WIN_BOOL ret;
+
+ if (!pem || !pem->pe_resource)
+ return FALSE;
+
+ resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
+ resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
+ if (!resdir)
+ return FALSE;
+ et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+ ret = FALSE;
+ for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+ LPWSTR name;
+ if (et[i].u1.s.NameIsString)
+ name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset);
+ else
+ name = (LPWSTR)(int)et[i].u1.Id;
+ ret = lpfun(hmod,type,name,lparam);
+ if (!ret)
+ break;
+ }
+ return ret;
+}
+
+/**********************************************************************
+ * PE_EnumResourceNames32A
+ */
+WIN_BOOL
+PE_EnumResourceLanguagesA(
+ HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun,
+ LONG lparam
+) {
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
+ int i;
+ PIMAGE_RESOURCE_DIRECTORY resdir;
+ PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
+ WIN_BOOL ret;
+ HANDLE heap = GetProcessHeap();
+ LPWSTR nameW,typeW;
+
+ if (!pem || !pem->pe_resource)
+ return FALSE;
+
+ resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
+ if (HIWORD(name))
+ nameW = HEAP_strdupAtoW(heap,0,name);
+ else
+ nameW = (LPWSTR)name;
+ resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE);
+ if (HIWORD(nameW))
+ HeapFree(heap,0,nameW);
+ if (!resdir)
+ return FALSE;
+ if (HIWORD(type))
+ typeW = HEAP_strdupAtoW(heap,0,type);
+ else
+ typeW = (LPWSTR)type;
+ resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE);
+ if (HIWORD(typeW))
+ HeapFree(heap,0,typeW);
+ if (!resdir)
+ return FALSE;
+ et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+ ret = FALSE;
+ for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+ /* languages are just ids... I hopem */
+ ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
+ if (!ret)
+ break;
+ }
+ return ret;
+}
+
+/**********************************************************************
+ * PE_EnumResourceLanguages32W
+ */
+WIN_BOOL
+PE_EnumResourceLanguagesW(
+ HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun,
+ LONG lparam
+) {
+ PE_MODREF *pem = HMODULE32toPE_MODREF(hmod);
+ int i;
+ PIMAGE_RESOURCE_DIRECTORY resdir;
+ PIMAGE_RESOURCE_DIRECTORY_ENTRY et;
+ WIN_BOOL ret;
+
+ if (!pem || !pem->pe_resource)
+ return FALSE;
+
+ resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource;
+ resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE);
+ if (!resdir)
+ return FALSE;
+ resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE);
+ if (!resdir)
+ return FALSE;
+ et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY));
+ ret = FALSE;
+ for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) {
+ ret = lpfun(hmod,name,type,et[i].u1.Id,lparam);
+ if (!ret)
+ break;
+ }
+ return ret;
+}
diff --git a/src/libw32dll/registry.c b/src/libw32dll/registry.c
new file mode 100644
index 000000000..1a45b2068
--- /dev/null
+++ b/src/libw32dll/registry.c
@@ -0,0 +1,421 @@
+#include "config.h"
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <pwd.h>
+#include <sys/types.h>
+
+#include "wine/winbase.h"
+#include "wine/winreg.h"
+#include "wine/winnt.h"
+#include "wine/winerror.h"
+#include "wine/debugtools.h"
+
+#include "registry.h"
+
+struct reg_value
+{
+ int type;
+ char* name;
+ int len;
+ char* value;
+};
+
+static int reg_size=0;
+
+static struct reg_value* regs=0;
+
+struct reg_handle_s;
+typedef struct reg_handle_s
+{
+ int handle;
+ char* name;
+ struct reg_handle_s* next;
+ struct reg_handle_s* prev;
+} reg_handle_t;
+
+static reg_handle_t* head=0;
+
+#define DIR -25
+
+static void create_registry();
+static void open_registry();
+static void save_registry();
+
+
+
+
+static void create_registry(){
+ if(regs)
+ {
+ printf("Logic error: create_registry() called with existing registry\n");
+ save_registry();
+ return;
+ }
+ regs=(struct reg_value*)malloc(3*sizeof(struct reg_value));
+ regs[0].type=regs[1].type=DIR;
+ regs[0].name=(char*)malloc(5);
+ strcpy(regs[0].name, "HKLM");
+ regs[1].name=(char*)malloc(5);
+ strcpy(regs[1].name, "HKCU");
+ regs[0].value=regs[1].value=NULL;
+ regs[0].len=regs[1].len=0;
+ reg_size=2;
+ save_registry();
+}
+static void open_registry()
+{
+ int fd;
+ int i;
+ int len;
+ struct passwd* pwent;
+ char* pathname;
+ if(regs)
+ {
+ printf("Multiple open_registry(>\n");
+ return;
+ }
+ pwent=getpwuid(getuid());
+ pathname=(char*)malloc(strlen(pwent->pw_dir)+20);
+ strcpy(pathname, pwent->pw_dir);
+ strcat(pathname, "/.registry");
+ fd=open(pathname, O_RDONLY);
+ free(pathname);
+ if(fd==-1)
+ {
+ printf("Creating new registry\n");
+ create_registry();
+ return;
+ }
+ read(fd, &reg_size, 4);
+ regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value));
+ for(i=0; i<reg_size; i++)
+ {
+ read(fd,&regs[i].type,4);
+ read(fd,&len,4);
+ regs[i].name=(char*)malloc(len+1);
+ if(regs[i].name==0)
+ {
+ reg_size=i+1;
+ goto error;
+ }
+ read(fd, regs[i].name, len);
+ regs[i].name[len]=0;
+ read(fd,&regs[i].len,4);
+ regs[i].value=(char*)malloc(regs[i].len+1);
+ if(regs[i].value==0)
+ {
+ free(regs[i].name);
+ reg_size=i+1;
+ goto error;
+ }
+ read(fd, regs[i].value, regs[i].len);
+ regs[i].value[regs[i].len]=0;
+ }
+error:
+ close(fd);
+ return;
+}
+
+static void save_registry()
+{
+ int fd, i, len;
+ struct passwd* pwent;
+ char* pathname;
+ pwent=getpwuid(getuid());
+ pathname=(char*)malloc(strlen(pwent->pw_dir)+20);
+ strcpy(pathname, pwent->pw_dir);
+ strcat(pathname, "/.registry");
+ fd=open(pathname, O_WRONLY | O_CREAT, 00777);
+ free(pathname);
+ if(fd==-1)
+ {
+ printf("Failed to open registry file for writing.\n");
+ return;
+ }
+ write(fd, &reg_size, 4);
+ for(i=0; i<reg_size; i++)
+ {
+ write(fd, &regs[i].type, 4);
+ len=strlen(regs[i].name);
+ write(fd, &len, 4);
+ write(fd, regs[i].name, len);
+ write(fd, &regs[i].len, 4);
+ write(fd, regs[i].value, regs[i].len);
+ }
+ close(fd);
+}
+static reg_handle_t* find_handle_by_name(const char* name)
+{
+ reg_handle_t* t;
+ for(t=head; t; t=t->prev)
+ {
+ if(!strcmp(t->name, name))
+ {
+ return t;
+ }
+ }
+ return 0;
+}
+static struct reg_value* find_value_by_name(const char* name)
+{
+ int i;
+ for(i=0; i<reg_size; i++)
+ if(!strcmp(regs[i].name, name))
+ return regs+i;
+ return 0;
+}
+static reg_handle_t* find_handle(int handle)
+{
+ reg_handle_t* t;
+ for(t=head; t; t=t->prev)
+ {
+ if(t->handle==handle)
+ {
+ return t;
+ }
+ }
+ return 0;
+}
+static int generate_handle()
+{
+ static int zz=249;
+ zz++;
+ while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER))
+ zz++;
+ return zz;
+}
+
+static reg_handle_t* insert_handle(long handle, const char* name)
+{
+ reg_handle_t* t;
+ t=(reg_handle_t*)malloc(sizeof(reg_handle_t));
+ if(head==0)
+ {
+ t->prev=0;
+ }
+ else
+ {
+ head->next=t;
+ t->prev=head;
+ }
+ t->next=0;
+ t->name=(char*)malloc(strlen(name)+1);
+ strcpy(t->name, name);
+ t->handle=handle;
+ head=t;
+ return t;
+}
+static char* build_keyname(long key, const char* subkey)
+{
+ char* full_name;
+ reg_handle_t* t;
+ if((t=find_handle(key))==0)
+ {
+ TRACE("Invalid key\n");
+ return NULL;
+ }
+ if(subkey==NULL)
+ subkey="<default>";
+ full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
+ strcpy(full_name, t->name);
+ strcat(full_name, "\\");
+ strcat(full_name, subkey);
+ return full_name;
+}
+struct reg_value* insert_reg_value(int handle, const char* name, int type, const void* value, int len)
+{
+ /* reg_handle_t* t; */
+ struct reg_value* v;
+ char* fullname;
+ if((fullname=build_keyname(handle, name))==NULL)
+ {
+ TRACE("Invalid handle\n");
+ return NULL;
+ }
+
+ if((v=find_value_by_name(fullname))==0)
+ //creating new value in registry
+ {
+ if(regs==0)
+ create_registry();
+ regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1));
+ v=regs+reg_size;
+ reg_size++;
+ }
+ else
+ //replacing old one
+ {
+ free(v->value);
+ free(v->name);
+ }
+ v->type=type;
+ v->len=len;
+ v->value=(char*)malloc(len);
+ memcpy(v->value, value, len);
+ v->name=(char*)malloc(strlen(fullname)+1);
+ strcpy(v->name, fullname);
+ save_registry();
+ return v;
+}
+
+static void init_registry()
+{
+ printf("Initializing registry\n");
+ open_registry();
+ insert_handle(HKEY_LOCAL_MACHINE, "HKLM");
+ insert_handle(HKEY_CURRENT_USER, "HKCU");
+}
+static reg_handle_t* find_handle_2(long key, const char* subkey)
+{
+ char* full_name;
+ reg_handle_t* t;
+ if((t=find_handle(key))==0)
+ {
+ TRACE("Invalid key\n");
+ return (reg_handle_t*)-1;
+ }
+ if(subkey==NULL)
+ return t;
+ full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
+ strcpy(full_name, t->name);
+ strcat(full_name, "\\");
+ strcat(full_name, subkey);
+ t=find_handle_by_name(full_name);
+ free(full_name);
+ return t;
+}
+
+long RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
+{
+ char* full_name;
+ reg_handle_t* t;
+ struct reg_value* v;
+ TRACE("Opening key %s\n", subkey);
+
+ if(!regs)
+ init_registry()
+;
+/* t=find_handle_2(key, subkey);
+
+ if(t==0)
+ return -1;
+
+ if(t==(reg_handle_t*)-1)
+ return -1;
+
+*/ full_name=build_keyname(key, subkey);
+ if(!full_name)
+ return -1;
+ v=find_value_by_name(full_name);
+
+ t=insert_handle(generate_handle(), full_name);
+ *newkey=t->handle;
+ free(full_name);
+
+ return 0;
+}
+long RegCloseKey(long key)
+{
+ reg_handle_t *handle;
+ if(key==HKEY_LOCAL_MACHINE)
+ return 0;
+ if(key==HKEY_CURRENT_USER)
+ return 0;
+ handle=find_handle(key);
+ if(handle==0)
+ return 0;
+ if(handle->prev)
+ handle->prev->next=handle->next;
+ if(handle->next)
+ handle->next->prev=handle->prev;
+ if(handle->name)
+ free(handle->name);
+ if(handle==head)
+ head=head->prev;
+ free(handle);
+ return 1;
+}
+long RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
+{
+ struct reg_value* t;
+ char* c;
+ TRACE("Querying value %s\n", value);
+ if(!regs)
+ init_registry()
+;
+ c=build_keyname(key, value);
+ if(c==NULL)
+ return 1;
+ if((t=find_value_by_name(c))==0)
+ {
+ free(c);
+ return 2;
+ }
+ free(c);
+ if(type)
+ *type=t->type;
+ if(data)
+ {
+ memcpy(data, t->value, (t->len<*count)?t->len:*count);
+ TRACE("returning %d bytes: %d\n", t->len, *(int*)data);
+ }
+ if(*count<t->len)
+ {
+ *count=t->len;
+ return ERROR_MORE_DATA;
+ }
+ else
+ {
+ *count=t->len;
+ }
+ return 0;
+}
+long RegCreateKeyExA(long key, const char* name, long reserved,
+ void* classs, long options, long security,
+ void* sec_attr, int* newkey, int* status)
+{
+ reg_handle_t* t;
+ char* fullname;
+ struct reg_value* v;
+// TRACE("Creating/Opening key %s\n", name);
+ TRACE("Creating/Opening key %s\n", name);
+ if(!regs)
+ init_registry()
+;
+ fullname=build_keyname(key, name);
+ if(fullname==NULL)
+ return 1;
+ v=find_value_by_name(fullname);
+ if(v==0)
+ {
+ int qw=45708;
+ v=insert_reg_value(key, name, DIR, &qw, 4);
+ *status=REG_CREATED_NEW_KEY;
+// return 0;
+ }
+ else
+ *status=REG_OPENED_EXISTING_KEY;
+
+ t=insert_handle(generate_handle(), fullname);
+ *newkey=t->handle;
+ free(fullname);
+ return 0;
+}
+long RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size)
+{
+ /* struct reg_value* t; */
+ char* c;
+ TRACE("Request to set value %s\n", name);
+ if(!regs)
+ init_registry()
+;
+ c=build_keyname(key, name);
+ if(c==NULL)
+ return 1;
+ insert_reg_value(key, name, v2, data, size);
+ free(c);
+ return 0;
+}
diff --git a/src/libw32dll/registry.h b/src/libw32dll/registry.h
new file mode 100644
index 000000000..2e794799e
--- /dev/null
+++ b/src/libw32dll/registry.h
@@ -0,0 +1,24 @@
+/********************************************************
+
+ Declaration of registry access functions
+ Copyright 2000 Eugene Smith (divx@euro.ru)
+
+*********************************************************/
+
+
+#ifndef REGISTRY_H
+#define REGISTRY_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+long RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey);
+long RegCloseKey(long key);
+long RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count);
+long RegCreateKeyExA(long key, const char* name, long reserved,
+ void* classs, long options, long security,
+ void* sec_attr, int* newkey, int* status);
+long RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size);
+#ifdef __cplusplus
+};
+#endif
+#endif
diff --git a/src/libw32dll/resource.c b/src/libw32dll/resource.c
new file mode 100644
index 000000000..67d398243
--- /dev/null
+++ b/src/libw32dll/resource.c
@@ -0,0 +1,479 @@
+/*
+ * Resources
+ *
+ * Copyright 1993 Robert J. Amstadt
+ * Copyright 1995 Alexandre Julliard
+ */
+#include "config.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "wine/winbase.h"
+#include "wine/windef.h"
+#include "wine/winuser.h"
+#include "wine/heap.h"
+#include "wine/module.h"
+#include "wine/debugtools.h"
+#include "wine/winerror.h"
+#define CP_ACP 0
+
+WORD WINE_LanguageId=0x409;//english
+
+#define HRSRC_MAP_BLOCKSIZE 16
+
+typedef struct _HRSRC_ELEM
+{
+ HANDLE hRsrc;
+ WORD type;
+} HRSRC_ELEM;
+
+typedef struct _HRSRC_MAP
+{
+ int nAlloc;
+ int nUsed;
+ HRSRC_ELEM *elem;
+} HRSRC_MAP;
+
+static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type,
+ LPCSTR name, WORD lang, int unicode)
+{
+ HRSRC hRsrc = 0;
+ LPWSTR typeStr, nameStr;
+ WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
+
+ if(!wm)
+ return 0;
+ /* 32-bit PE module */
+
+
+ if ( HIWORD( type ) && (!unicode))
+ typeStr = HEAP_strdupAtoW( GetProcessHeap(), 0, type );
+ else
+ typeStr = (LPWSTR)type;
+ if ( HIWORD( name ) && (!unicode))
+ nameStr = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
+ else
+ nameStr = (LPWSTR)name;
+
+ hRsrc = PE_FindResourceExW( wm, nameStr, typeStr, lang );
+
+ if ( HIWORD( type ) && (!unicode))
+ HeapFree( GetProcessHeap(), 0, typeStr );
+ if ( HIWORD( name ) && (!unicode))
+ HeapFree( GetProcessHeap(), 0, nameStr );
+
+ return hRsrc;
+}
+
+/**********************************************************************
+ * RES_FindResource
+ */
+
+static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type,
+ LPCSTR name, WORD lang, int unicode )
+{
+ HRSRC hRsrc;
+// __TRY
+// {
+ hRsrc = RES_FindResource2(hModule, type, name, lang, unicode);
+// }
+// __EXCEPT(page_fault)
+// {
+// WARN("page fault\n");
+// SetLastError(ERROR_INVALID_PARAMETER);
+// return 0;
+// }
+// __ENDTRY
+ return hRsrc;
+}
+
+/**********************************************************************
+ * RES_SizeofResource
+ */
+static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc)
+{
+ DWORD size = 0;
+ /* HRSRC hRsrc32; */
+
+// HMODULE16 hMod16 = MapHModuleLS( hModule );
+// NE_MODULE *pModule = NE_GetPtr( hMod16 );
+// WINE_MODREF *wm = pModule && pModule->module32?
+// MODULE32_LookupHMODULE( pModule->module32 ) : NULL;
+ WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
+
+ if ( !hModule || !hRsrc ) return 0;
+
+ /* 32-bit PE module */
+ /* If we got a 16-bit hRsrc, convert it */
+// hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
+ if(!HIWORD(hRsrc))
+ {
+ printf("16-bit hRsrcs not supported\n");
+ return 0;
+ }
+ size = PE_SizeofResource( hModule, hRsrc );
+ return size;
+}
+
+/**********************************************************************
+ * RES_AccessResource
+ */
+static HFILE RES_AccessResource( HMODULE hModule, HRSRC hRsrc )
+{
+ HFILE hFile = HFILE_ERROR;
+
+ WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
+
+ if ( !hModule || !hRsrc ) return HFILE_ERROR;
+
+ /* 32-bit PE module */
+ FIXME("32-bit modules not yet supported.\n" );
+ hFile = HFILE_ERROR;
+
+ return hFile;
+}
+
+/**********************************************************************
+ * RES_LoadResource
+ */
+static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc)
+{
+ HGLOBAL hMem = 0;
+ /* HRSRC hRsrc32; */
+ WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule );
+
+
+ if ( !hModule || !hRsrc ) return 0;
+
+ /* 32-bit PE module */
+
+ /* If we got a 16-bit hRsrc, convert it */
+// hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc );
+ if(!HIWORD(hRsrc))
+ {
+ printf("16-bit hRsrcs not supported\n");
+ return 0;
+ }
+ hMem = PE_LoadResource( wm, hRsrc );
+
+ return hMem;
+}
+
+/**********************************************************************
+ * RES_LockResource
+ */
+static LPVOID RES_LockResource( HGLOBAL handle )
+{
+ LPVOID bits = NULL;
+
+ TRACE("(%08x, %s)\n", handle, "PE" );
+
+ bits = (LPVOID)handle;
+
+ return bits;
+}
+
+/**********************************************************************
+ * RES_FreeResource
+ */
+static WIN_BOOL RES_FreeResource( HGLOBAL handle )
+{
+ HGLOBAL retv = handle;
+ return (WIN_BOOL)retv;
+}
+
+/**********************************************************************
+ * FindResourceA (KERNEL32.128)
+ */
+HANDLE WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type )
+{
+ return RES_FindResource( hModule, type, name,
+ WINE_LanguageId, 0);
+}
+HANDLE WINAPI FindResourceW( HMODULE hModule, LPCWSTR name, LPCWSTR type )
+{
+ return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
+ WINE_LanguageId, 1);
+}
+
+/**********************************************************************
+ * FindResourceExA (KERNEL32.129)
+ */
+HANDLE WINAPI FindResourceExA( HMODULE hModule,
+ LPCSTR type, LPCSTR name, WORD lang )
+{
+ return RES_FindResource( hModule, type, name,
+ lang, 0 );
+}
+
+HANDLE WINAPI FindResourceExW( HMODULE hModule,
+ LPCWSTR type, LPCWSTR name, WORD lang )
+{
+ return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name,
+ lang, 1 );
+}
+
+
+
+/**********************************************************************
+ * LockResource (KERNEL32.384)
+ */
+LPVOID WINAPI LockResource( HGLOBAL handle )
+{
+ return RES_LockResource( handle );
+}
+
+
+/**********************************************************************
+ * FreeResource (KERNEL32.145)
+ */
+WIN_BOOL WINAPI FreeResource( HGLOBAL handle )
+{
+ return RES_FreeResource( handle );
+}
+
+
+/**********************************************************************
+ * AccessResource (KERNEL32.64)
+ */
+INT WINAPI AccessResource( HMODULE hModule, HRSRC hRsrc )
+{
+ return RES_AccessResource( hModule, hRsrc );
+}
+/**********************************************************************
+ * SizeofResource (KERNEL32.522)
+ */
+DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc )
+{
+ return RES_SizeofResource( hModule, hRsrc );
+}
+
+
+INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id,
+ LPWSTR buffer, INT buflen );
+
+/**********************************************************************
+ * LoadStringA (USER32.375)
+ */
+INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id,
+ LPSTR buffer, INT buflen )
+{
+ INT retval;
+ INT wbuflen;
+ INT abuflen;
+ LPWSTR wbuf = NULL;
+ LPSTR abuf = NULL;
+
+ if ( buffer != NULL && buflen > 0 )
+ *buffer = 0;
+
+ wbuflen = LoadStringW(instance,resource_id,NULL,0);
+ if ( !wbuflen )
+ return 0;
+ wbuflen ++;
+
+ retval = 0;
+ wbuf = HeapAlloc( GetProcessHeap(), 0, wbuflen * sizeof(WCHAR) );
+ wbuflen = LoadStringW(instance,resource_id,wbuf,wbuflen);
+ if ( wbuflen > 0 )
+ {
+ abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,NULL,0,NULL,NULL);
+ if ( abuflen > 0 )
+ {
+ if ( buffer == NULL || buflen == 0 )
+ retval = abuflen;
+ else
+ {
+ abuf = HeapAlloc( GetProcessHeap(), 0, abuflen * sizeof(CHAR) );
+ abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,abuf,abuflen,NULL,NULL);
+ if ( abuflen > 0 )
+ {
+ abuflen = min(abuflen,buflen - 1);
+ memcpy( buffer, abuf, abuflen );
+ buffer[abuflen] = 0;
+ retval = abuflen;
+ }
+ HeapFree( GetProcessHeap(), 0, abuf );
+ }
+ }
+ }
+ HeapFree( GetProcessHeap(), 0, wbuf );
+
+ return retval;
+}
+
+/**********************************************************************
+ * LoadStringW (USER32.376)
+ */
+INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id,
+ LPWSTR buffer, INT buflen )
+{
+ HGLOBAL hmem;
+ HRSRC hrsrc;
+ WCHAR *p;
+ int string_num;
+ int i;
+
+ if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */
+ resource_id = (UINT)(-((INT)resource_id));
+ TRACE("instance = %04x, id = %04x, buffer = %08x, "
+ "length = %d\n", instance, (int)resource_id, (int) buffer, buflen);
+
+ /* Use bits 4 - 19 (incremented by 1) as resourceid, mask out
+ * 20 - 31. */
+ hrsrc = FindResourceW( instance, (LPCWSTR)(((resource_id>>4)&0xffff)+1),
+ RT_STRINGW );
+ if (!hrsrc) return 0;
+ hmem = LoadResource( instance, hrsrc );
+ if (!hmem) return 0;
+
+ p = LockResource(hmem);
+ string_num = resource_id & 0x000f;
+ for (i = 0; i < string_num; i++)
+ p += *p + 1;
+
+ TRACE("strlen = %d\n", (int)*p );
+
+ if (buffer == NULL) return *p;
+ i = min(buflen - 1, *p);
+ if (i > 0) {
+ memcpy(buffer, p + 1, i * sizeof (WCHAR));
+ buffer[i] = (WCHAR) 0;
+ } else {
+ if (buflen > 1) {
+ buffer[0] = (WCHAR) 0;
+ return 0;
+ }
+#if 0
+ WARN("Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1);
+#endif
+ }
+
+ TRACE("String loaded !\n");
+ return i;
+}
+
+/* Messages...used by FormatMessage32* (KERNEL32.something)
+ *
+ * They can be specified either directly or using a message ID and
+ * loading them from the resource.
+ *
+ * The resourcedata has following format:
+ * start:
+ * 0: DWORD nrofentries
+ * nrofentries * subentry:
+ * 0: DWORD firstentry
+ * 4: DWORD lastentry
+ * 8: DWORD offset from start to the stringentries
+ *
+ * (lastentry-firstentry) * stringentry:
+ * 0: WORD len (0 marks end)
+ * 2: WORD flags
+ * 4: CHAR[len-4]
+ * (stringentry i of a subentry refers to the ID 'firstentry+i')
+ *
+ * Yes, ANSI strings in win32 resources. Go figure.
+ */
+
+/**********************************************************************
+ * LoadMessageA (internal)
+ */
+INT WINAPI LoadMessageA( HMODULE instance, UINT id, WORD lang,
+ LPSTR buffer, INT buflen )
+{
+ HGLOBAL hmem;
+ HRSRC hrsrc;
+ PMESSAGE_RESOURCE_DATA mrd;
+ PMESSAGE_RESOURCE_BLOCK mrb;
+ PMESSAGE_RESOURCE_ENTRY mre;
+ int i,slen;
+
+ TRACE("instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen);
+
+ /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
+ hrsrc = FindResourceExW(instance,RT_MESSAGELISTW,(LPWSTR)1,lang);
+ if (!hrsrc) return 0;
+ hmem = LoadResource( instance, hrsrc );
+ if (!hmem) return 0;
+
+ mrd = (PMESSAGE_RESOURCE_DATA)LockResource(hmem);
+ mre = NULL;
+ mrb = &(mrd->Blocks[0]);
+ for (i=mrd->NumberOfBlocks;i--;) {
+ if ((id>=mrb->LowId) && (id<=mrb->HighId)) {
+ mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mrd)+mrb->OffsetToEntries);
+ id -= mrb->LowId;
+ break;
+ }
+ mrb++;
+ }
+ if (!mre)
+ return 0;
+ for (i=id;i--;) {
+ if (!mre->Length)
+ return 0;
+ mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mre)+(mre->Length));
+ }
+ slen=mre->Length;
+ TRACE(" - strlen=%d\n",slen);
+ i = min(buflen - 1, slen);
+ if (buffer == NULL)
+ return slen;
+ if (i>0) {
+ lstrcpynA(buffer,(char*)mre->Text,i);
+ buffer[i]=0;
+ } else {
+ if (buflen>1) {
+ buffer[0]=0;
+ return 0;
+ }
+ }
+ if (buffer)
+ TRACE("'%s' copied !\n", buffer);
+ return i;
+}
+
+
+
+/**********************************************************************
+ * EnumResourceTypesA (KERNEL32.90)
+ */
+WIN_BOOL WINAPI EnumResourceTypesA( HMODULE hmodule,ENUMRESTYPEPROCA lpfun,
+ LONG lParam)
+{
+ /* FIXME: move WINE_MODREF stuff here */
+ return PE_EnumResourceTypesA(hmodule,lpfun,lParam);
+}
+
+/**********************************************************************
+ * EnumResourceNamesA (KERNEL32.88)
+ */
+WIN_BOOL WINAPI EnumResourceNamesA( HMODULE hmodule, LPCSTR type,
+ ENUMRESNAMEPROCA lpfun, LONG lParam )
+{
+ /* FIXME: move WINE_MODREF stuff here */
+ return PE_EnumResourceNamesA(hmodule,type,lpfun,lParam);
+}
+/**********************************************************************
+ * EnumResourceLanguagesA (KERNEL32.86)
+ */
+WIN_BOOL WINAPI EnumResourceLanguagesA( HMODULE hmodule, LPCSTR type,
+ LPCSTR name, ENUMRESLANGPROCA lpfun,
+ LONG lParam)
+{
+ /* FIXME: move WINE_MODREF stuff here */
+ return PE_EnumResourceLanguagesA(hmodule,type,name,lpfun,lParam);
+}
+/**********************************************************************
+ * LoadResource (KERNEL32.370)
+ */
+HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc )
+{
+ return RES_LoadResource( hModule, hRsrc);
+}
diff --git a/src/libw32dll/stubs.s b/src/libw32dll/stubs.s
new file mode 100644
index 000000000..519eefa58
--- /dev/null
+++ b/src/libw32dll/stubs.s
@@ -0,0 +1,36 @@
+ .file "stubs.c"
+ .version "01.01"
+gcc2_compiled.:
+.section .rodata
+.LC0:
+ .string "Called unk_%s\n"
+.text
+ .align 4
+.globl unk_exp1
+ .type unk_exp1,@function
+unk_exp1:
+ pushl %ebp
+ movl %esp,%ebp
+ subl $4,%esp
+ movl $1,-4(%ebp)
+ movl -4(%ebp),%eax
+ movl %eax,%ecx
+ movl %ecx,%edx
+ sall $4,%edx
+ subl %eax,%edx
+ leal 0(,%edx,2),%eax
+ movl %eax,%edx
+ addl $export_names,%edx
+ pushl %edx
+ pushl $.LC0
+ call printf
+ addl $8,%esp
+ xorl %eax,%eax
+ jmp .L1
+ .align 4
+.L1:
+ leave
+ ret
+.Lfe1:
+ .size unk_exp1,.Lfe1-unk_exp1
+ .ident "GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)"
diff --git a/src/libw32dll/vfl.c b/src/libw32dll/vfl.c
new file mode 100644
index 000000000..b7ce8ecdc
--- /dev/null
+++ b/src/libw32dll/vfl.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright 1998 Marcus Meissner
+ */
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "wine/winbase.h"
+#include "wine/windef.h"
+#include "wine/winuser.h"
+#include "wine/vfw.h"
+#include "wine/winestring.h"
+#include "wine/driver.h"
+#include "wine/avifmt.h"
+
+#define FIXME_(X) printf
+#define FIXME printf
+
+long VFWAPI VideoForWindowsVersion(void);
+
+extern void* my_mreq(int size, int to_zero);
+extern void DrvClose(HDRVR hdrvr);
+extern int my_release(char* memory);
+
+long VFWAPIV ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits);
+
+WIN_BOOL VFWAPI ICInfo(long fccType, long fccHandler, ICINFO * lpicinfo);
+LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo, long cb);
+HIC VFWAPI ICOpen(long fccType, long fccHandler, UINT wMode);
+HIC VFWAPI ICOpenFunction(long fccType, long fccHandler, unsigned int wMode, void* lpfnHandler);
+
+LRESULT VFWAPI ICClose(HIC hic);
+LRESULT VFWAPI ICSendMessage(HIC hic, unsigned int msg, long dw1, long dw2);
+HIC VFWAPI ICLocate(long fccType, long fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, short wFlags);
+
+#define OpenDriverA DrvOpen
+extern HDRVR VFWAPI DrvOpen(long);
+#define STORE_ALL \
+ __asm__ ( \
+ "push %%ebx\n\t" \
+ "push %%ecx\n\t" \
+ "push %%edx\n\t" \
+ "push %%esi\n\t" \
+ "push %%edi\n\t"::)
+
+#define REST_ALL \
+ __asm__ ( \
+ "pop %%edi\n\t" \
+ "pop %%esi\n\t" \
+ "pop %%edx\n\t" \
+ "pop %%ecx\n\t" \
+ "pop %%ebx\n\t"::)
+
+
+typedef struct {
+ unsigned int uDriverSignature;
+ void* hDriverModule;
+ DRIVERPROC DriverProc;
+ long dwDriverID;
+} DRVR;
+
+/***********************************************************************
+ * VideoForWindowsVersion [MSVFW.2][MSVIDEO.2]
+ * Returns the version in major.minor form.
+ * In Windows95 this returns 0x040003b6 (4.950)
+ */
+long VideoForWindowsVersion(void) {
+ return 0x040003B6; /* 4.950 */
+}
+
+/* system.ini: [drivers] */
+
+/***********************************************************************
+ * ICInfo [MSVFW.33]
+ * Get information about an installable compressor. Return TRUE if there
+ * is one.
+ */
+int VFWAPI
+ICInfo(
+ long fccType, /* [in] type of compressor ('vidc') */
+ long fccHandler, /* [in] <n>th compressor */
+ ICINFO *lpicinfo /* [out] information about compressor */
+) {
+ char type[5];
+
+ memcpy(type,&fccType,4);type[4]=0;
+
+ /* does OpenDriver/CloseDriver */
+ lpicinfo->dwSize = sizeof(ICINFO);
+ lpicinfo->fccType = fccType;
+ lpicinfo->dwFlags = 0;
+/*
+ if (GetPrivateProfileStringA("drivers32",NULL,NULL,buf,2000,"system.ini")) {
+ char *s = buf;
+ while (*s) {
+ if (!lstrncmpiA(type,s,4)) {
+ if(!fccHandler--) {
+ lpicinfo->fccHandler = mmioStringToFOURCCA(s+5,0);
+ return TRUE;
+ }
+ }
+ s=s+lstrlenA(s)+1;
+ }
+ }
+*/
+ return TRUE;
+}
+
+/***********************************************************************
+ * ICOpen [MSVFW.37]
+ * Opens an installable compressor. Return special handle.
+ */
+HIC VFWAPI
+ICOpen(long fccType,long fccHandler,unsigned int wMode) {
+ char type[5],handler[5],codecname[20];
+ ICOPEN icopen;
+ HDRVR hdrv;
+ WINE_HIC *whic;
+
+ memcpy(type,&fccType,4);type[4]=0;
+ memcpy(handler,&fccHandler,4);handler[4]=0;
+
+ sprintf(codecname,"%s.%s",type,handler);
+
+ /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the
+ * same layout as ICOPEN
+ */
+ icopen.fccType = fccType;
+ icopen.fccHandler = fccHandler;
+ icopen.dwSize = sizeof(ICOPEN);
+ icopen.dwFlags = wMode;
+ /* FIXME: do we need to fill out the rest too? */
+// hdrv=OpenDriverA(codecname,"drivers32",(long)&icopen);
+ hdrv=OpenDriverA((long)&icopen);
+/*
+ if (!hdrv) {
+ if (!strcasecmp(type,"vids")) {
+ sprintf(codecname,"vidc.%s",handler);
+ fccType = mmioFOURCC('v','i','d','c');
+ }
+// hdrv=OpenDriverA(codecname,"drivers32",(long)&icopen);
+ hdrv=OpenDriverA((long)&icopen);
+*/
+ if (!hdrv)
+ return 0;
+// }
+ whic = (WINE_HIC*)my_mreq(sizeof(WINE_HIC), 0);
+ whic->hdrv = hdrv;
+ whic->driverproc= ((DRVR*)hdrv)->DriverProc;
+// whic->private = ICSendMessage((HIC)whic,DRV_OPEN,0,(long)&icopen);
+ whic->private = ((DRVR*)hdrv)->dwDriverID;
+ return (HIC)whic;
+}
+
+/***********************************************************************
+ * ICOpenFunction [MSVFW.38]
+ */
+HIC VFWAPI ICOpenFunction(long fccType, long fccHandler, unsigned int wMode,
+void* lpfnHandler) {
+ char type[5],handler[5];
+ HIC hic;
+ WINE_HIC *whic;
+
+ memcpy(type,&fccType,4);type[4]=0;
+ memcpy(handler,&fccHandler,4);handler[4]=0;
+ FIXME("(%s,%s,%d,%p), stub!\n",type,handler,wMode,lpfnHandler);
+ hic = ICOpen(fccType,fccHandler,wMode);
+ if (!hic)
+ return hic;
+ whic = (WINE_HIC*)hic;
+ whic->driverproc = (DRIVERPROC)lpfnHandler;
+ return hic;
+}
+
+
+/***********************************************************************
+ * ICGetInfo [MSVFW.30]
+ */
+LRESULT VFWAPI
+ICGetInfo(HIC hic,ICINFO *picinfo,long cb) {
+ LRESULT ret;
+
+ ret = ICSendMessage(hic,ICM_GETINFO,(long)picinfo,cb);
+
+ return ret;
+}
+
+/***********************************************************************
+ * ICLocate [MSVFW.35]
+ */
+HIC VFWAPI
+ICLocate(
+ long fccType, long fccHandler, LPBITMAPINFOHEADER lpbiIn,
+ LPBITMAPINFOHEADER lpbiOut, short wMode
+) {
+ char type[5],handler[5];
+ HIC hic;
+ long querymsg;
+
+ switch (wMode) {
+ case ICMODE_FASTCOMPRESS:
+ case ICMODE_COMPRESS:
+ querymsg = ICM_COMPRESS_QUERY;
+ break;
+ case ICMODE_DECOMPRESS:
+ case ICMODE_FASTDECOMPRESS:
+ querymsg = ICM_DECOMPRESS_QUERY;
+ break;
+ case ICMODE_DRAW:
+ querymsg = ICM_DRAW_QUERY;
+ break;
+ default:
+ FIXME("Unknown mode (%d)\n",wMode);
+ return 0;
+ }
+
+ /* Easy case: handler/type match, we just fire a query and return */
+ hic = ICOpen(fccType,fccHandler,wMode);
+ if (hic) {
+ if (!ICSendMessage(hic,querymsg,(long)lpbiIn,(long)lpbiOut))
+ return hic;
+ ICClose(hic);
+ }
+ type[4]='\0';memcpy(type,&fccType,4);
+ handler[4]='\0';memcpy(handler,&fccHandler,4);
+ if (fccType==streamtypeVIDEO) {
+ hic = ICLocate(ICTYPE_VIDEO,fccHandler,lpbiIn,lpbiOut,wMode);
+ if (hic)
+ return hic;
+ }
+ FIXME("(%s,%s,%p,%p,0x%04x),unhandled!\n",type,handler,lpbiIn,lpbiOut,wMode);
+ return 0;
+}
+
+/***********************************************************************
+ * ICCompress [MSVFW.23]
+ */
+long VFWAPIV
+ICCompress(
+ HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpData,
+ LPBITMAPINFOHEADER lpbiInput,void* lpBits,long* lpckid,
+ long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality,
+ LPBITMAPINFOHEADER lpbiPrev,void* lpPrev
+) {
+ ICCOMPRESS iccmp;
+
+ iccmp.dwFlags = dwFlags;
+
+ iccmp.lpbiOutput = lpbiOutput;
+ iccmp.lpOutput = lpData;
+ iccmp.lpbiInput = lpbiInput;
+ iccmp.lpInput = lpBits;
+
+ iccmp.lpckid = lpckid;
+ iccmp.lpdwFlags = lpdwFlags;
+ iccmp.lFrameNum = lFrameNum;
+ iccmp.dwFrameSize = dwFrameSize;
+ iccmp.dwQuality = dwQuality;
+ iccmp.lpbiPrev = lpbiPrev;
+ iccmp.lpPrev = lpPrev;
+ return ICSendMessage(hic,ICM_COMPRESS,(long)&iccmp,sizeof(iccmp));
+}
+
+/***********************************************************************
+ * ICDecompress [MSVFW.26]
+ */
+long VFWAPIV
+ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits) {
+ ICDECOMPRESS icd;
+ int result;
+ icd.dwFlags = dwFlags;
+ icd.lpbiInput = lpbiFormat;
+ icd.lpInput = lpData;
+
+ icd.lpbiOutput = lpbi;
+ icd.lpOutput = lpBits;
+ icd.ckid = 0;
+ STORE_ALL;
+ result=ICSendMessage(hic,ICM_DECOMPRESS,(long)&icd,sizeof(icd));
+ REST_ALL;
+ return result;
+}
+
+/***********************************************************************
+ * ICSendMessage [MSVFW.40]
+ */
+LRESULT VFWAPI
+ICSendMessage(HIC hic,unsigned int msg,long lParam1,long lParam2) {
+ LRESULT ret;
+ WINE_HIC *whic = (WINE_HIC*)hic;
+ char qw[200];
+
+ __asm__ __volatile__ ("fsave (%0)\n\t": :"r"(&qw));
+ STORE_ALL;
+ /*__asm__
+ (
+ "pushl %eax\n\t"
+ "movl $0xf,%eax\n\t"
+ "movw %ax, %fs\n\t"
+ "popl %eax\n\t"
+ );*/
+ ret = whic->driverproc(whic->private,1,msg,lParam1,lParam2);
+ REST_ALL;
+ __asm__ __volatile__ ("frstor (%0)\n\t": :"r"(&qw));
+// } else
+
+// ret = SendDriverMessage(whic->hdrv,msg,lParam1,lParam2);
+// TRACE(" -> 0x%08lx\n",ret);
+ return ret;
+}
+
+
+/***********************************************************************
+ * ICClose [MSVFW.22]
+ */
+LRESULT VFWAPI ICClose(HIC hic) {
+ WINE_HIC *whic = (WINE_HIC*)hic;
+ /* FIXME: correct? */
+// CloseDriver(whic->hdrv,0,0);
+ DrvClose(whic->hdrv);
+//#warning FIXME: DrvClose
+ my_release(whic);
+ return 0;
+}
+int VFWAPI ICDoSomething()
+{
+ return 0;
+}
+
diff --git a/src/libw32dll/w32codec.c b/src/libw32dll/w32codec.c
new file mode 100644
index 000000000..b88614400
--- /dev/null
+++ b/src/libw32dll/w32codec.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: w32codec.c,v 1.1 2001/04/18 22:35:05 f1rmb Exp $
+ *
+ * routines for using w32 codecs
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "wine/msacm.h"
+#include "wine/driver.h"
+#include "wine/avifmt.h"
+#include "wine/vfw.h"
+#include "wine/mmreg.h"
+#include "../video_out/video_out.h"
+#include "../audio_out/audio_out.h"
+
+extern vo_driver_t *gVideoDriver;
+extern char* win32_codec_name;
+int w32c_yuv_supported ;
+int w32c_yuv_hack_needed ;
+int w32c_flipped ;
+unsigned char w32c_buf[128*1024];
+int w32c_size;
+unsigned char w32c_audio_buf[16384];
+int w32c_audio_size;
+unsigned char w32c_sample_buf[40000];
+BITMAPINFOHEADER w32c_bih, w32c_o_bih;
+HIC w32c_hic;
+void *our_out_buffer;
+HACMSTREAM w32c_srcstream;
+int w32c_rec_audio_src_size;
+
+char* get_vids_codec_name(unsigned long fccHandler, BITMAPINFOHEADER *bih) {
+
+ w32c_yuv_supported=0;
+ w32c_yuv_hack_needed=0;
+ w32c_flipped=0;
+ switch(fccHandler){
+ case mmioFOURCC('M', 'P', 'G', '4'):
+ case mmioFOURCC('m', 'p', 'g', '4'):
+ case mmioFOURCC('M', 'P', '4', '2'):
+ case mmioFOURCC('m', 'p', '4', '2'):
+ /* case mmioFOURCC('M', 'P', '4', '3'):
+ case mmioFOURCC('m', 'p', '4', '3'): */
+ /* Video in Microsoft MPEG-4 format */
+ w32c_yuv_supported=1;
+ w32c_yuv_hack_needed=1;
+ return "mpg4c32.dll";
+ case mmioFOURCC('M', 'P', '4', '3'):
+ case mmioFOURCC('m', 'p', '4', '3'):
+ /* Video in MPEG-4 v3 (really DivX) format */
+ bih->biCompression=mmioFOURCC('d', 'i', 'v', '3'); /* hack */
+ w32c_yuv_supported=1;
+ w32c_yuv_hack_needed=1;
+ return "divxc32.dll";
+
+ case mmioFOURCC('D', 'I', 'V', '3'):
+ case mmioFOURCC('d', 'i', 'v', '3'):
+ case mmioFOURCC('D', 'I', 'V', '4'):
+ case mmioFOURCC('d', 'i', 'v', '4'):
+ case mmioFOURCC('M', 'P', '4', '1'):
+ case mmioFOURCC('m', 'p', '4', '1'):
+ /* Video in DivX ;-) format */
+ w32c_yuv_supported =1;
+ w32c_yuv_hack_needed=1;
+ return "divxc32.dll";
+
+ case mmioFOURCC('I', 'V', '5', '0'):
+ case mmioFOURCC('i', 'v', '5', '0'):
+ /* Video in Indeo Video 5 format */
+ w32c_yuv_supported=1; /* YUV pic is upside-down :( */
+ return "ir50_32.dll";
+
+ case mmioFOURCC('I', 'V', '4', '1'):
+ case mmioFOURCC('i', 'v', '4', '1'):
+ /* Video in Indeo Video 4.1 format */
+ w32c_flipped=1;
+ return "ir41_32.dll";
+
+ case mmioFOURCC('I', 'V', '3', '2'):
+ case mmioFOURCC('i', 'v', '3', '2'):
+ /* Video in Indeo Video 3.2 format */
+ w32c_flipped=1;
+ return "ir32_32.dll";
+
+ case mmioFOURCC('c', 'v', 'i', 'd'):
+ /* Video in Cinepak format */
+ w32c_yuv_supported=1;
+ return "iccvid.dll";
+
+ /*** Only 16bit .DLL available (can't load under linux) ***
+ case mmioFOURCC('V', 'C', 'R', '1'):
+ printf("Video in ATI VCR1 format\n");
+ return "ativcr1.dll";
+ */
+
+ case mmioFOURCC('V', 'C', 'R', '2'):
+ /* Video in ATI VCR2 format */
+ w32c_yuv_supported=1;
+ return "ativcr2.dll";
+
+ case mmioFOURCC('I', '2', '6', '3'):
+ case mmioFOURCC('i', '2', '6', '3'):
+ /* Video in I263 format */
+ return "i263_32.drv";
+
+ case mmioFOURCC('M', 'J', 'P', 'G'):
+ /* Video in MJPEG format */
+ w32c_yuv_supported=1;
+ return "mcmjpg32.dll";
+ /* return "m3jpeg32.dll";
+ return "libavi_mjpeg.so"; */
+ }
+ printf("UNKNOWN video codec: %.4s (0x%0X)\n",(char*)&fccHandler,(int)fccHandler);
+ printf("If you know this video format and codec, you can edit codecs.c in the source!\n");
+ printf("Please contact the author, send this movie to be supported by future version.\n");
+ return NULL;
+}
+
+#define IMGFMT_YUY2 (('2'<<24)|('Y'<<16)|('U'<<8)|'Y')
+
+int w32c_init_video (BITMAPINFOHEADER *bih_){
+ HRESULT ret;
+ int outfmt = IMGFMT_YUY2;
+ int video_step;
+
+ memcpy ( &w32c_bih, bih_, sizeof (BITMAPINFOHEADER));
+ video_step = w32c_bih.biSize; /* HACK */
+ w32c_bih.biSize = sizeof(BITMAPINFOHEADER);
+
+ memset(&w32c_o_bih, 0, sizeof(BITMAPINFOHEADER));
+ w32c_o_bih.biSize = sizeof(BITMAPINFOHEADER);
+
+ win32_codec_name = get_vids_codec_name (w32c_bih.biCompression, &w32c_bih);
+ w32c_hic = ICOpen( 0x63646976, w32c_bih.biCompression, ICMODE_FASTDECOMPRESS);
+
+ if(!w32c_hic){
+ printf("ICOpen failed! unknown codec / wrong parameters?\n");
+ return 0;
+ }
+
+ ret = ICDecompressGetFormat(w32c_hic, &w32c_bih, &w32c_o_bih);
+ if(ret){
+ printf("ICDecompressGetFormat failed: Error %ld\n", (long)ret);
+ return 0;
+ }
+
+ if(outfmt==IMGFMT_YUY2)
+ w32c_o_bih.biBitCount=16;
+ else
+ w32c_o_bih.biBitCount=outfmt&0xFF;// //24;
+
+ w32c_o_bih.biSizeImage = w32c_o_bih.biWidth*w32c_o_bih.biHeight*(w32c_o_bih.biBitCount/8);
+
+ /*
+ if(!flipped)
+ w32c_o_bih.biHeight=-bih.biHeight; */ /* flip image! */
+
+ w32c_o_bih.biHeight=-w32c_bih.biHeight;
+
+ if(outfmt==IMGFMT_YUY2 && !w32c_yuv_hack_needed)
+ w32c_o_bih.biCompression = mmioFOURCC('Y','U','Y','2');
+
+ ret = ICDecompressQuery(w32c_hic, &w32c_bih, &w32c_o_bih);
+
+ if(ret){
+ printf("ICDecompressQuery failed: Error %ld\n", (long)ret);
+ return 0;
+ }
+
+ ret = ICDecompressBegin(w32c_hic, &w32c_bih, &w32c_o_bih);
+ if(ret){
+ printf("ICDecompressBegin failed: Error %ld\n", (long)ret);
+ return 0;
+ }
+
+ if (w32c_yuv_hack_needed) {
+ w32c_o_bih.biCompression = mmioFOURCC('Y','U','Y','2');
+ }
+
+ w32c_size = 0;
+
+ if (!(gVideoDriver->get_capabilities () && VO_CAP_YUY2)) {
+ printf ("video output driver doesn't support YUY2 !!");
+ }
+
+ vo_set_image_format (w32c_bih.biWidth, w32c_bih.biHeight, 42, IMGFMT_YUY2, video_step);
+
+ our_out_buffer = malloc (w32c_o_bih.biSizeImage);
+
+ return 1;
+}
+
+int nFrame = 0;
+
+void w32c_decode_video (unsigned char *data, uint32_t nSize, int bFrameEnd, uint32_t nPTS) {
+
+ HRESULT ret;
+ vo_image_buffer_t *img;
+
+ memcpy (&w32c_buf[w32c_size], data, nSize);
+
+ w32c_size += nSize;
+
+ if (bFrameEnd) {
+
+ w32c_bih.biSizeImage = w32c_size;
+ /*
+ printf ("Frame complete => decompressing [%d %d %d %d ... %d %d]size=%d\n",
+ w32c_buf[0],w32c_buf[1],w32c_buf[2],w32c_buf[3],
+ w32c_buf[w32c_size-2],w32c_buf[w32c_size-1], w32c_size);
+ */
+
+ img = vo_alloc_image_buffer();
+
+ /* printf ("ICDecrompress %d\n",img); */
+
+ ret = ICDecompress(w32c_hic, ICDECOMPRESS_NOTKEYFRAME,
+ &w32c_bih, w32c_buf,
+ &w32c_o_bih, img->mem[0]);
+
+ /* memcpy(img->mem[0],our_out_buffer,w32c_bih.biWidth*w32c_bih.biHeight*2); */
+ /* memset(img->mem[1],128,w32c_o_bih.biWidth*w32c_o_bih.biHeight/4); */
+ /* memset(img->mem[2],128,w32c_o_bih.biWidth*w32c_o_bih.biHeight/4); */
+
+ img->PTS = nPTS;
+ if(ret) {
+ printf("Error decompressing frame, err=%ld\n", (long)ret);
+ img->bFrameBad = 1;
+ } else
+ img->bFrameBad = 0;
+
+ img->nID = nFrame;
+ nFrame++;
+
+ vo_queue_frame (img);
+ vo_free_image_buffer (img);
+
+
+ w32c_size = 0;
+ }
+
+}
+
+void w32c_close_video () {
+}
+
+char* get_auds_codec_name(int id){
+
+ switch (id){
+ case 0x160:/* DivX audio */
+ case 0x161:/* DivX audio */
+ return "divxa32.acm";
+ case 0x2: /* MS ADPCM */
+ return "msadp32.acm";
+ case 0x55: /* MPEG l3 */
+ return "l3codeca.acm";
+ case 0x11: /* IMA ADPCM */
+ return "imaadp32.acm";
+ case 0x31: /* MS GSM */
+ case 0x32: /* MS GSM */
+ return "msgsm32.acm";
+ }
+ printf("UNKNOWN audio codec: 0x%0X\n",id);
+ printf("If you know this audio format and codec, you can edit codecs.c in the source!\n");
+ printf("Please contact the author, send this movie to be supported by future version.\n");
+ return NULL;
+}
+
+int w32c_init_audio (WAVEFORMATEX *in_fmt_){
+
+ HRESULT ret;
+ static WAVEFORMATEX wf;
+ long in_size=in_fmt_->nBlockAlign;
+ unsigned long srcsize=0;
+ static WAVEFORMATEX *in_fmt;
+
+ in_fmt = (WAVEFORMATEX *) malloc (64);
+
+ memcpy (in_fmt, in_fmt_, sizeof (WAVEFORMATEX) + in_fmt_->cbSize);
+
+ if ( (in_fmt->wFormatTag == 0x01) || (in_fmt->wFormatTag == 0x2000)
+ || (in_fmt->wFormatTag == 0x50) || (in_fmt->wFormatTag == 0x53) ) {
+ /* handled by other codecs in source code */
+ return 1;
+ }
+
+ w32c_srcstream=NULL;
+
+ gAudioOut->open (16, in_fmt->nSamplesPerSec, AO_MODE_STEREO);
+
+ wf.nChannels=in_fmt->nChannels;
+ wf.nSamplesPerSec=in_fmt->nSamplesPerSec;
+ wf.nAvgBytesPerSec=2*wf.nSamplesPerSec*wf.nChannels;
+ wf.wFormatTag=WAVE_FORMAT_PCM;
+ wf.nBlockAlign=2*in_fmt->nChannels;
+ wf.wBitsPerSample=16;
+ wf.cbSize=0;
+
+ win32_codec_name = get_auds_codec_name (in_fmt->wFormatTag);
+ ret=acmStreamOpen(&w32c_srcstream,(HACMDRIVER)NULL,
+ in_fmt,
+ &wf,
+ NULL,0,0,0);
+ if(ret){
+ if(ret==ACMERR_NOTPOSSIBLE)
+ printf("ACM_Decoder: Unappropriate audio format\n");
+ else
+ printf("ACM_Decoder: acmStreamOpen error %d", ret);
+ w32c_srcstream=NULL;
+ return 0;
+ }
+
+ /*
+ acmStreamSize(w32c_srcstream, in_size, &srcsize, ACM_STREAMSIZEF_SOURCE);
+ printf("Audio buffer min. size: %d\n",srcsize);
+ */
+
+ acmStreamSize(w32c_srcstream, 16384, &w32c_rec_audio_src_size, ACM_STREAMSIZEF_DESTINATION);
+ /* printf("recommended source buffer size: %d\n", w32c_rec_audio_src_size); */
+
+ w32c_audio_size = 0;
+
+ return 1;
+}
+
+
+void w32c_decode_audio (unsigned char *data, uint32_t nSize, int bFrameEnd, uint32_t nPTS) {
+
+ static ACMSTREAMHEADER ash;
+ HRESULT hr;
+ DWORD srcsize=0;
+
+ memcpy (&w32c_audio_buf[w32c_audio_size], data, nSize);
+
+ w32c_audio_size += nSize;
+
+ while (w32c_audio_size >= w32c_rec_audio_src_size) {
+
+ memset(&ash, 0, sizeof(ash));
+ ash.cbStruct=sizeof(ash);
+ ash.fdwStatus=0;
+ ash.dwUser=0;
+ ash.pbSrc=w32c_audio_buf;
+ ash.cbSrcLength=w32c_rec_audio_src_size;
+ ash.pbDst=w32c_sample_buf;
+ ash.cbDstLength=20000;
+ hr=acmStreamPrepareHeader(w32c_srcstream,&ash,0);
+ if(hr){
+ printf("ACM_Decoder: acmStreamPrepareHeader error %d\n",hr);
+ return;
+ }
+
+ /*
+ printf ("decoding %d of %d bytes (%02x %02x %02x %02x ... %02x %02x)\n",
+ w32c_rec_audio_src_size, w32c_audio_size,
+ w32c_audio_buf[0], w32c_audio_buf[1], w32c_audio_buf[2], w32c_audio_buf[3],
+ w32c_audio_buf[w32c_rec_audio_src_size-2], w32c_audio_buf[w32c_rec_audio_src_size-1]);
+ */
+
+ hr=acmStreamConvert(w32c_srcstream,&ash,0);
+ if(hr){
+ /* printf("acmStreamConvert error %d, used %d bytes\n",hr,ash.cbSrcLengthUsed); */
+ ash.cbSrcLengthUsed = w32c_rec_audio_src_size;
+ } else {
+ /*
+ printf ("acmStreamConvert worked, used %d bytes, generated %d bytes\n",
+ ash.cbSrcLengthUsed, ash.cbDstLengthUsed);
+ */
+ if (ash.cbDstLengthUsed>0) {
+ /*
+ printf ("decoded : %02x %02x %02x %02x ... %02x %02x \n",
+ w32c_sample_buf[0], w32c_sample_buf[1], w32c_sample_buf[2], w32c_sample_buf[3],
+ w32c_sample_buf[ash.cbDstLengthUsed-2], w32c_sample_buf[ash.cbDstLengthUsed-1]);
+ */
+ gAudioOut->write_audio_data (w32c_sample_buf, ash.cbDstLengthUsed / 4, nPTS);
+ }
+ }
+ if(ash.cbSrcLengthUsed>=w32c_audio_size){
+ w32c_audio_size=0;
+ } else {
+ unsigned char *pSrc, *pDst;
+ int i;
+
+ w32c_audio_size-=ash.cbSrcLengthUsed;
+
+ pSrc = &w32c_audio_buf [ash.cbSrcLengthUsed];
+ pDst = w32c_audio_buf;
+ for (i=0; i<w32c_audio_size; i++) {
+ *pDst = *pSrc;
+ pDst ++;
+ pSrc ++;
+ }
+ }
+
+ hr=acmStreamUnprepareHeader(w32c_srcstream,&ash,0);
+ if(hr){
+ printf("ACM_Decoder: acmStreamUnprepareHeader error %d\n",hr);
+ }
+ }
+}
+
+void w32c_close_audio () {
+ acmStreamClose(w32c_srcstream, 0);
+}
diff --git a/src/libw32dll/w32codec.h b/src/libw32dll/w32codec.h
new file mode 100644
index 000000000..15a0ec867
--- /dev/null
+++ b/src/libw32dll/w32codec.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: w32codec.h,v 1.1 2001/04/18 22:35:05 f1rmb Exp $
+ *
+ * routines for using w32 codecs
+ *
+ */
+
+#include "wine/msacm.h"
+#include "wine/avifmt.h"
+#include "wine/vfw.h"
+
+
+int w32c_init_video(BITMAPINFOHEADER *bih) ;
+
+void w32c_decode_video (unsigned char *data, uint32_t nSize, int bFrameEnd, uint32_t nPTS);
+
+void w32c_close_video ();
+
+int w32c_init_audio (WAVEFORMATEX *in_fmt);
+
+void w32c_decode_audio (unsigned char *data, uint32_t nSize, int bFrameEnd, uint32_t nPTS) ;
+
+void w32c_close_audio ();
diff --git a/src/libw32dll/win32.c b/src/libw32dll/win32.c
new file mode 100644
index 000000000..7fc879530
--- /dev/null
+++ b/src/libw32dll/win32.c
@@ -0,0 +1,1706 @@
+/***********************************************************
+
+ Win32 emulation code. Functions that emulate
+ responses from corresponding Win32 API calls.
+ Since we are not going to be able to load
+ virtually any DLL, we can only implement this
+ much, adding needed functions with each new codec.
+
+************************************************************/
+
+#include "config.h"
+
+#include "win32.h"
+#include <stdio.h>
+#include <pthread.h>
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>
+#else
+#include <stdlib.h>
+#endif
+#include <time.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+
+#include "wine/winbase.h"
+#include "wine/winreg.h"
+#include "wine/winnt.h"
+#include "wine/winerror.h"
+#include "wine/debugtools.h"
+#include "wine/module.h"
+
+#include "registry.h"
+#include "loader.h"
+#ifdef USE_TSC
+static unsigned int localcount()
+{
+ int a;
+ __asm__ __volatile__("rdtsc\n\t"
+ :"=a"(a)
+ :
+ :"edx");
+ return a;
+}
+static void longcount(long long* z)
+{
+ __asm__ __volatile__(
+ "pushl %%ebx\n\t"
+ "movl %%eax, %%ebx\n\t"
+ "rdtsc\n\t"
+ "movl %%eax, 0(%%ebx)\n\t"
+ "movl %%edx, 4(%%ebx)\n\t"
+ "popl %%ebx\n\t"
+ ::"a"(z));
+}
+#else
+#include <sys/time.h>
+#include <unistd.h>
+static unsigned int localcount()
+{
+ struct timeval tv;
+ unsigned limit=~0;
+ limit/=1000000;
+ gettimeofday(&tv, 0);
+ return limit*tv.tv_usec;
+}
+static void longcount(long long* z)
+{
+ struct timeval tv;
+ unsigned long long result;
+ unsigned limit=~0;
+ if(!z)return;
+ limit/=1000000;
+ gettimeofday(&tv, 0);
+ result=tv.tv_sec;
+ result<<=32;
+ result+=limit*tv.tv_usec;
+ *z=result;
+}
+#endif
+
+void dbgprintf(char* fmt, ...)
+{
+#ifdef DETAILED_OUT
+#if 1
+ va_list va;
+ va_start(va, fmt);
+ vprintf(fmt, va);
+ va_end(va);
+#else
+ va_list va;
+ FILE* f;
+ va_start(va, fmt);
+ f=fopen("./log", "a");
+ if(f==0)return;
+ vfprintf(f, fmt, va);
+ fsync(f);
+ fclose(f);
+#endif
+#endif
+}
+char export_names[500][30]={
+"name1",
+//"name2",
+//"name3"
+};
+//#define min(x,y) ((x)<(y)?(x):(y))
+
+static unsigned char* heap=NULL;
+static int heap_counter=0;
+void test_heap()
+{
+ int offset=0;
+ if(heap==0)
+ return;
+ while(offset<heap_counter)
+ {
+ if(*(int*)(heap+offset)!=0x433476)
+ {
+ printf("Heap corruption at address %d\n", offset);
+ return;
+ }
+ offset+=8+*(int*)(heap+offset+4);
+ }
+ for(;offset<min(offset+1000, 20000000); offset++)
+ if(heap[offset]!=0xCC)
+ {
+ printf("Free heap corruption at address %d\n", offset);
+ }
+}
+#undef MEMORY_DEBUG
+
+#ifdef MEMORY_DEBUG
+
+void* my_mreq(int size, int to_zero)
+{
+ static int test=0;
+ test++;
+ if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter);
+// test_heap();
+ if(heap==NULL)
+ {
+ heap=malloc(20000000);
+ memset(heap, 0xCC,20000000);
+ }
+ if(heap==0)
+ {
+ printf("No enough memory\n");
+ return 0;
+ }
+ if(heap_counter+size>20000000)
+ {
+ printf("No enough memory\n");
+ return 0;
+ }
+ *(int*)(heap+heap_counter)=0x433476;
+ heap_counter+=4;
+ *(int*)(heap+heap_counter)=size;
+ heap_counter+=4;
+ printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size);
+ if(to_zero)
+ memset(heap+heap_counter, 0, size);
+ heap_counter+=size;
+ return heap+heap_counter-size;
+}
+int my_release(char* memory)
+{
+// test_heap();
+ if(memory==NULL)
+ {
+ printf("ERROR: free(0)\n");
+ return 0;
+ }
+ if(*(int*)(memory-8)!=0x433476)
+ {
+ printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
+ return 0;
+ }
+ printf("Freed %d bytes of memory\n", *(int*)(memory-4));
+// memset(memory-8, *(int*)(memory-4), 0xCC);
+ return 0;
+}
+
+#else
+void* my_mreq(int size, int to_zero)
+{
+ void* answer;
+ if(to_zero)
+ answer=calloc(size+4, 1);
+ else
+ answer=malloc(size+4);
+ *(int*)answer=size;
+ return (int*)answer+1;
+}
+int my_release(char* memory)
+{
+ if(memory==0)return 0;
+ free(memory-4);
+ return 0;
+}
+#endif
+int my_size(char* memory)
+{
+ return *(int*)(memory-4);
+}
+
+extern int unk_exp1;
+char extcode[20000];// place for 200 unresolved exports
+int pos=0;
+
+int WINAPI ext_unknown()
+{
+ printf("Unknown func called\n");
+ return 0;
+}
+int WINAPI expIsBadWritePtr(void* ptr, unsigned int count)
+{
+ dbgprintf("IsBadWritePtr(%x, %x)\n", ptr, count);
+ if(count==0)
+ return 0;
+ if(ptr==0)
+ return 1;
+ return 0;
+}
+int WINAPI expIsBadReadPtr(void* ptr, unsigned int count)
+{
+ dbgprintf("IsBadReadPtr(%x, %x)\n", ptr, count);
+ if(count==0)
+ return 0;
+ if(ptr==0)
+ return 1;
+ return 0;
+}
+void* CDECL expmalloc(int size)
+{
+//printf("malloc");
+// return malloc(size);
+ void* result=my_mreq(size,0);
+ dbgprintf("malloc(%x)\n", size);
+ if(result==0)
+ {
+ dbgprintf("returns 0\n");
+ printf("WARNING: malloc() failed\n");
+ }
+ return result;
+}
+void CDECL expfree(void* mem)
+{
+// return free(mem);
+ dbgprintf("free(%x)\n", mem);
+ my_release(mem);
+}
+void* CDECL expnew(int size)
+{
+// printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
+// printf("%08x %08x %08x %08x\n",
+// size, *(1+(int*)&size),
+// *(2+(int*)&size),*(3+(int*)&size));
+ void* result=expmalloc(size);
+ dbgprintf("new(%x)\n", size);
+ if(result==0)
+ {
+ dbgprintf("returns 0\n");
+ printf("WARNING: malloc() failed\n");
+ }
+ return result;
+
+}
+int CDECL expdelete(void* memory)
+{
+ dbgprintf("delete(%x)\n", memory);
+ expfree(memory);
+ return 0;
+}
+int WINAPI expDisableThreadLibraryCalls(int module)
+{
+ dbgprintf("DisableThreadLibraryCalls(%x)\n", module);
+ return 0;
+}
+int CDECL exp_initterm(int v1, int v2)
+{
+ return 0;
+}
+
+typedef struct {
+ unsigned int uDriverSignature;
+ void* hDriverModule;
+ void* DriverProc;
+ unsigned int dwDriverID;
+} DRVR;
+
+void* WINAPI expGetDriverModuleHandle(DRVR* pdrv)
+{
+ dbgprintf("GetDriverModuleHandle(%x)\n", pdrv);
+ return pdrv->hDriverModule;
+}
+
+void* WINAPI expGetModuleHandleA(const char* name)
+{
+ WINE_MODREF* wm;
+ dbgprintf("GetModuleHandleA(%s)\n", name);
+ if(!name)return 0;
+ wm=MODULE_FindModule(name);
+ if(wm==0)return 0;
+ return (void*)(wm->module);
+}
+struct th_list_t;
+typedef struct th_list_t{
+int id;
+void* thread;
+struct th_list_t* next;
+struct th_list_t* prev;
+}th_list;
+
+static th_list* list=NULL;
+
+
+
+void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize, void* lpStartAddress,
+ void* lpParameter, long dwFlags, long* dwThreadId)
+{
+ pthread_t *pth;
+// printf("CreateThread:");
+ pth=my_mreq(sizeof(pthread_t), 0);
+ dbgprintf("pthread_create\n");
+ pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter);
+ if(dwFlags)
+ dbgprintf( "WARNING: CreateThread flags not supported\n");
+ if(dwThreadId)
+ *dwThreadId=(long)pth;
+ dbgprintf( "Created thread %08X\n", pth);
+ if(list==NULL)
+ {
+ list=my_mreq(sizeof(th_list), 1);
+ list->next=list->prev=NULL;
+ }
+ else
+ {
+ list->next=my_mreq(sizeof(th_list), 0);
+ list->next->prev=list;
+ list->next->next=NULL;
+ list=list->next;
+ }
+ list->thread=pth;
+ return pth;
+}
+
+struct mutex_list_t;
+
+struct mutex_list_t
+{
+ pthread_mutex_t *pm;
+ char name[64];
+ struct mutex_list_t* next;
+ struct mutex_list_t* prev;
+};
+typedef struct mutex_list_t mutex_list;
+static mutex_list* mlist=NULL;
+void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
+ char bInitialState, const char* name)
+{
+#warning ManualReset
+ pthread_mutex_t *pm;
+ dbgprintf("CreateEvent\n");
+ if(mlist!=NULL)
+ {
+ mutex_list* pp=mlist;
+ if(name!=NULL)
+ do
+ {
+ if(strcmp(pp->name, name)==0)
+ return pp->pm;
+ }while(pp=pp->prev);
+ }
+ pm=my_mreq(sizeof(pthread_mutex_t), 0);
+ pthread_mutex_init(pm, NULL);
+ if(mlist==NULL)
+ {
+ mlist=my_mreq(sizeof(mutex_list), 00);
+ mlist->next=mlist->prev=NULL;
+ }
+ else
+ {
+ mlist->next=my_mreq(sizeof(mutex_list), 00);
+ mlist->next->prev=mlist->next;
+ mlist->next->next=NULL;
+ mlist=mlist->next;
+ }
+ mlist->pm=pm;
+ if(name!=NULL)
+ strncpy(mlist->name, name, 64);
+ else
+ mlist->name[0]=0;
+ if(pm==NULL)
+ dbgprintf("ERROR::: CreateEventA failure\n");
+ if(bInitialState)
+ pthread_mutex_lock(pm);
+ return pm;
+}
+
+void* WINAPI expSetEvent(void* event)
+{
+ dbgprintf("Trying to lock %X\n", event);
+ pthread_mutex_lock(event);
+}
+void* WINAPI expResetEvent(void* event)
+{
+ dbgprintf("Unlocking %X\n", event);
+ pthread_mutex_unlock(event);
+}
+
+void* WINAPI expWaitForSingleObject(void* object, int duration)
+{
+#warning not sure
+ dbgprintf("WaitForSingleObject: duration %d\n", duration);
+ pthread_mutex_lock(object);
+ pthread_mutex_unlock(object);
+}
+
+static BYTE PF[64] = {0,};
+
+void WINAPI expGetSystemInfo(SYSTEM_INFO* si)
+{
+ /* FIXME: better values for the two entries below... */
+ static int cache = 0;
+ static SYSTEM_INFO cachedsi;
+ HKEY xhkey=0,hkey;
+ dbgprintf("GetSystemInfo()\n");
+
+ if (cache) {
+ memcpy(si,&cachedsi,sizeof(*si));
+ return;
+ }
+ memset(PF,0,sizeof(PF));
+
+ cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
+ cachedsi.dwPageSize = getpagesize();
+
+ /* FIXME: better values for the two entries below... */
+ cachedsi.lpMinimumApplicationAddress = (void *)0x40000000;
+ cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
+ cachedsi.dwActiveProcessorMask = 1;
+ cachedsi.dwNumberOfProcessors = 1;
+ cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
+ cachedsi.dwAllocationGranularity = 0x10000;
+ cachedsi.wProcessorLevel = 3; /* pentium */
+ cachedsi.wProcessorRevision = 0;
+
+#ifdef __FreeBSD__
+ cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
+ cachedsi.wProcessorLevel= 5;
+ PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
+#ifdef MMX
+ PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
+#endif
+ cachedsi.dwNumberOfProcessors=1;
+#else
+ {
+ char buf[20];
+ char line[200];
+ FILE *f = fopen ("/proc/cpuinfo", "r");
+
+ if (!f)
+ return;
+ xhkey = 0;
+ while (fgets(line,200,f)!=NULL) {
+ char *s,*value;
+
+ /* NOTE: the ':' is the only character we can rely on */
+ if (!(value = strchr(line,':')))
+ continue;
+ /* terminate the valuename */
+ *value++ = '\0';
+ /* skip any leading spaces */
+ while (*value==' ') value++;
+ if ((s=strchr(value,'\n')))
+ *s='\0';
+
+ /* 2.1 method */
+ if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) {
+ if (isdigit (value[0])) {
+ switch (value[0] - '0') {
+ case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
+ cachedsi.wProcessorLevel= 3;
+ break;
+ case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
+ cachedsi.wProcessorLevel= 4;
+ break;
+ case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
+ cachedsi.wProcessorLevel= 5;
+ break;
+ case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
+ cachedsi.wProcessorLevel= 5;
+ break;
+ default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
+ cachedsi.wProcessorLevel= 5;
+ break;
+ }
+ }
+ /* set the CPU type of the current processor */
+ sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
+ continue;
+ }
+ /* old 2.0 method */
+ if (!lstrncmpiA(line, "cpu",strlen("cpu"))) {
+ if ( isdigit (value[0]) && value[1] == '8' &&
+ value[2] == '6' && value[3] == 0
+ ) {
+ switch (value[0] - '0') {
+ case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
+ cachedsi.wProcessorLevel= 3;
+ break;
+ case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
+ cachedsi.wProcessorLevel= 4;
+ break;
+ case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
+ cachedsi.wProcessorLevel= 5;
+ break;
+ case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
+ cachedsi.wProcessorLevel= 5;
+ break;
+ default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
+ cachedsi.wProcessorLevel= 5;
+ break;
+ }
+ }
+ /* set the CPU type of the current processor */
+ sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
+ continue;
+ }
+ if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) {
+ if (!lstrncmpiA(value,"yes",3))
+ PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
+
+ continue;
+ }
+ if (!lstrncmpiA(line,"fpu",strlen("fpu"))) {
+ if (!lstrncmpiA(value,"no",2))
+ PF[PF_FLOATING_POINT_EMULATED] = TRUE;
+
+ continue;
+ }
+ if (!lstrncmpiA(line,"processor",strlen("processor"))) {
+ /* processor number counts up...*/
+ int x;
+
+ if (sscanf(value,"%d",&x))
+ if (x+1>cachedsi.dwNumberOfProcessors)
+ cachedsi.dwNumberOfProcessors=x+1;
+
+ /* Create a new processor subkey on a multiprocessor
+ * system
+ */
+ sprintf(buf,"%d",x);
+ }
+ if (!lstrncmpiA(line,"stepping",strlen("stepping"))) {
+ int x;
+
+ if (sscanf(value,"%d",&x))
+ cachedsi.wProcessorRevision = x;
+ }
+ if ( (!lstrncmpiA(line,"flags",strlen("flags"))) ||
+ (!lstrncmpiA(line,"features",strlen("features"))) ) {
+ if (strstr(value,"cx8"))
+ PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
+ if (strstr(value,"mmx"))
+ PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
+
+ }
+ }
+ fclose (f);
+ }
+#endif /* __FreeBSD__ */
+ memcpy(si,&cachedsi,sizeof(*si));
+}
+
+long WINAPI expGetVersion()
+{
+ return 0xC0000A04;//Windows 98
+}
+
+HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size)
+{
+// printf("HeapCreate:");
+ dbgprintf("HeapCreate(%X, %X, %X)\n", flags, init_size, max_size);
+ if(init_size==0)
+ return (HANDLE)my_mreq(0x110000, 0);
+ else
+ return (HANDLE)my_mreq(init_size, 0);
+}
+void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size)
+{
+ void* z;
+ dbgprintf("HeapAlloc(%X, %X, %X)\n", heap, flags, size);
+// printf("HeapAlloc:");
+ z=my_mreq(size, flags&8);
+// z=HeapAlloc(heap,flags,size);
+ if(z==0)
+ printf("HeapAlloc failure\n");
+ return z;
+}
+long WINAPI expHeapDestroy(void* heap)
+{
+ dbgprintf("HeapDestroy(%X)\n", heap);
+ my_release(heap);
+ return 1;
+}
+
+long WINAPI expHeapFree(int arg1, int arg2, void* ptr)
+{
+ dbgprintf("HeapFree(%X, %X, %X)\n", arg1, arg2, ptr);
+ my_release(ptr);
+ return 1;
+}
+long WINAPI expHeapSize(int heap, int flags, void* pointer)
+{
+ return my_size(pointer);
+}
+long WINAPI expGetProcessHeap(void)
+{
+ return 1;
+}
+void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4)
+{
+ void* z;
+ dbgprintf("VirtualAlloc(%d %d %d %d) \n",v1,v2,v3,v4);
+ z=VirtualAlloc(v1, v2, v3, v4);
+ if(z==0)
+ printf("VirtualAlloc failure\n");
+ return z;
+}
+int WINAPI expVirtualFree(void* v1, int v2, int v3)
+{
+ dbgprintf("VirtualFree(%X %X %X) \n",v1,v2,v3);
+ return VirtualFree(v1,v2,v3);
+}
+struct CRITSECT
+{
+ pthread_t id;
+ pthread_mutex_t mutex;
+ int locked;
+};
+void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c)
+{
+ struct CRITSECT cs;
+ dbgprintf("InitCriticalSection(%X) \n", c);
+/* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
+ {
+ printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
+ sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
+ return;
+ }*/
+/* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
+ pthread_mutex_init(&cs.mutex, NULL);
+ cs.locked=0;
+ *(void**)c=malloc(sizeof cs);
+ memcpy(*(void**)c, &cs, sizeof cs);
+ return;
+}
+void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c)
+{
+ struct CRITSECT* cs=(struct CRITSECT*)c;
+ dbgprintf("EnterCriticalSection(%X) \n",c);
+// cs.id=pthread_self();
+ if(cs->locked)
+ if(cs->id==pthread_self())
+ return;
+ pthread_mutex_lock(&(cs->mutex));
+ cs->locked=1;
+ cs->id=pthread_self();
+ return;
+}
+void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c)
+{
+ struct CRITSECT* cs=(struct CRITSECT*)c;
+ dbgprintf("LeaveCriticalSection(%X) \n",c);
+ cs->locked=0;
+ pthread_mutex_unlock(&(cs->mutex));
+ return;
+}
+void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c)
+{
+ dbgprintf("DeleteCriticalSection(%X) \n",c);
+ pthread_mutex_destroy((pthread_mutex_t*)c);
+ return;
+}
+int WINAPI expGetCurrentThreadId()
+{
+ dbgprintf("GetCurrentThreadId() \n");
+ return getpid();
+}
+struct tls_s;
+typedef struct tls_s
+{
+ void* value;
+ int used;
+ struct tls_s* prev;
+ struct tls_s* next;
+}tls_t;
+
+tls_t* g_tls=NULL;
+
+void* WINAPI expTlsAlloc()
+{
+ dbgprintf("TlsAlloc \n");
+ if(g_tls==NULL)
+ {
+ g_tls=my_mreq(sizeof(tls_t), 0);
+ g_tls->next=g_tls->prev=NULL;
+ }
+ else
+ {
+ g_tls->next=my_mreq(sizeof(tls_t), 0);
+ g_tls->next->prev=g_tls;
+ g_tls->next->next=NULL;
+ g_tls=g_tls->next;
+ }
+ return g_tls;
+}
+
+int WINAPI expTlsSetValue(tls_t* index, void* value)
+{
+ dbgprintf("TlsSetVal(%X %X) \n", index, value );
+ if(index==0)
+ return 0;
+ index->value=value;
+ return 1;
+}
+void* WINAPI expTlsGetValue(tls_t* index)
+{
+ dbgprintf("TlsGetVal(%X) \n", index );
+ if(index==0)
+ return 0;
+ return index->value;
+}
+int WINAPI expTlsFree(tls_t* index)
+{
+ dbgprintf("TlsFree(%X) \n", index);
+ if(index==0)
+ return 0;
+ if(index->next)
+ index->next->prev=index->prev;
+ if(index->prev)
+ index->prev->next=index->next;
+ my_release((void*)index);
+ return 1;
+}
+
+void* WINAPI expLocalAlloc(int flags, int size)
+{
+ void* z;
+ dbgprintf("LocalAlloc(%d, flags %X)\n", size, flags);
+ if(flags&GMEM_ZEROINIT)
+ z=my_mreq(size, 1);
+ else
+ z=my_mreq(size, 0);
+ if(z==0)
+ printf("LocalAlloc() failed\n");
+ return z;
+}
+void* WINAPI expLocalLock(void* z)
+{
+ dbgprintf("LocalLock\n");
+ return z;
+}
+void* WINAPI expGlobalAlloc(int flags, int size)
+{
+ void* z;
+ dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags);
+ if(flags&GMEM_ZEROINIT)
+ z=my_mreq(size, 1);
+ else
+ z=my_mreq(size, 0);
+ if(z==0)
+ printf("LocalAlloc() failed\n");
+ return z;
+}
+void* WINAPI expGlobalLock(void* z)
+{
+ dbgprintf("GlobalLock\n");
+ return z;
+}
+
+int WINAPI expLoadStringA(long instance, long id, void* buf, long size)
+{
+ dbgprintf("LoadStringA\n");
+ return LoadStringA(instance, id, buf, size);
+}
+
+long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, char* s2, int siz2)
+{
+#warning FIXME
+ dbgprintf("MB2WCh\n");
+ dbgprintf("WARNING: Unsupported call: MBToWCh %s\n", s1);
+ if(s2==0)
+ return 1;
+ s2[0]=s2[1]=0;
+ return 1;
+}
+long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1, char* s2, int siz2, char* c3, int* siz3)
+{
+ int result;
+ dbgprintf("WCh2MB\n");
+ result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3);
+ dbgprintf("=> %d\n", result);
+ return result;
+}
+long WINAPI expGetVersionExA(OSVERSIONINFOA* c)
+{
+ dbgprintf("GetVersionExA\n");
+ c->dwMajorVersion=4;
+ c->dwMinorVersion=10;
+ c->dwBuildNumber=0x40a07ce;
+ c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS;
+ strcpy(c->szCSDVersion, "Win98");
+ return 1;
+}
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count, long max_count, char* name)
+{
+#warning FIXME
+/* struct sembuf buf[1];
+ int sem=semget(IPC_PRIVATE,1,IPC_CREAT);
+ if(sem==-1)
+ {
+ printf("semget() failed\n");
+ return (HANDLE)-1;
+ }
+ buf[0].sem_num=0;
+ printf("%s\n", name);
+ printf("Init count %d, max count %d\n", init_count, max_count);
+ buf[0].sem_op=-max_count+init_count;
+ buf[0].sem_flg=0;
+ if(semop(sem, &buf, 1)<0)
+ {
+ printf("semop() failed\n");
+ }
+ return sem;
+*/
+ void* z;
+ dbgprintf("CreateSemaphoreA\n");
+ z=my_mreq(24, 0);
+ pthread_mutex_init(z, NULL);
+ return (HANDLE)z;
+}
+
+long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count)
+{
+// The state of a semaphore object is signaled when its count
+// is greater than zero and nonsignaled when its count is equal to zero
+// Each time a waiting thread is released because of the semaphore's signaled
+// state, the count of the semaphore is decreased by one.
+ struct sembuf buf[1];
+ dbgprintf("ReleaseSemaphore\n");
+ dbgprintf("WARNING: Unsupported call: ReleaseSemaphoreA\n");
+/* if(hsem==-1)return 0;
+ buf[0].sem_num=0;
+ buf[0].sem_op=-1;
+ buf[0].sem_flg=0;
+ if(semop(hsem, &buf, 1)<0)
+ {
+ printf("ReleaseSemaphore: semop() failed\n");
+ }*/
+
+ return 1;//zero on error
+}
+
+
+long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
+{
+ dbgprintf("RegOpenKeyExA(%d,%s)\n", key, subkey);
+ return RegOpenKeyExA(key, subkey, reserved, access, newkey);
+}
+long WINAPI expRegCloseKey(long key)
+{
+ dbgprintf("RegCloseKey()\n");
+ return RegCloseKey(key);
+}
+long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
+{
+ dbgprintf("RegQueryValueExA()\n");
+ return RegQueryValueExA(key, value, reserved, type, data, count);
+}
+long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved,
+ void* classs, long options, long security,
+ void* sec_attr, int* newkey, int* status)
+{
+ dbgprintf("RegCreateKeyExA()\n");
+ return RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status);
+}
+long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size)
+{
+ dbgprintf("RegSetValueExA()\n");
+ return RegSetValueExA(key, name, v1, v2, data, size);
+}
+
+long WINAPI expRegOpenKeyA (
+long hKey,
+ LPCSTR lpSubKey,
+ int* phkResult
+){
+ return RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult);
+}
+
+long WINAPI expQueryPerformanceCounter(long long* z)
+{
+ dbgprintf("QueryPerformanceCounter()\n");
+ longcount(z);
+ return 1;
+}
+
+static double old_freq()
+{
+ int i=time(NULL);
+ int x,y;
+ while(i==time(NULL));
+ x=localcount();
+ i++;
+ while(i==time(NULL));
+ y=localcount();
+ return (double)(y-x)/1000.;
+}
+static double CPU_Freq()
+{
+#ifdef USE_TSC
+ FILE *f = fopen ("/proc/cpuinfo", "r");
+ char line[200];
+ char model[200]="unknown";
+ char flags[500]="";
+ char *s,*value;
+ double freq=-1;
+
+ if (!f)
+ {
+ printf("Can't open /proc/cpuinfo for reading\n");
+ return old_freq();
+ }
+ while (fgets(line,200,f)!=NULL)
+ {
+ /* NOTE: the ':' is the only character we can rely on */
+ if (!(value = strchr(line,':')))
+ continue;
+ /* terminate the valuename */
+ *value++ = '\0';
+ /* skip any leading spaces */
+ while (*value==' ') value++;
+ if ((s=strchr(value,'\n')))
+ *s='\0';
+
+ if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz")))
+ {
+ sscanf(value, "%lf", &freq);
+ freq*=1000;
+ break;
+ }
+ continue;
+
+ }
+ fclose(f);
+ if(freq<0)return old_freq();
+ return freq;
+#else
+ return old_freq();
+#endif
+}
+
+long WINAPI expQueryPerformanceFrequency(long long* z)
+{
+ dbgprintf("QueryPerformanceFrequency()\n");
+ *z=(long long)CPU_Freq();
+ return 1;
+}
+long WINAPI exptimeGetTime()
+{
+ struct timeval t;
+ dbgprintf("timeGetTime()\n");
+ gettimeofday(&t, 0);
+ return 1000*t.tv_sec+t.tv_usec/1000;
+}
+void* WINAPI expLocalHandle(void* v)
+{
+ dbgprintf("LocalHandle\n");
+ return v;
+}
+void* WINAPI expGlobalHandle(void* v)
+{
+ dbgprintf("GlobalHandle\n");
+ return v;
+}
+int WINAPI expGlobalUnlock(void* v)
+{
+ dbgprintf("GlobalUnlock\n");
+ return 1;
+}
+//
+void* WINAPI expGlobalFree(void* v)
+{
+ dbgprintf("GlobalFree(%X)\n", v);
+ my_release(v);
+ return 0;
+}
+
+int WINAPI expLocalUnlock(void* v)
+{
+ dbgprintf("LocalUnlock\n");
+ return 1;
+}
+//
+void* WINAPI expLocalFree(void* v)
+{
+ dbgprintf("LocalFree(%X)\n", v);
+ my_release(v);
+ return 0;
+}
+
+HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type)
+{
+ dbgprintf("FindResourceA\n");
+ return FindResourceA(module, name, type);
+}
+HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res)
+{
+ dbgprintf("LoadResource\n");
+ return LoadResource(module, res);;
+}
+void* WINAPI expLockResource(long res)
+{
+ dbgprintf("LockResource\n");
+ return LockResource(res);
+}
+int WINAPI expFreeResource(long res)
+{
+ dbgprintf("FreeResource\n");
+ return FreeResource(res);
+}
+//bool fun(HANDLE)
+//!0 on success
+int WINAPI expCloseHandle(long v1)
+{
+ dbgprintf("CloseHandle\n");
+ return 1;
+}
+
+const char* WINAPI expGetCommandLineA()
+{
+ dbgprintf("GetCommandLine\n");
+ return "c:\\aviplay.exe";
+}
+LPWSTR WINAPI expGetEnvironmentStringsW()
+{
+ static wchar_t envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
+ dbgprintf("GetEnvStringsW\n");
+ return (LPWSTR)envs;
+}
+
+int WINAPI expFreeEnvironmentStringsW(short* strings)
+{
+ dbgprintf("FreeEnvStringsW\n");
+ return 1;
+}
+LPCSTR WINAPI expGetEnvironmentStrings()
+{
+ dbgprintf("GetEnvStrings\n");
+ return "\0\0";
+}
+
+int WINAPI expGetStartupInfoA(STARTUPINFOA *s)
+{
+ int i;
+ dbgprintf("GetStartupInfoA\n");
+/*
+ for(i=0; i<sizeof(STARTUPINFOA)/4; i++)
+ ((int*)s)[i]=i+0x200;
+*/
+ memset(s, 0, sizeof(*s));
+ s->cb=sizeof(*s);
+ s->lpReserved="qwe";
+ s->lpDesktop="rty";
+ s->lpTitle="uio";
+ s->dwX=s->dwY=0;
+ s->dwXSize=s->dwYSize=200;
+ s->dwFlags=s->wShowWindow=0;
+ return 1;
+}
+
+int WINAPI expGetStdHandle(int z)
+{
+ dbgprintf("GetStdHandle\n");
+ dbgprintf("WARNING: Unsupported call: GetStdHandle\n");
+ return 1234;
+}
+int WINAPI expGetFileType(int handle)
+{
+ dbgprintf("GetFileType\n");
+ dbgprintf("WARNING: Unsupported call: GetFileType\n");
+ return 5678;
+}
+int WINAPI expSetHandleCount(int count)
+{
+ dbgprintf("SetHandleCount\n");
+ return 1;
+}
+int WINAPI expGetACP()
+{
+ dbgprintf("GetACP\n");
+ dbgprintf("WARNING: Unsupported call: GetACP\n");
+ return 0;
+}
+extern WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m);
+int WINAPI expGetModuleFileNameA(int module, char* s, int len)
+{
+ WINE_MODREF *mr;
+ dbgprintf("GetModuleFileNameA\n");
+// printf("File name of module %X requested\n", module);
+ if(s==0)
+ return 0;
+ if(len<35)
+ return 0;
+ strcpy(s, "c:\\windows\\system\\");
+ mr=MODULE32_LookupHMODULE(module);
+ if(mr==0)//oops
+ {
+ strcat(s, "aviplay.dll");
+ return 1;
+ }
+ if(strrchr(mr->filename, '/')==NULL)
+ strcat(s, mr->filename);
+ else
+ strcat(s, strrchr(mr->filename, '/')+1);
+ return 1;
+}
+
+int WINAPI expSetUnhandledExceptionFilter(void* filter)
+{
+ dbgprintf("SetUnhandledExcFilter\n");
+ return 1;//unsupported and probably won't ever be supported
+}
+extern char* def_path;
+
+int WINAPI expLoadLibraryA(char* name)
+{
+ char qq[256];
+ dbgprintf("LoadLibraryA\n");
+ printf("They want library %s\n", name);
+ strcpy(qq, def_path);
+ strcat(qq, "/");
+ strcat(qq, name);
+ return LoadLibraryA(qq);
+}
+int WINAPI expFreeLibrary(int module)
+{
+ dbgprintf("FreeLibrary\n");
+ return FreeLibrary(module);
+}
+void* WINAPI expGetProcAddress(HMODULE mod, char* name)
+{
+ dbgprintf("GetProcAddress\n");
+ return GetProcAddress(mod, name);
+}
+
+long WINAPI expCreateFileMappingA(int hFile, void* lpAttr,
+ long flProtect, long dwMaxHigh, long dwMaxLow, const char* name)
+{
+ dbgprintf("CreateFileMappingA\n");
+ return CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name);
+}
+
+long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name)
+{
+ dbgprintf("OpenFileMappingA\n");
+ return OpenFileMappingA(hFile, hz, name);
+}
+
+void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh, DWORD offLow, DWORD size)
+{
+ dbgprintf("MapViewOfFile(%d, %x, %x, %x, %x)\n",
+ file,mode,offHigh,offLow,size);
+ return (char*)file+offLow;
+}
+
+void* WINAPI expUnmapViewOfFile(void* view)
+{
+ dbgprintf("UnmapViewOfFile()\n");
+ return 0;
+}
+
+void* WINAPI expSleep(int time)
+{
+ dbgprintf("Sleep(%d)\n", time);
+ usleep(time);
+ return 0;
+}
+ // why does IV32 codec want to call this? I don't know ...
+void* WINAPI expCreateCompatibleDC(int hdc)
+{
+ dbgprintf("CreateCompatibleDC(%d)\n", hdc);
+ return (void*)129;
+}
+
+int WINAPI expGetDeviceCaps(int hdc, int unk)
+{
+ dbgprintf("GetDeviceCaps(%d, %d)\n", hdc, unk);
+ return 0;
+}
+
+WIN_BOOL WINAPI expDeleteDC(int hdc)
+{
+ dbgprintf("DeleteDC(%d)\n", hdc);
+ return 0;
+}
+
+int expwsprintfA(char* string, char* format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ dbgprintf("wsprintfA\n");
+ return vsprintf(string, format, va);
+}
+
+int WINAPI expGetPrivateProfileIntA(const char* appname, const char* keyname, int default_value, const char* filename)
+{
+ int size=255;
+ char buffer[256];
+ char* fullname;
+ int result;
+
+ buffer[255]=0;
+ dbgprintf("GetPrivateProfileIntA(%s, %s, %s)\n", appname, keyname, filename );
+ if(!(appname && keyname && filename) ) return default_value;
+ fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
+ strcpy(fullname, "Software\\IniFileMapping\\");
+ strcat(fullname, appname);
+ strcat(fullname, "\\");
+ strcat(fullname, keyname);
+ strcat(fullname, "\\");
+ strcat(fullname, filename);
+ result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size);
+ if((size>=0)&&(size<256))
+ buffer[size]=0;
+// printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
+ free(fullname);
+ if(result)
+ return default_value;
+ else
+ return atoi(buffer);
+}
+int WINAPI expGetPrivateProfileStringA(const char* appname, const char* keyname,
+ const char* def_val, char* dest, unsigned int len, const char* filename)
+{
+ int result;
+ int size;
+ char* fullname;
+ dbgprintf("GetPrivateProfileStringA(%s, %s, %s, %X, %X, %s)\n", appname, keyname, def_val, dest, len, filename );
+ if(!(appname && keyname && filename) ) return 0;
+ fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
+ strcpy(fullname, "Software\\IniFileMapping\\");
+ strcat(fullname, appname);
+ strcat(fullname, "\\");
+ strcat(fullname, keyname);
+ strcat(fullname, "\\");
+ strcat(fullname, filename);
+ size=len;
+ result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size);
+// printf("GetPrivateProfileStringA(%s, %s, %s, %X, %X, %s)\n", appname, keyname, def_val, dest, len, filename );
+ free(fullname);
+ if(!result)
+ return size;
+ strncpy(dest, def_val, size);
+ return size;
+}
+int WINAPI expWritePrivateProfileStringA(const char* appname, const char* keyname,
+ const char* string, const char* filename)
+{
+ int size=256;
+ char* fullname;
+ dbgprintf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
+ if(!(appname && keyname && filename) ) return -1;
+ fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
+ strcpy(fullname, "Software\\IniFileMapping\\");
+ strcat(fullname, appname);
+ strcat(fullname, "\\");
+ strcat(fullname, keyname);
+ strcat(fullname, "\\");
+ strcat(fullname, filename);
+ RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string));
+// printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
+// printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
+ free(fullname);
+ return 0;
+}
+
+unsigned int _GetPrivateProfileIntA(const char* appname, const char* keyname, INT default_value, const char* filename)
+{
+ return expGetPrivateProfileIntA(appname, keyname, default_value, filename);
+}
+int _GetPrivateProfileStringA(const char* appname, const char* keyname,
+ const char* def_val, char* dest, unsigned int len, const char* filename)
+{
+ return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename);
+}
+int _WritePrivateProfileStringA(const char* appname, const char* keyname,
+ const char* string, const char* filename)
+{
+ return expWritePrivateProfileStringA(appname, keyname, string, filename);
+}
+
+
+int WINAPI expDefDriverProc(int _private, int id, int msg, int arg1, int arg2)
+{
+ printf("Called DefDriverProc(%X)\n", msg);
+ return 0;
+}
+
+int WINAPI expSizeofResource(int v1, int v2)
+{
+ dbgprintf("SizeofResource()\n");
+ return SizeofResource(v1, v2);
+}
+
+int WINAPI expGetLastError()
+{
+ dbgprintf("GetLastError()\n");
+ return GetLastError();
+}
+
+void WINAPI expSetLastError(int error)
+{
+ dbgprintf("SetLastError()\n");
+ SetLastError(error);
+}
+
+char* expstrrchr(char* string, int value)
+{
+ return strrchr(string, value);
+}
+
+char* expstrchr(char* string, int value)
+{
+ return strchr(string, value);
+}
+
+int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle)
+{
+ printf("GetFileVersionInfoSizeA(%s,0x%X)\n", name, lpHandle);
+ return 0;
+}
+
+int WINAPI expIsBadStringPtrW(const short* string, int nchars)
+{
+ if(string==0)return 1;
+ return 0;
+}
+extern long WINAPI InterlockedExchangeAdd( long* dest, long incr )
+{
+ long ret;
+ __asm__ __volatile__( "lock; xaddl %0,(%1)"
+ : "=r" (ret) : "r" (dest), "0" (incr) : "memory" );
+ return ret;
+}
+
+extern long WINAPI expInterlockedIncrement( long* dest )
+{
+ return InterlockedExchangeAdd( dest, 1 ) + 1;
+}
+extern long WINAPI expInterlockedDecrement( long* dest )
+{
+ return InterlockedExchangeAdd( dest, -1 ) - 1;
+}
+
+extern void WINAPI expOutputDebugStringA( const char* string )
+{
+ fprintf(stderr, "DEBUG: %s\n", string);
+}
+
+int WINAPI expGetDC(int hwnd)
+{
+ return 0;
+}
+
+int WINAPI expGetDesktopWindow()
+{
+ return 0;
+}
+
+int WINAPI expReleaseDC(int hwnd, int hdc)
+{
+ return 0;
+}
+
+int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe)
+{
+ return 0;
+}
+/*
+typedef struct _TIME_ZONE_INFORMATION {
+ long Bias;
+ char StandardName[32];
+ SYSTEMTIME StandardDate;
+ long StandardBias;
+ char DaylightName[32];
+ SYSTEMTIME DaylightDate;
+ long DaylightBias;
+} TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
+*/
+
+int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
+{
+ memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION));
+ return 0;
+}
+
+void WINAPI expGetLocalTime(SYSTEMTIME* systime)
+{
+ time_t local_time;
+ struct tm *local_tm;
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ local_time=tv.tv_sec;
+ local_tm=localtime(&local_time);
+
+ systime->wYear = local_tm->tm_year + 1900;
+ systime->wMonth = local_tm->tm_mon + 1;
+ systime->wDayOfWeek = local_tm->tm_wday;
+ systime->wDay = local_tm->tm_mday;
+ systime->wHour = local_tm->tm_hour;
+ systime->wMinute = local_tm->tm_min;
+ systime->wSecond = local_tm->tm_sec;
+ systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
+}
+
+int WINAPI expGetSystemTime(SYSTEMTIME* systime)
+{
+ time_t local_time;
+ struct tm *local_tm;
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ local_time=tv.tv_sec;
+ local_tm=gmtime(&local_time);
+
+ systime->wYear = local_tm->tm_year + 1900;
+ systime->wMonth = local_tm->tm_mon + 1;
+ systime->wDayOfWeek = local_tm->tm_wday;
+ systime->wDay = local_tm->tm_mday;
+ systime->wHour = local_tm->tm_hour;
+ systime->wMinute = local_tm->tm_min;
+ systime->wSecond = local_tm->tm_sec;
+ systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
+
+}
+
+int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size)
+{
+ dbgprintf("GetEnvironmentVariableA\n");
+ printf("%s %x %x\n", name, field, size);
+ if(field)field[0]=0;
+ return 0;
+}
+
+
+//HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName, LPARAM lParam2);
+//HDRVR WINAPI expOpenDriverW(LPCWSTR szDriverName, LPCWSTR szSectionName, LPARAM lParam2);
+HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName, LPARAM lParam2){
+ printf("winmm32::OpenDriver() called\n");
+ return NULL;
+}
+
+
+struct exports
+{
+ char name[64];
+ int id;
+ void* func;
+};
+struct libs
+{
+ char name[64];
+ int length;
+ struct exports* exps;
+};
+
+#define FF(X,Y) \
+{#X, Y, (void*)exp##X},
+
+struct exports exp_kernel32[]={
+FF(IsBadWritePtr, 357)
+FF(IsBadReadPtr, 354)
+FF(IsBadStringPtrW, -1)
+FF(DisableThreadLibraryCalls, -1)
+FF(CreateThread, -1)
+FF(CreateEventA, -1)
+FF(SetEvent, -1)
+FF(ResetEvent, -1)
+FF(WaitForSingleObject, -1)
+FF(GetSystemInfo, -1)
+FF(GetVersion, 332)
+FF(HeapCreate, 461)
+FF(HeapAlloc, -1)
+FF(HeapDestroy, -1)
+FF(HeapFree, -1)
+FF(HeapSize, -1)
+FF(GetProcessHeap, -1)
+FF(VirtualAlloc, -1)
+FF(VirtualFree, -1)
+FF(InitializeCriticalSection, -1)
+FF(EnterCriticalSection, -1)
+FF(LeaveCriticalSection, -1)
+FF(DeleteCriticalSection, -1)
+FF(TlsAlloc, -1)
+FF(TlsFree, -1)
+FF(TlsGetValue, -1)
+FF(TlsSetValue, -1)
+FF(GetCurrentThreadId, -1)
+FF(LocalAlloc, -1)
+FF(LocalLock, -1)
+FF(GlobalAlloc, -1)
+FF(GlobalLock, -1)
+FF(MultiByteToWideChar, 427)
+FF(WideCharToMultiByte, -1)
+FF(GetVersionExA, -1)
+FF(CreateSemaphoreA, -1)
+FF(QueryPerformanceCounter, -1)
+FF(QueryPerformanceFrequency, -1)
+FF(LocalHandle, -1)
+FF(LocalUnlock, -1)
+FF(LocalFree, -1)
+FF(GlobalHandle, -1)
+FF(GlobalUnlock, -1)
+FF(GlobalFree, -1)
+FF(LoadResource, -1)
+FF(ReleaseSemaphore, -1)
+FF(FindResourceA, -1)
+FF(LockResource, -1)
+FF(FreeResource, -1)
+FF(SizeofResource, -1)
+FF(CloseHandle, -1)
+FF(GetCommandLineA, -1)
+FF(GetEnvironmentStringsW, -1)
+FF(FreeEnvironmentStringsW, -1)
+FF(GetEnvironmentStrings, -1)
+FF(GetStartupInfoA, -1)
+FF(GetStdHandle, -1)
+FF(GetFileType, -1)
+FF(SetHandleCount, -1)
+FF(GetACP, -1)
+FF(GetModuleFileNameA, -1)
+FF(SetUnhandledExceptionFilter, -1)
+FF(LoadLibraryA, -1)
+FF(GetProcAddress, -1)
+FF(FreeLibrary, -1)
+FF(CreateFileMappingA, -1)
+FF(OpenFileMappingA, -1)
+FF(MapViewOfFile, -1)
+FF(UnmapViewOfFile, -1)
+FF(Sleep, -1)
+FF(GetModuleHandleA, -1)
+FF(GetPrivateProfileIntA, -1)
+FF(GetPrivateProfileStringA, -1)
+FF(WritePrivateProfileStringA, -1)
+FF(GetLastError, -1)
+FF(SetLastError, -1)
+FF(InterlockedIncrement, -1)
+FF(InterlockedDecrement, -1)
+FF(GetTimeZoneInformation, -1)
+FF(OutputDebugStringA, -1)
+FF(GetLocalTime, -1)
+FF(GetSystemTime, -1)
+FF(GetEnvironmentVariableA, -1)
+};
+
+struct exports exp_msvcrt[]={
+FF(malloc, -1)
+FF(_initterm, -1)
+FF(free, -1)
+{"??3@YAXPAX@Z", -1, expdelete},
+{"??2@YAPAXI@Z", -1, expnew},
+FF(strrchr, -1)
+FF(strchr, -1)
+};
+struct exports exp_winmm[]={
+FF(GetDriverModuleHandle, -1)
+FF(timeGetTime, -1)
+FF(DefDriverProc, -1)
+FF(OpenDriver, -1)
+};
+struct exports exp_user32[]={
+FF(LoadStringA, -1)
+FF(wsprintfA, -1)
+FF(GetDC, -1)
+FF(GetDesktopWindow, -1)
+FF(ReleaseDC, -1)
+};
+struct exports exp_advapi32[]={
+FF(RegOpenKeyA, -1)
+FF(RegOpenKeyExA, -1)
+FF(RegCreateKeyExA, -1)
+FF(RegQueryValueExA, -1)
+FF(RegSetValueExA, -1)
+FF(RegCloseKey, -1)
+};
+struct exports exp_gdi32[]={
+FF(CreateCompatibleDC, -1)
+FF(GetDeviceCaps, -1)
+FF(DeleteDC, -1)
+FF(GetSystemPaletteEntries, -1)
+};
+struct exports exp_version[]={
+FF(GetFileVersionInfoSizeA, -1)
+};
+#define LL(X) \
+{#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
+
+struct libs libraries[]={
+LL(kernel32)
+LL(msvcrt)
+LL(winmm)
+LL(user32)
+LL(advapi32)
+LL(gdi32)
+LL(version)
+};
+
+void* LookupExternal(const char* library, int ordinal)
+{
+ char* answ;
+ int i,j;
+ if(library==0)
+ {
+ printf("ERROR: library=0\n");
+ return (void*)ext_unknown;
+ }
+ printf("External func %s:%d\n", library, ordinal);
+// printf("%x %x\n", &unk_exp1, &unk_exp2);
+
+ for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
+ {
+ if(strcasecmp(library, libraries[i].name))
+ continue;
+ for(j=0; j<libraries[i].length; j++)
+ {
+ if(ordinal!=libraries[i].exps[j].id)
+ continue;
+ printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
+ return libraries[i].exps[j].func;
+ }
+ }
+ if(pos>150)return 0;
+ answ=(char*)extcode+pos*0x64;
+ memcpy(answ, &unk_exp1, 0x64);
+ *(int*)(answ+9)=pos;
+ *(int*)(answ+47)-=((int)answ-(int)&unk_exp1);
+ sprintf(export_names[pos], "%s:%d", library, ordinal);
+ pos++;
+ return (void*)answ;
+}
+
+void* LookupExternalByName(const char* library, const char* name)
+{
+ char* answ;
+ int i,j;
+// return (void*)ext_unknown;
+ if(library==0)
+ {
+ printf("ERROR: library=0\n");
+ return (void*)ext_unknown;
+ }
+ if(name==0)
+ {
+ printf("ERROR: name=0\n");
+ return (void*)ext_unknown;
+ }
+// printf("External func %s:%s\n", library, name);
+ for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
+ {
+ if(strcasecmp(library, libraries[i].name))
+ continue;
+ for(j=0; j<libraries[i].length; j++)
+ {
+ if(strcmp(name, libraries[i].exps[j].name))
+ continue;
+// printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
+ return libraries[i].exps[j].func;
+ }
+ }// printf("%x %x\n", &unk_exp1, &unk_exp2);
+ //printf("Missing (%d) External func %s:%s\n", pos, library, name);
+ if(pos>150){
+// printf("Warning! Too many missing externals!\n");
+ return 0;
+ }
+ strcpy(export_names[pos], name);
+ answ=(char*)extcode+pos*0x64;
+ memcpy(answ, &unk_exp1, 0x64);
+ *(int*)(answ+9)=pos;
+ *(int*)(answ+47)-=((int)answ-(int)&unk_exp1);
+ pos++;
+ return (void*)answ;
+// memcpy(extcode, &unk_exp1, 0x64);
+// *(int*)(extcode+52)-=((int)extcode-(int)&unk_exp1);
+// return (void*)extcode;
+// printf("Unknown func %s:%s\n", library, name);
+// return (void*)ext_unknown;
+}
+
diff --git a/src/libw32dll/win32.h b/src/libw32dll/win32.h
new file mode 100644
index 000000000..327cfb298
--- /dev/null
+++ b/src/libw32dll/win32.h
@@ -0,0 +1 @@
+int ext_unknown();
diff --git a/src/libw32dll/wine/Makefile.am b/src/libw32dll/wine/Makefile.am
new file mode 100644
index 000000000..bbf9d835c
--- /dev/null
+++ b/src/libw32dll/wine/Makefile.am
@@ -0,0 +1,16 @@
+noinst_HEADERS = avifmt.h elfdll.h msacm.h pshpack1.h winbase.h \
+ winnt.h basetsd.h heap.h msacmdrv.h pshpack2.h\
+ windef.h winreg.h config.h ldt.h ntdef.h \
+ pshpack4.h windows.h winuser.h debugtools.h mmreg.h \
+ pe_image.h pshpack8.h winerror.h driver.h module.h \
+ poppack.h vfw.h winestring.h
+
+debug:
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/libw32dll/wine/avifmt.h b/src/libw32dll/wine/avifmt.h
new file mode 100644
index 000000000..904d55bca
--- /dev/null
+++ b/src/libw32dll/wine/avifmt.h
@@ -0,0 +1,244 @@
+/****************************************************************************
+ *
+ * AVIFMT - AVI file format definitions
+ *
+ ****************************************************************************/
+#ifndef AVIFMT
+#define AVIFMT
+
+#ifndef NOAVIFMT
+
+#ifndef __WINE_WINDEF_H
+#include "windef.h"
+#endif
+
+#ifndef __WINE_MMSYSTEM_H
+#ifndef __WINE_MSACM_H
+typedef DWORD FOURCC;
+#endif
+#endif
+
+
+#ifdef _MSC_VER
+#pragma warning(disable:4200)
+#endif
+
+/* The following is a short description of the AVI file format. Please
+ * see the accompanying documentation for a full explanation.
+ *
+ * An AVI file is the following RIFF form:
+ *
+ * RIFF('AVI'
+ * LIST('hdrl'
+ * avih(<MainAVIHeader>)
+ * LIST ('strl'
+ * strh(<Stream header>)
+ * strf(<Stream format>)
+ * ... additional header data
+ * LIST('movi'
+ * { LIST('rec'
+ * SubChunk...
+ * )
+ * | SubChunk } ....
+ * )
+ * [ <AVIIndex> ]
+ * )
+ *
+ * The main file header specifies how many streams are present. For
+ * each one, there must be a stream header chunk and a stream format
+ * chunk, enlosed in a 'strl' LIST chunk. The 'strf' chunk contains
+ * type-specific format information; for a video stream, this should
+ * be a BITMAPINFO structure, including palette. For an audio stream,
+ * this should be a WAVEFORMAT (or PCMWAVEFORMAT) structure.
+ *
+ * The actual data is contained in subchunks within the 'movi' LIST
+ * chunk. The first two characters of each data chunk are the
+ * stream number with which that data is associated.
+ *
+ * Some defined chunk types:
+ * Video Streams:
+ * ##db: RGB DIB bits
+ * ##dc: RLE8 compressed DIB bits
+ * ##pc: Palette Change
+ *
+ * Audio Streams:
+ * ##wb: waveform audio bytes
+ *
+ * The grouping into LIST 'rec' chunks implies only that the contents of
+ * the chunk should be read into memory at the same time. This
+ * grouping is used for files specifically intended to be played from
+ * CD-ROM.
+ *
+ * The index chunk at the end of the file should contain one entry for
+ * each data chunk in the file.
+ *
+ * Limitations for the current software:
+ * Only one video stream and one audio stream are allowed.
+ * The streams must start at the beginning of the file.
+ *
+ *
+ * To register codec types please obtain a copy of the Multimedia
+ * Developer Registration Kit from:
+ *
+ * Microsoft Corporation
+ * Multimedia Systems Group
+ * Product Marketing
+ * One Microsoft Way
+ * Redmond, WA 98052-6399
+ *
+ */
+
+#ifndef mmioFOURCC
+#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
+ ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \
+ ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) )
+#endif
+
+/* Macro to make a TWOCC out of two characters */
+#ifndef aviTWOCC
+#define aviTWOCC(ch0, ch1) ((WORD)(BYTE)(ch0) | ((WORD)(BYTE)(ch1) << 8))
+#endif
+
+typedef WORD TWOCC;
+
+/* form types, list types, and chunk types */
+#define formtypeAVI mmioFOURCC('A', 'V', 'I', ' ')
+#define listtypeAVIHEADER mmioFOURCC('h', 'd', 'r', 'l')
+#define ckidAVIMAINHDR mmioFOURCC('a', 'v', 'i', 'h')
+#define listtypeSTREAMHEADER mmioFOURCC('s', 't', 'r', 'l')
+#define ckidSTREAMHEADER mmioFOURCC('s', 't', 'r', 'h')
+#define ckidSTREAMFORMAT mmioFOURCC('s', 't', 'r', 'f')
+#define ckidSTREAMHANDLERDATA mmioFOURCC('s', 't', 'r', 'd')
+#define ckidSTREAMNAME mmioFOURCC('s', 't', 'r', 'n')
+
+#define listtypeAVIMOVIE mmioFOURCC('m', 'o', 'v', 'i')
+#define listtypeAVIRECORD mmioFOURCC('r', 'e', 'c', ' ')
+
+#define ckidAVINEWINDEX mmioFOURCC('i', 'd', 'x', '1')
+
+/*
+** Stream types for the <fccType> field of the stream header.
+*/
+#define streamtypeVIDEO mmioFOURCC('v', 'i', 'd', 's')
+#define streamtypeAUDIO mmioFOURCC('a', 'u', 'd', 's')
+#define streamtypeMIDI mmioFOURCC('m', 'i', 'd', 's')
+#define streamtypeTEXT mmioFOURCC('t', 'x', 't', 's')
+
+/* Basic chunk types */
+#define cktypeDIBbits aviTWOCC('d', 'b')
+#define cktypeDIBcompressed aviTWOCC('d', 'c')
+#define cktypePALchange aviTWOCC('p', 'c')
+#define cktypeWAVEbytes aviTWOCC('w', 'b')
+
+/* Chunk id to use for extra chunks for padding. */
+#define ckidAVIPADDING mmioFOURCC('J', 'U', 'N', 'K')
+
+/*
+** Useful macros
+**
+** Warning: These are nasty macro, and MS C 6.0 compiles some of them
+** incorrectly if optimizations are on. Ack.
+*/
+
+/* Macro to get stream number out of a FOURCC ckid */
+#define FromHex(n) (((n) >= 'A') ? ((n) + 10 - 'A') : ((n) - '0'))
+#define StreamFromFOURCC(fcc) ((WORD) ((FromHex(LOBYTE(LOWORD(fcc))) << 4) + \
+ (FromHex(HIBYTE(LOWORD(fcc))))))
+
+/* Macro to get TWOCC chunk type out of a FOURCC ckid */
+#define TWOCCFromFOURCC(fcc) HIWORD(fcc)
+
+/* Macro to make a ckid for a chunk out of a TWOCC and a stream number
+** from 0-255.
+*/
+#define ToHex(n) ((BYTE) (((n) > 9) ? ((n) - 10 + 'A') : ((n) + '0')))
+#define MAKEAVICKID(tcc, stream) \
+ MAKELONG((ToHex((stream) & 0x0f) << 8) | \
+ (ToHex(((stream) & 0xf0) >> 4)), tcc)
+
+/*
+** Main AVI File Header
+*/
+
+/* flags for use in <dwFlags> in AVIFileHdr */
+#define AVIF_HASINDEX 0x00000010 // Index at end of file?
+#define AVIF_MUSTUSEINDEX 0x00000020
+#define AVIF_ISINTERLEAVED 0x00000100
+#define AVIF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames?
+#define AVIF_WASCAPTUREFILE 0x00010000
+#define AVIF_COPYRIGHTED 0x00020000
+
+/* The AVI File Header LIST chunk should be padded to this size */
+#define AVI_HEADERSIZE 2048 // size of AVI header list
+
+typedef struct
+{
+ DWORD dwMicroSecPerFrame; // frame display rate (or 0L)
+ DWORD dwMaxBytesPerSec; // max. transfer rate
+ DWORD dwPaddingGranularity; // pad to multiples of this
+ // size; normally 2K.
+ DWORD dwFlags; // the ever-present flags
+ DWORD dwTotalFrames; // # frames in file
+ DWORD dwInitialFrames;
+ DWORD dwStreams;
+ DWORD dwSuggestedBufferSize;
+
+ DWORD dwWidth;
+ DWORD dwHeight;
+
+ DWORD dwReserved[4];
+} MainAVIHeader;
+
+/*
+** Stream header
+*/
+
+#define AVISF_DISABLED 0x00000001
+
+#define AVISF_VIDEO_PALCHANGES 0x00010000
+
+
+typedef struct {
+ FOURCC fccType;
+ FOURCC fccHandler;
+ DWORD dwFlags; /* Contains AVITF_* flags */
+ WORD wPriority;
+ WORD wLanguage;
+ DWORD dwInitialFrames;
+ DWORD dwScale;
+ DWORD dwRate; /* dwRate / dwScale == samples/second */
+ DWORD dwStart;
+ DWORD dwLength; /* In units above... */
+ DWORD dwSuggestedBufferSize;
+ DWORD dwQuality;
+ DWORD dwSampleSize;
+ RECT rcFrame;
+} AVIStreamHeader;
+
+/* Flags for index */
+#define AVIIF_LIST 0x00000001L // chunk is a 'LIST'
+#define AVIIF_KEYFRAME 0x00000010L // this frame is a key frame.
+
+#define AVIIF_NOTIME 0x00000100L // this frame doesn't take any time
+#define AVIIF_COMPUSE 0x0FFF0000L // these bits are for compressor use
+
+#define FOURCC_RIFF mmioFOURCC('R', 'I', 'F', 'F')
+#define FOURCC_LIST mmioFOURCC('L', 'I', 'S', 'T')
+
+typedef struct
+{
+ DWORD ckid;
+ DWORD dwFlags;
+ DWORD dwChunkOffset; // Position of chunk
+ DWORD dwChunkLength; // Length of chunk
+} AVIINDEXENTRY;
+
+#define AVISTREAMREAD_CONVENIENT (-1L)
+
+/*
+** Palette change chunk
+**
+** Used in video streams.
+*/
+#endif /* NOAVIFMT */
+#endif
diff --git a/src/libw32dll/wine/basetsd.h b/src/libw32dll/wine/basetsd.h
new file mode 100644
index 000000000..7b5d3aba9
--- /dev/null
+++ b/src/libw32dll/wine/basetsd.h
@@ -0,0 +1,145 @@
+/*
+ * Compilers that uses ILP32, LP64 or P64 type models
+ * for both Win32 and Win64 are supported by this file.
+ */
+
+#ifndef __WINE_BASETSD_H
+#define __WINE_BASETSD_H
+
+#ifdef __WINE__
+#include "config.h"
+#endif /* defined(__WINE__) */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+/*
+ * Win32 was easy to implement under Unix since most (all?) 32-bit
+ * Unices uses the same type model (ILP32) as Win32, where int, long
+ * and pointer are 32-bit.
+ *
+ * Win64, however, will cause some problems when implemented under Unix.
+ * Linux/{Alpha, Sparc64} and most (all?) other 64-bit Unices uses
+ * the LP64 type model where int is 32-bit and long and pointer are
+ * 64-bit. Win64 on the other hand uses the P64 (sometimes called LLP64)
+ * type model where int and long are 32 bit and pointer is 64-bit.
+ */
+
+/* Type model indepent typedefs */
+
+typedef char __int8;
+typedef unsigned char __uint8;
+
+typedef short __int16;
+typedef unsigned short __uint16;
+
+typedef int __int32;
+typedef unsigned int __uint32;
+
+typedef long long __int64;
+typedef unsigned long long __uint64;
+
+#if defined(_WIN64)
+
+typedef __uint32 __ptr32;
+typedef void *__ptr64;
+
+#else /* FIXME: defined(_WIN32) */
+
+typedef void *__ptr32;
+typedef __uint64 __ptr64;
+
+#endif
+
+/* Always signed and 32 bit wide */
+
+typedef __int32 LONG32;
+//typedef __int32 INT32;
+
+typedef LONG32 *PLONG32;
+//typedef INT32 *PINT32;
+
+/* Always unsigned and 32 bit wide */
+
+typedef __uint32 ULONG32;
+typedef __uint32 DWORD32;
+typedef __uint32 UINT32;
+
+typedef ULONG32 *PULONG32;
+typedef DWORD32 *PDWORD32;
+typedef UINT32 *PUINT32;
+
+/* Always signed and 64 bit wide */
+
+typedef __int64 LONG64;
+typedef __int64 INT64;
+
+typedef LONG64 *PLONG64;
+typedef INT64 *PINT64;
+
+/* Always unsigned and 64 bit wide */
+
+typedef __uint64 ULONG64;
+typedef __uint64 DWORD64;
+typedef __uint64 UINT64;
+
+typedef ULONG64 *PULONG64;
+typedef DWORD64 *PDWORD64;
+typedef UINT64 *PUINT64;
+
+/* Win32 or Win64 dependent typedef/defines. */
+
+#ifdef _WIN64
+
+typedef __int64 INT_PTR, *PINT_PTR;
+typedef __uint64 UINT_PTR, *PUINT_PTR;
+
+#define MAXINT_PTR 0x7fffffffffffffff
+#define MININT_PTR 0x8000000000000000
+#define MAXUINT_PTR 0xffffffffffffffff
+
+typedef __int32 HALF_PTR, *PHALF_PTR;
+typedef __int32 UHALF_PTR, *PUHALF_PTR;
+
+#define MAXHALF_PTR 0x7fffffff
+#define MINHALF_PTR 0x80000000
+#define MAXUHALF_PTR 0xffffffff
+
+typedef __int64 LONG_PTR, *PLONG_PTR;
+typedef __uint64 ULONG_PTR, *PULONG_PTR;
+typedef __uint64 DWORD_PTR, *PDWORD_PTR;
+
+#else /* FIXME: defined(_WIN32) */
+
+typedef __int32 INT_PTR, *PINT_PTR;
+typedef __uint32 UINT_PTR, *PUINT_PTR;
+
+#define MAXINT_PTR 0x7fffffff
+#define MININT_PTR 0x80000000
+#define MAXUINT_PTR 0xffffffff
+
+typedef __int16 HALF_PTR, *PHALF_PTR;
+typedef __uint16 UHALF_PTR, *PUHALF_PTR;
+
+#define MAXUHALF_PTR 0xffff
+#define MAXHALF_PTR 0x7fff
+#define MINHALF_PTR 0x8000
+
+typedef __int32 LONG_PTR, *PLONG_PTR;
+typedef __uint32 ULONG_PTR, *PULONG_PTR;
+typedef __uint32 DWORD_PTR, *PDWORD_PTR;
+
+#endif /* defined(_WIN64) || defined(_WIN32) */
+
+typedef INT_PTR SSIZE_T, *PSSIZE_T;
+typedef UINT_PTR SIZE_T, *PSIZE_T;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* !defined(__WINE_BASETSD_H) */
+
+
+
diff --git a/src/libw32dll/wine/config.h b/src/libw32dll/wine/config.h
new file mode 100644
index 000000000..dc651b3d8
--- /dev/null
+++ b/src/libw32dll/wine/config.h
@@ -0,0 +1,442 @@
+/* include/config.h. Generated automatically by configure. */
+/* include/config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+/* #undef C_ALLOCA */
+
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define if you have alloca, as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#define HAVE_ALLOCA_H 1
+
+/* Define as __inline if that's what the C compiler calls it. */
+/* #undef inline */
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+/* #undef size_t */
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+/* #undef STACK_DIRECTION */
+
+/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+/* #undef STAT_MACROS_BROKEN */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if your processor stores words with the most significant
+ byte first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define if the X Window System is missing or not being used. */
+/* #undef X_DISPLAY_MISSING */
+
+/* Define if symbols declared in assembly code need an underscore prefix */
+/* #undef NEED_UNDERSCORE_PREFIX */
+
+/* Define to use .string instead of .ascii */
+#define HAVE_ASM_STRING 1
+
+/* Define if struct msghdr contains msg_accrights */
+/* #undef HAVE_MSGHDR_ACCRIGHTS */
+
+/* Define if struct sockaddr_un contains sun_len */
+/* #undef HAVE_SOCKADDR_SUN_LEN */
+
+/* Define if you have the Xxf86dga library (-lXxf86dga). */
+#define HAVE_LIBXXF86DGA 1
+
+/* Define if you have the Xxf86dga library version 2.0 (-lXxf86dga). */
+/* #undef HAVE_LIBXXF86DGA2 */
+
+/* Define if you have the X Shm extension */
+#define HAVE_LIBXXSHM 1
+
+/* Define if you have the Xxf86vm library */
+#define HAVE_LIBXXF86VM 1
+
+/* Define if you have the Xpm library */
+#define HAVE_LIBXXPM 1
+
+/* Define if you have the Open Sound system. */
+#define HAVE_OSS 1
+
+/* Define if you have the Open Sound system (MIDI interface). */
+#define HAVE_OSS_MIDI 1
+
+/* Define if X libraries are not reentrant (compiled without -D_REENTRANT). */
+/* #undef NO_REENTRANT_X11 */
+
+/* Define if libc is not reentrant */
+/* #undef NO_REENTRANT_LIBC */
+
+/* Define if libc uses __errno_location for reentrant errno */
+#define HAVE__ERRNO_LOCATION 1
+
+/* Define if libc uses __error for reentrant errno */
+/* #undef HAVE__ERROR */
+
+/* Define if libc uses ___errno for reentrant errno */
+/* #undef HAVE___ERRNO */
+
+/* Define if libc uses __thr_errno for reentrant errno */
+/* #undef HAVE__THR_ERRNO */
+
+/* Define if all debug messages are to be compiled out */
+/* #undef NO_DEBUG_MSGS */
+
+/* Define if TRACE messages are to be compiled out */
+/* #undef NO_TRACE_MSGS */
+
+/* Define if the struct statfs has the member bavail */
+#define STATFS_HAS_BAVAIL 1
+
+/* Define if the struct statfs has the member bfree */
+#define STATFS_HAS_BFREE 1
+
+/* Define if the struct statfs is defined by <sys/vfs.h> */
+#define STATFS_DEFINED_BY_SYS_VFS 1
+
+/* Define if the struct statfs is defined by <sys/statfs.h> */
+#define STATFS_DEFINED_BY_SYS_STATFS 1
+
+/* Define if the struct statfs is defined by <sys/mount.h> */
+/* #undef STATFS_DEFINED_BY_SYS_MOUNT */
+
+/* Define if ncurses have the new resizeterm function */
+#define HAVE_RESIZETERM 1
+
+/* Define if ncurses have the new getbkgd function */
+#define HAVE_GETBKGD 1
+
+/* Define if IPX should use netipx/ipx.h from libc */
+#define HAVE_IPX_GNU 1
+
+/* Define if IPX includes are taken from Linux kernel */
+/* #undef HAVE_IPX_LINUX */
+
+/* Define if Mesa is present on the system or not */
+/* #undef HAVE_LIBMESAGL */
+
+/* Define if the system has dynamic link library support with the dl* API */
+#define HAVE_DL_API 1
+
+/* Define if <linux/joystick.h> defines the Linux 2.2 joystick API */
+#define HAVE_LINUX_22_JOYSTICK_API 1
+
+/* Define if the OpenGL implementation supports the GL_EXT_color_table extension */
+/* #undef HAVE_GL_COLOR_TABLE */
+
+/* Define if the OpenGL implementation supports the GL_EXT_paletted_texture extension */
+/* #undef HAVE_GL_PALETTED_TEXTURE */
+
+/* The number of bytes in a long long. */
+#define SIZEOF_LONG_LONG 8
+
+/* Define if you have the __libc_fork function. */
+/* #undef HAVE___LIBC_FORK */
+
+/* Define if you have the _lwp_create function. */
+/* #undef HAVE__LWP_CREATE */
+
+/* Define if you have the clone function. */
+#define HAVE_CLONE 1
+
+/* Define if you have the connect function. */
+#define HAVE_CONNECT 1
+
+/* Define if you have the dlopen function. */
+/* #undef HAVE_DLOPEN */
+
+/* Define if you have the gethostbyname function. */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define if you have the getnetbyaddr function. */
+#define HAVE_GETNETBYADDR 1
+
+/* Define if you have the getnetbyname function. */
+#define HAVE_GETNETBYNAME 1
+
+/* Define if you have the getpagesize function. */
+#define HAVE_GETPAGESIZE 1
+
+/* Define if you have the getprotobyname function. */
+#define HAVE_GETPROTOBYNAME 1
+
+/* Define if you have the getprotobynumber function. */
+#define HAVE_GETPROTOBYNUMBER 1
+
+/* Define if you have the getservbyport function. */
+#define HAVE_GETSERVBYPORT 1
+
+/* Define if you have the getsockopt function. */
+#define HAVE_GETSOCKOPT 1
+
+/* Define if you have the inet_network function. */
+#define HAVE_INET_NETWORK 1
+
+/* Define if you have the memmove function. */
+#define HAVE_MEMMOVE 1
+
+/* Define if you have the openpty function. */
+#define HAVE_OPENPTY 1
+
+/* Define if you have the rfork function. */
+/* #undef HAVE_RFORK */
+
+/* Define if you have the select function. */
+#define HAVE_SELECT 1
+
+/* Define if you have the sendmsg function. */
+#define HAVE_SENDMSG 1
+
+/* Define if you have the settimeofday function. */
+#define HAVE_SETTIMEOFDAY 1
+
+/* Define if you have the sigaltstack function. */
+#define HAVE_SIGALTSTACK 1
+
+/* Define if you have the statfs function. */
+#define HAVE_STATFS 1
+
+/* Define if you have the strcasecmp function. */
+#define HAVE_STRCASECMP 1
+
+/* Define if you have the strerror function. */
+#define HAVE_STRERROR 1
+
+/* Define if you have the strncasecmp function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define if you have the tcgetattr function. */
+#define HAVE_TCGETATTR 1
+
+/* Define if you have the timegm function. */
+#define HAVE_TIMEGM 1
+
+/* Define if you have the usleep function. */
+#define HAVE_USLEEP 1
+
+/* Define if you have the vfscanf function. */
+#define HAVE_VFSCANF 1
+
+/* Define if you have the wait4 function. */
+#define HAVE_WAIT4 1
+
+/* Define if you have the waitpid function. */
+#define HAVE_WAITPID 1
+
+/* Define if you have the <GL/gl.h> header file. */
+/* #undef HAVE_GL_GL_H */
+
+/* Define if you have the <GL/glx.h> header file. */
+/* #undef HAVE_GL_GLX_H */
+
+/* Define if you have the <X11/Xlib.h> header file. */
+#define HAVE_X11_XLIB_H 1
+
+/* Define if you have the <X11/extensions/XShm.h> header file. */
+#define HAVE_X11_EXTENSIONS_XSHM_H 1
+
+/* Define if you have the <X11/extensions/xf86dga.h> header file. */
+#define HAVE_X11_EXTENSIONS_XF86DGA_H 1
+
+/* Define if you have the <X11/extensions/xf86vmode.h> header file. */
+#define HAVE_X11_EXTENSIONS_XF86VMODE_H 1
+
+/* Define if you have the <X11/xpm.h> header file. */
+#define HAVE_X11_XPM_H 1
+
+/* Define if you have the <a.out.h> header file. */
+#define HAVE_A_OUT_H 1
+
+/* Define if you have the <a_out.h> header file. */
+#define HAVE_A_OUT_H 1
+
+/* Define if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define if you have the <arpa/nameser.h> header file. */
+#define HAVE_ARPA_NAMESER_H 1
+
+/* Define if you have the <curses.h> header file. */
+/* #undef HAVE_CURSES_H */
+
+/* Define if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define if you have the <elf.h> header file. */
+#define HAVE_ELF_H 1
+
+/* Define if you have the <float.h> header file. */
+#define HAVE_FLOAT_H 1
+
+/* Define if you have the <libio.h> header file. */
+#define HAVE_LIBIO_H 1
+
+/* Define if you have the <link.h> header file. */
+#define HAVE_LINK_H 1
+
+/* Define if you have the <linux/cdrom.h> header file. */
+#define HAVE_LINUX_CDROM_H 1
+
+/* Define if you have the <linux/joystick.h> header file. */
+#define HAVE_LINUX_JOYSTICK_H 1
+
+/* Define if you have the <linux/ucdrom.h> header file. */
+/* #undef HAVE_LINUX_UCDROM_H */
+
+/* Define if you have the <machine/soundcard.h> header file. */
+/* #undef HAVE_MACHINE_SOUNDCARD_H */
+
+/* Define if you have the <ncurses.h> header file. */
+#define HAVE_NCURSES_H 1
+
+/* Define if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H 1
+
+/* Define if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H 1
+
+/* Define if you have the <pty.h> header file. */
+#define HAVE_PTY_H 1
+
+/* Define if you have the <resolv.h> header file. */
+#define HAVE_RESOLV_H 1
+
+/* Define if you have the <sched.h> header file. */
+#define HAVE_SCHED_H 1
+
+/* Define if you have the <socket.h> header file. */
+/* #undef HAVE_SOCKET_H */
+
+/* Define if you have the <soundcard.h> header file. */
+/* #undef HAVE_SOUNDCARD_H */
+
+/* Define if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define if you have the <sys/cdio.h> header file. */
+/* #undef HAVE_SYS_CDIO_H */
+
+/* Define if you have the <sys/errno.h> header file. */
+#define HAVE_SYS_ERRNO_H 1
+
+/* Define if you have the <sys/file.h> header file. */
+#define HAVE_SYS_FILE_H 1
+
+/* Define if you have the <sys/filio.h> header file. */
+/* #undef HAVE_SYS_FILIO_H */
+
+/* Define if you have the <sys/ipc.h> header file. */
+#define HAVE_SYS_IPC_H 1
+
+/* Define if you have the <sys/lwp.h> header file. */
+/* #undef HAVE_SYS_LWP_H */
+
+/* Define if you have the <sys/mman.h> header file. */
+#define HAVE_SYS_MMAN_H 1
+
+/* Define if you have the <sys/modem.h> header file. */
+/* #undef HAVE_SYS_MODEM_H */
+
+/* Define if you have the <sys/mount.h> header file. */
+#define HAVE_SYS_MOUNT_H 1
+
+/* Define if you have the <sys/msg.h> header file. */
+#define HAVE_SYS_MSG_H 1
+
+/* Define if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define if you have the <sys/reg.h> header file. */
+#define HAVE_SYS_REG_H 1
+
+/* Define if you have the <sys/shm.h> header file. */
+#define HAVE_SYS_SHM_H 1
+
+/* Define if you have the <sys/signal.h> header file. */
+#define HAVE_SYS_SIGNAL_H 1
+
+/* Define if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define if you have the <sys/sockio.h> header file. */
+/* #undef HAVE_SYS_SOCKIO_H */
+
+/* Define if you have the <sys/soundcard.h> header file. */
+#define HAVE_SYS_SOUNDCARD_H 1
+
+/* Define if you have the <sys/statfs.h> header file. */
+#define HAVE_SYS_STATFS_H 1
+
+/* Define if you have the <sys/strtio.h> header file. */
+/* #undef HAVE_SYS_STRTIO_H */
+
+/* Define if you have the <sys/syscall.h> header file. */
+#define HAVE_SYS_SYSCALL_H 1
+
+/* Define if you have the <sys/v86.h> header file. */
+/* #undef HAVE_SYS_V86_H */
+
+/* Define if you have the <sys/v86intr.h> header file. */
+/* #undef HAVE_SYS_V86INTR_H */
+
+/* Define if you have the <sys/vfs.h> header file. */
+#define HAVE_SYS_VFS_H 1
+
+/* Define if you have the <sys/vm86.h> header file. */
+#define HAVE_SYS_VM86_H 1
+
+/* Define if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define if you have the <syscall.h> header file. */
+#define HAVE_SYSCALL_H 1
+
+/* Define if you have the <ucontext.h> header file. */
+#define HAVE_UCONTEXT_H 1
+
+/* Define if you have the <wctype.h> header file. */
+#define HAVE_WCTYPE_H 1
+
+/* Define if you have the curses library (-lcurses). */
+/* #undef HAVE_LIBCURSES */
+
+/* Define if you have the i386 library (-li386). */
+/* #undef HAVE_LIBI386 */
+
+/* Define if you have the m library (-lm). */
+#define HAVE_LIBM 1
+
+/* Define if you have the mmap library (-lmmap). */
+/* #undef HAVE_LIBMMAP */
+
+/* Define if you have the ncurses library (-lncurses). */
+#define HAVE_LIBNCURSES 1
+
+/* Define if you have the ossaudio library (-lossaudio). */
+/* #undef HAVE_LIBOSSAUDIO */
+
+/* Define if you have the w library (-lw). */
+/* #undef HAVE_LIBW */
+
+/* Define if you have the xpg4 library (-lxpg4). */
+/* #undef HAVE_LIBXPG4 */
diff --git a/src/libw32dll/wine/debugtools.h b/src/libw32dll/wine/debugtools.h
new file mode 100644
index 000000000..9290f5705
--- /dev/null
+++ b/src/libw32dll/wine/debugtools.h
@@ -0,0 +1,92 @@
+
+#ifndef __WINE_DEBUGTOOLS_H
+#define __WINE_DEBUGTOOLS_H
+
+#include <stdarg.h>
+#include "config.h"
+#include "windef.h"
+
+struct _GUID;
+
+#define TRACE __vprintf
+#define dbg_printf __vprintf
+
+/* Internal definitions (do not use these directly) */
+
+enum __DEBUG_CLASS { __DBCL_FIXME, __DBCL_ERR, __DBCL_WARN, __DBCL_TRACE, __DBCL_COUNT };
+
+#ifndef NO_TRACE_MSGS
+# define __GET_DEBUGGING_trace(dbch) ((dbch)[0] & (1 << __DBCL_TRACE))
+#else
+# define __GET_DEBUGGING_trace(dbch) 0
+#endif
+
+#ifndef NO_DEBUG_MSGS
+# define __GET_DEBUGGING_warn(dbch) ((dbch)[0] & (1 << __DBCL_WARN))
+# define __GET_DEBUGGING_fixme(dbch) ((dbch)[0] & (1 << __DBCL_FIXME))
+#else
+# define __GET_DEBUGGING_warn(dbch) 0
+# define __GET_DEBUGGING_fixme(dbch) 0
+#endif
+
+/* define error macro regardless of what is configured */
+#define __GET_DEBUGGING_err(dbch) ((dbch)[0] & (1 << __DBCL_ERR))
+
+#define __GET_DEBUGGING(dbcl,dbch) __GET_DEBUGGING_##dbcl(dbch)
+#define __SET_DEBUGGING(dbcl,dbch,on) \
+ ((on) ? ((dbch)[0] |= 1 << (dbcl)) : ((dbch)[0] &= ~(1 << (dbcl))))
+
+#ifndef __GNUC__
+#define __FUNCTION__ ""
+#endif
+
+#define __DPRINTF(dbcl,dbch) \
+ (!__GET_DEBUGGING(dbcl,(dbch)) || (dbg_header_##dbcl((dbch),__FUNCTION__),0)) ? \
+ (void)0 : (void)dbg_printf
+
+/* Exported definitions and macros */
+
+/* These function return a printable version of a string, including
+ quotes. The string will be valid for some time, but not indefinitely
+ as strings are re-used. */
+extern LPCSTR debugstr_an (LPCSTR s, int n);
+extern LPCSTR debugstr_wn (LPCWSTR s, int n);
+extern LPCSTR debugres_a (LPCSTR res);
+extern LPCSTR debugres_w (LPCWSTR res);
+extern LPCSTR debugstr_guid( const struct _GUID *id );
+extern LPCSTR debugstr_hex_dump (const void *ptr, int len);
+extern int dbg_header_err( const char *dbg_channel, const char *func );
+extern int dbg_header_warn( const char *dbg_channel, const char *func );
+extern int dbg_header_fixme( const char *dbg_channel, const char *func );
+extern int dbg_header_trace( const char *dbg_channel, const char *func );
+extern int dbg_vprintf( const char *format, va_list args );
+
+static inline LPCSTR debugstr_a( LPCSTR s ) { return debugstr_an( s, 80 ); }
+static inline LPCSTR debugstr_w( LPCWSTR s ) { return debugstr_wn( s, 80 ); }
+
+#ifdef __GNUC__
+extern int dbg_printf(const char *format, ...) __attribute__((format (printf,1,2)));
+#else
+extern int dbg_printf(const char *format, ...);
+#endif
+
+#define TRACE_(X)
+#define WARN_(X)
+#define WARN
+#define ERR_(X)
+#define ERR
+#define FIXME_(X)
+#define FIXME
+
+#define TRACE_ON(X) 1
+#define ERR_ON(X) 1
+
+#define DECLARE_DEBUG_CHANNEL(ch) \
+ extern char dbch_##ch[];
+#define DEFAULT_DEBUG_CHANNEL(ch) \
+ extern char dbch_##ch[]; static char * const __dbch_default = dbch_##ch;
+
+#define DPRINTF
+#define MESSAGE
+
+#endif /* __WINE_DEBUGTOOLS_H */
diff --git a/src/libw32dll/wine/driver.h b/src/libw32dll/wine/driver.h
new file mode 100644
index 000000000..dc8661aa3
--- /dev/null
+++ b/src/libw32dll/wine/driver.h
@@ -0,0 +1,112 @@
+/*
+ * Drivers definitions
+ */
+
+#ifndef __WINE_DRIVER_H
+#define __WINE_DRIVER_H
+
+#include "windef.h"
+
+#define MMSYSERR_BASE 0
+
+#define MMSYSERR_NOERROR 0 /* no error */
+#define MMSYSERR_ERROR (MMSYSERR_BASE + 1) /* unspecified error */
+#define MMSYSERR_BADDEVICEID (MMSYSERR_BASE + 2) /* device ID out of range */
+#define MMSYSERR_NOTENABLED (MMSYSERR_BASE + 3) /* driver failed enable */
+#define MMSYSERR_ALLOCATED (MMSYSERR_BASE + 4) /* device already allocated */
+#define MMSYSERR_INVALHANDLE (MMSYSERR_BASE + 5) /* device handle is invalid */
+#define MMSYSERR_NODRIVER (MMSYSERR_BASE + 6) /* no device driver present */
+#define MMSYSERR_NOMEM (MMSYSERR_BASE + 7) /* memory allocation error */
+#define MMSYSERR_NOTSUPPORTED (MMSYSERR_BASE + 8) /* function isn't supported */
+#define MMSYSERR_BADERRNUM (MMSYSERR_BASE + 9) /* error value out of range */
+#define MMSYSERR_INVALFLAG (MMSYSERR_BASE + 10) /* invalid flag passed */
+#define MMSYSERR_INVALPARAM (MMSYSERR_BASE + 11) /* invalid parameter passed */
+#define MMSYSERR_LASTERROR (MMSYSERR_BASE + 11) /* last error in range */
+
+#define DRV_LOAD 0x0001
+#define DRV_ENABLE 0x0002
+#define DRV_OPEN 0x0003
+#define DRV_CLOSE 0x0004
+#define DRV_DISABLE 0x0005
+#define DRV_FREE 0x0006
+#define DRV_CONFIGURE 0x0007
+#define DRV_QUERYCONFIGURE 0x0008
+#define DRV_INSTALL 0x0009
+#define DRV_REMOVE 0x000A
+#define DRV_EXITSESSION 0x000B
+#define DRV_EXITAPPLICATION 0x000C
+#define DRV_POWER 0x000F
+
+#define DRV_RESERVED 0x0800
+#define DRV_USER 0x4000
+
+#define DRVCNF_CANCEL 0x0000
+#define DRVCNF_OK 0x0001
+#define DRVCNF_RESTART 0x0002
+
+#define DRVEA_NORMALEXIT 0x0001
+#define DRVEA_ABNORMALEXIT 0x0002
+
+#define DRV_SUCCESS 0x0001
+#define DRV_FAILURE 0x0000
+
+#define GND_FIRSTINSTANCEONLY 0x00000001
+
+#define GND_FORWARD 0x00000000
+#define GND_REVERSE 0x00000002
+
+typedef struct {
+ DWORD dwDCISize;
+ LPCSTR lpszDCISectionName;
+ LPCSTR lpszDCIAliasName;
+} DRVCONFIGINFO16, *LPDRVCONFIGINFO16;
+
+typedef struct {
+ DWORD dwDCISize;
+ LPCWSTR lpszDCISectionName;
+ LPCWSTR lpszDCIAliasName;
+} DRVCONFIGINFO, *LPDRVCONFIGINFO;
+
+
+/* GetDriverInfo16 references this structure, so this a struct defined
+ * in the Win16 API.
+ * GetDriverInfo has been deprecated in Win32.
+ */
+typedef struct
+{
+ UINT16 length;
+ HDRVR16 hDriver;
+ HINSTANCE16 hModule;
+ CHAR szAliasName[128];
+} DRIVERINFOSTRUCT16, *LPDRIVERINFOSTRUCT16;
+
+LRESULT WINAPI DefDriverProc16(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg,
+ LPARAM dwParam1, LPARAM dwParam2);
+LRESULT WINAPI DefDriverProc(DWORD dwDriverIdentifier, HDRVR hdrvr,
+ UINT Msg, LPARAM lParam1, LPARAM lParam2);
+HDRVR16 WINAPI OpenDriver16(LPCSTR szDriverName, LPCSTR szSectionName,
+ LPARAM lParam2);
+HDRVR WINAPI OpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName,
+ LPARAM lParam2);
+HDRVR WINAPI OpenDriverW(LPCWSTR szDriverName, LPCWSTR szSectionName,
+ LPARAM lParam2);
+#define OpenDriver WINELIB_NAME_AW(OpenDriver)
+LRESULT WINAPI CloseDriver16(HDRVR16 hDriver, LPARAM lParam1, LPARAM lParam2);
+LRESULT WINAPI CloseDriver(HDRVR hDriver, LPARAM lParam1, LPARAM lParam2);
+LRESULT WINAPI SendDriverMessage16( HDRVR16 hDriver, UINT16 message,
+ LPARAM lParam1, LPARAM lParam2 );
+LRESULT WINAPI SendDriverMessage( HDRVR hDriver, UINT message,
+ LPARAM lParam1, LPARAM lParam2 );
+HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDriver);
+HMODULE WINAPI GetDriverModuleHandle(HDRVR hDriver);
+
+DWORD WINAPI GetDriverFlags( HDRVR hDriver );
+#ifdef __WINE__
+/* this call (GetDriverFlags) is not documented, nor the flags returned.
+ * here are Wine only definitions
+ */
+#define WINE_GDF_EXIST 0x80000000
+#define WINE_GDF_16BIT 0x10000000
+#endif
+
+#endif /* __WINE_DRIVER_H */
diff --git a/src/libw32dll/wine/elfdll.h b/src/libw32dll/wine/elfdll.h
new file mode 100644
index 000000000..1f356856f
--- /dev/null
+++ b/src/libw32dll/wine/elfdll.h
@@ -0,0 +1,14 @@
+#ifndef __WINE_ELFDLL_H
+#define __WINE_ELFDLL_H
+
+#include "module.h"
+#include "windef.h"
+
+WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR libname, DWORD flags);
+HINSTANCE16 ELFDLL_LoadModule16(LPCSTR libname);
+void ELFDLL_UnloadLibrary(WINE_MODREF *wm);
+
+void *ELFDLL_dlopen(const char *libname, int flags);
+extern char *extra_ld_library_path;
+
+#endif
diff --git a/src/libw32dll/wine/heap.h b/src/libw32dll/wine/heap.h
new file mode 100644
index 000000000..bd0604b75
--- /dev/null
+++ b/src/libw32dll/wine/heap.h
@@ -0,0 +1,56 @@
+/*
+ * Win32 heap definitions
+ *
+ * Copyright 1996 Alexandre Julliard
+ */
+
+#ifndef __WINE_HEAP_H
+#define __WINE_HEAP_H
+
+#include "config.h"
+
+#include "winbase.h"
+
+extern HANDLE SystemHeap;
+extern HANDLE SegptrHeap;
+
+extern int HEAP_IsInsideHeap( HANDLE heap, DWORD flags, LPCVOID ptr );
+extern SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr );
+extern LPSTR HEAP_strdupA( HANDLE heap, DWORD flags, LPCSTR str );
+extern LPWSTR HEAP_strdupW( HANDLE heap, DWORD flags, LPCWSTR str );
+extern LPWSTR HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str );
+extern LPSTR HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str );
+
+/* SEGPTR helper macros */
+
+#define SEGPTR_ALLOC(size) \
+ (HeapAlloc( SegptrHeap, 0, (size) ))
+#define SEGPTR_NEW(type) \
+ ((type *)HeapAlloc( SegptrHeap, 0, sizeof(type) ))
+#define SEGPTR_STRDUP(str) \
+ (HIWORD(str) ? HEAP_strdupA( SegptrHeap, 0, (str) ) : (LPSTR)(str))
+#define SEGPTR_STRDUP_WtoA(str) \
+ (HIWORD(str) ? HEAP_strdupWtoA( SegptrHeap, 0, (str) ) : (LPSTR)(str))
+ /* define an inline function, a macro won't do */
+static inline SEGPTR WINE_UNUSED SEGPTR_Get(LPCVOID ptr) {
+ return (HIWORD(ptr) ? HEAP_GetSegptr( SegptrHeap, 0, ptr ) : (SEGPTR)ptr);
+}
+#define SEGPTR_GET(ptr) SEGPTR_Get(ptr)
+#define SEGPTR_FREE(ptr) \
+ (HIWORD(ptr) ? HeapFree( SegptrHeap, 0, (ptr) ) : 0)
+
+/* system heap private data */
+/* you must lock the system heap before using this structure */
+typedef struct
+{
+ void *gdi; /* GDI heap */
+ void *user; /* USER handle table */
+ void *cursor; /* cursor information */
+ void *queue; /* message queues descriptor */
+ void *win; /* windows descriptor */
+ void *root; /* X11 root window */
+} SYSTEM_HEAP_DESCR;
+
+extern SYSTEM_HEAP_DESCR *SystemHeapDescr;
+
+#endif /* __WINE_HEAP_H */
diff --git a/src/libw32dll/wine/ldt.h b/src/libw32dll/wine/ldt.h
new file mode 100644
index 000000000..f87ecc14e
--- /dev/null
+++ b/src/libw32dll/wine/ldt.h
@@ -0,0 +1,98 @@
+/*
+ * LDT copy
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#ifndef __WINE_LDT_H
+#define __WINE_LDT_H
+
+#include "windef.h"
+enum seg_type
+{
+ SEGMENT_DATA = 0,
+ SEGMENT_STACK = 1,
+ SEGMENT_CODE = 2
+};
+
+ /* This structure represents a real LDT entry. */
+ /* It is used by get_ldt_entry() and set_ldt_entry(). */
+typedef struct
+{
+ unsigned long base; /* base address */
+ unsigned long limit; /* segment limit (in pages or bytes) */
+ int seg_32bit; /* is segment 32-bit? */
+ int read_only; /* is segment read-only? */
+ int limit_in_pages; /* is the limit in pages or bytes? */
+ enum seg_type type; /* segment type */
+} ldt_entry;
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+extern void LDT_BytesToEntry( const unsigned long *buffer, ldt_entry *content);
+extern void LDT_EntryToBytes( unsigned long *buffer, const ldt_entry *content);
+extern int LDT_GetEntry( int entry, ldt_entry *content );
+extern int LDT_SetEntry( int entry, const ldt_entry *content );
+extern void LDT_Print( int start, int length );
+
+
+ /* This structure is used to build the local copy of the LDT. */
+typedef struct
+{
+ unsigned long base; /* base address or 0 if entry is free */
+ unsigned long limit; /* limit in bytes or 0 if entry is free */
+} ldt_copy_entry;
+
+#define LDT_SIZE 8192
+
+extern ldt_copy_entry ldt_copy[LDT_SIZE];
+
+#define __AHSHIFT 3 /* don't change! */
+#define __AHINCR (1 << __AHSHIFT)
+
+#define SELECTOR_TO_ENTRY(sel) (((int)(sel) & 0xffff) >> __AHSHIFT)
+#define ENTRY_TO_SELECTOR(i) ((i) ? (((int)(i) << __AHSHIFT) | 7) : 0)
+#define IS_LDT_ENTRY_FREE(i) (!(ldt_flags_copy[(i)] & LDT_FLAGS_ALLOCATED))
+#define IS_SELECTOR_FREE(sel) (IS_LDT_ENTRY_FREE(SELECTOR_TO_ENTRY(sel)))
+#define GET_SEL_BASE(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].base)
+#define GET_SEL_LIMIT(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].limit)
+
+/* Convert a segmented ptr (16:16) to a linear (32) pointer */
+
+#define PTR_SEG_OFF_TO_LIN(seg,off) \
+ ((void*)(GET_SEL_BASE(seg) + (unsigned int)(off)))
+#define PTR_SEG_TO_LIN(ptr) \
+ PTR_SEG_OFF_TO_LIN(SELECTOROF(ptr),OFFSETOF(ptr))
+#define PTR_SEG_OFF_TO_SEGPTR(seg,off) \
+ ((SEGPTR)MAKELONG(off,seg))
+#define PTR_SEG_OFF_TO_HUGEPTR(seg,off) \
+ PTR_SEG_OFF_TO_SEGPTR( (seg) + (HIWORD(off) << __AHSHIFT), LOWORD(off) )
+
+#define W32S_APPLICATION() (PROCESS_Current()->flags & PDB32_WIN32S_PROC)
+#define W32S_OFFSET 0x10000
+#define W32S_APP2WINE(addr, offset) ((addr)? (DWORD)(addr) + (DWORD)(offset) : 0)
+#define W32S_WINE2APP(addr, offset) ((addr)? (DWORD)(addr) - (DWORD)(offset) : 0)
+
+extern unsigned char ldt_flags_copy[LDT_SIZE];
+
+#define LDT_FLAGS_TYPE 0x03 /* Mask for segment type */
+#define LDT_FLAGS_READONLY 0x04 /* Segment is read-only (data) */
+#define LDT_FLAGS_EXECONLY 0x04 /* Segment is execute-only (code) */
+#define LDT_FLAGS_32BIT 0x08 /* Segment is 32-bit (code or stack) */
+#define LDT_FLAGS_BIG 0x10 /* Segment is big (limit is in pages) */
+#define LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */
+
+#define GET_SEL_FLAGS(sel) (ldt_flags_copy[SELECTOR_TO_ENTRY(sel)])
+
+#define FIRST_LDT_ENTRY_TO_ALLOC 17
+
+/* Determine if sel is a system selector (i.e. not managed by Wine) */
+#define IS_SELECTOR_SYSTEM(sel) \
+ (!((sel) & 4) || (SELECTOR_TO_ENTRY(sel) < FIRST_LDT_ENTRY_TO_ALLOC))
+#define IS_SELECTOR_32BIT(sel) \
+ (IS_SELECTOR_SYSTEM(sel) || (GET_SEL_FLAGS(sel) & LDT_FLAGS_32BIT))
+#ifdef __cplusplus
+}
+#endif
+#endif /* __WINE_LDT_H */
diff --git a/src/libw32dll/wine/mmreg.h b/src/libw32dll/wine/mmreg.h
new file mode 100644
index 000000000..74e26250d
--- /dev/null
+++ b/src/libw32dll/wine/mmreg.h
@@ -0,0 +1,104 @@
+/*
+ * mmreg.h - Declarations for ???
+ */
+
+#ifndef __WINE_MMREG_H
+#define __WINE_MMREG_H
+
+/***********************************************************************
+ * Defines/Enums
+ */
+
+#ifndef _ACM_WAVEFILTER
+#define _ACM_WAVEFILTER
+
+#include "windef.h"
+
+#define WAVE_FILTER_UNKNOWN 0x0000
+#define WAVE_FILTER_DEVELOPMENT 0xFFFF
+
+typedef struct _WAVEFILTER {
+ DWORD cbStruct;
+ DWORD dwFilterTag;
+ DWORD fdwFilter;
+ DWORD dwReserved[5];
+} WAVEFILTER, *PWAVEFILTER, *NPWAVEFILTER, *LPWAVEFILTER;
+#endif /* _ACM_WAVEFILTER */
+
+#ifndef WAVE_FILTER_VOLUME
+#define WAVE_FILTER_VOLUME 0x0001
+
+typedef struct _WAVEFILTER_VOLUME {
+ WAVEFILTER wfltr;
+ DWORD dwVolume;
+} VOLUMEWAVEFILTER, *PVOLUMEWAVEFILTER, *NPVOLUMEWAVEFILTER, *LPVOLUMEWAVEFILTER;
+#endif /* WAVE_FILTER_VOLUME */
+
+#ifndef WAVE_FILTER_ECHO
+#define WAVE_FILTER_ECHO 0x0002
+
+typedef struct WAVEFILTER_ECHO {
+ WAVEFILTER wfltr;
+ DWORD dwVolume;
+ DWORD dwDelay;
+} ECHOWAVEFILTER, *PECHOWAVEFILTER, *NPECHOWAVEFILTER, *LPECHOWAVEFILTER;
+#endif /* WAVEFILTER_ECHO */
+
+#ifndef _WAVEFORMATEX_
+#define _WAVEFORMATEX_
+typedef struct _WAVEFORMATEX {
+ WORD wFormatTag;
+ WORD nChannels;
+ DWORD nSamplesPerSec;
+ DWORD nAvgBytesPerSec;
+ WORD nBlockAlign;
+ WORD wBitsPerSample;
+ WORD cbSize;
+} WAVEFORMATEX, *PWAVEFORMATEX, *NPWAVEFORMATEX, *LPWAVEFORMATEX;
+#endif /* _WAVEFORMATEX_ */
+
+/* WAVE form wFormatTag IDs */
+#define WAVE_FORMAT_UNKNOWN 0x0000 /* Microsoft Corporation */
+#define WAVE_FORMAT_ADPCM 0x0002 /* Microsoft Corporation */
+#define WAVE_FORMAT_IBM_CVSD 0x0005 /* IBM Corporation */
+#define WAVE_FORMAT_ALAW 0x0006 /* Microsoft Corporation */
+#define WAVE_FORMAT_MULAW 0x0007 /* Microsoft Corporation */
+#define WAVE_FORMAT_OKI_ADPCM 0x0010 /* OKI */
+#define WAVE_FORMAT_DVI_ADPCM 0x0011 /* Intel Corporation */
+#define WAVE_FORMAT_IMA_ADPCM (WAVE_FORMAT_DVI_ADPCM) /* Intel Corporation */
+#define WAVE_FORMAT_MEDIASPACE_ADPCM 0x0012 /* Videologic */
+#define WAVE_FORMAT_SIERRA_ADPCM 0x0013 /* Sierra Semiconductor Corp */
+#define WAVE_FORMAT_G723_ADPCM 0x0014 /* Antex Electronics Corporation */
+#define WAVE_FORMAT_DIGISTD 0x0015 /* DSP Solutions, Inc. */
+#define WAVE_FORMAT_DIGIFIX 0x0016 /* DSP Solutions, Inc. */
+#define WAVE_FORMAT_DIALOGIC_OKI_ADPCM 0x0017 /* Dialogic Corporation */
+#define WAVE_FORMAT_YAMAHA_ADPCM 0x0020 /* Yamaha Corporation of America */
+#define WAVE_FORMAT_SONARC 0x0021 /* Speech Compression */
+#define WAVE_FORMAT_DSPGROUP_TRUESPEECH 0x0022 /* DSP Group, Inc */
+#define WAVE_FORMAT_ECHOSC1 0x0023 /* Echo Speech Corporation */
+#define WAVE_FORMAT_AUDIOFILE_AF36 0x0024 /* */
+#define WAVE_FORMAT_APTX 0x0025 /* Audio Processing Technology */
+#define WAVE_FORMAT_AUDIOFILE_AF10 0x0026 /* */
+#define WAVE_FORMAT_DOLBY_AC2 0x0030 /* Dolby Laboratories */
+#define WAVE_FORMAT_GSM610 0x0031 /* Microsoft Corporation */
+#define WAVE_FORMAT_ANTEX_ADPCME 0x0033 /* Antex Electronics Corporation */
+#define WAVE_FORMAT_CONTROL_RES_VQLPC 0x0034 /* Control Resources Limited */
+#define WAVE_FORMAT_DIGIREAL 0x0035 /* DSP Solutions, Inc. */
+#define WAVE_FORMAT_DIGIADPCM 0x0036 /* DSP Solutions, Inc. */
+#define WAVE_FORMAT_CONTROL_RES_CR10 0x0037 /* Control Resources Limited */
+#define WAVE_FORMAT_NMS_VBXADPCM 0x0038 /* Natural MicroSystems */
+#define WAVE_FORMAT_G721_ADPCM 0x0040 /* Antex Electronics Corporation */
+#define WAVE_FORMAT_MPEG 0x0050 /* Microsoft Corporation */
+#define WAVE_FORMAT_CREATIVE_ADPCM 0x0200 /* Creative Labs, Inc */
+#define WAVE_FORMAT_CREATIVE_FASTSPEECH8 0x0202 /* Creative Labs, Inc */
+#define WAVE_FORMAT_CREATIVE_FASTSPEECH10 0x0203 /* Creative Labs, Inc */
+#define WAVE_FORMAT_FM_TOWNS_SND 0x0300 /* Fujitsu Corp. */
+#define WAVE_FORMAT_OLIGSM 0x1000 /* Ing C. Olivetti & C., S.p.A. */
+#define WAVE_FORMAT_OLIADPCM 0x1001 /* Ing C. Olivetti & C., S.p.A. */
+#define WAVE_FORMAT_OLICELP 0x1002 /* Ing C. Olivetti & C., S.p.A. */
+#define WAVE_FORMAT_OLISBC 0x1003 /* Ing C. Olivetti & C., S.p.A. */
+#define WAVE_FORMAT_OLIOPR 0x1004 /* Ing C. Olivetti & C., S.p.A. */
+
+#define WAVE_FORMAT_DEVELOPMENT (0xFFFF)
+
+#endif /* __WINE_MMREG_H */
diff --git a/src/libw32dll/wine/module.h b/src/libw32dll/wine/module.h
new file mode 100644
index 000000000..7237c95f0
--- /dev/null
+++ b/src/libw32dll/wine/module.h
@@ -0,0 +1,198 @@
+/*
+ * Module definitions
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#ifndef __WINE_MODULE_H
+#define __WINE_MODULE_H
+
+#include "windef.h"
+//#include "dosexe.h"
+#include "pe_image.h"
+
+
+
+typedef struct {
+ BYTE type;
+ BYTE flags;
+ BYTE segnum;
+ WORD offs WINE_PACKED;
+} ET_ENTRY;
+
+typedef struct {
+ WORD first; /* ordinal */
+ WORD last; /* ordinal */
+ WORD next; /* bundle */
+} ET_BUNDLE;
+
+
+ /* In-memory segment table */
+typedef struct
+{
+ WORD filepos; /* Position in file, in sectors */
+ WORD size; /* Segment size on disk */
+ WORD flags; /* Segment flags */
+ WORD minsize; /* Min. size of segment in memory */
+ HANDLE16 hSeg; /* Selector or handle (selector - 1) */
+ /* of segment in memory */
+} SEGTABLEENTRY;
+
+
+ /* Self-loading modules contain this structure in their first segment */
+
+#include "pshpack1.h"
+
+typedef struct
+{
+ WORD version; /* Must be "A0" (0x3041) */
+ WORD reserved;
+ FARPROC16 BootApp; /* startup procedure */
+ FARPROC16 LoadAppSeg; /* procedure to load a segment */
+ FARPROC16 reserved2;
+ FARPROC16 MyAlloc; /* memory allocation procedure,
+ * wine must write this field */
+ FARPROC16 EntryAddrProc;
+ FARPROC16 ExitProc; /* exit procedure */
+ WORD reserved3[4];
+ FARPROC16 SetOwner; /* Set Owner procedure, exported by wine */
+} SELFLOADHEADER;
+
+ /* Parameters for LoadModule() */
+typedef struct
+{
+ HGLOBAL16 hEnvironment; /* Environment segment */
+ SEGPTR cmdLine WINE_PACKED; /* Command-line */
+ SEGPTR showCmd WINE_PACKED; /* Code for ShowWindow() */
+ SEGPTR reserved WINE_PACKED;
+} LOADPARAMS16;
+
+typedef struct
+{
+ LPSTR lpEnvAddress;
+ LPSTR lpCmdLine;
+ UINT16 *lpCmdShow;
+ DWORD dwReserved;
+} LOADPARAMS;
+
+#include "poppack.h"
+
+/* internal representation of 32bit modules. per process. */
+typedef enum {
+ MODULE32_PE = 1,
+ MODULE32_ELF,
+ MODULE32_ELFDLL
+} MODULE32_TYPE;
+
+typedef struct _wine_modref
+{
+ struct _wine_modref *next;
+ struct _wine_modref *prev;
+ MODULE32_TYPE type;
+ union {
+ PE_MODREF pe;
+ ELF_MODREF elf;
+ } binfmt;
+
+ HMODULE module;
+
+ int nDeps;
+ struct _wine_modref **deps;
+
+ int flags;
+ int refCount;
+
+ char *filename;
+ char *modname;
+ char *short_filename;
+ char *short_modname;
+} WINE_MODREF;
+
+#define WINE_MODREF_INTERNAL 0x00000001
+#define WINE_MODREF_NO_DLL_CALLS 0x00000002
+#define WINE_MODREF_PROCESS_ATTACHED 0x00000004
+#define WINE_MODREF_LOAD_AS_DATAFILE 0x00000010
+#define WINE_MODREF_DONT_RESOLVE_REFS 0x00000020
+#define WINE_MODREF_MARKER 0x80000000
+
+
+
+/* Resource types */
+typedef struct resource_typeinfo_s NE_TYPEINFO;
+typedef struct resource_nameinfo_s NE_NAMEINFO;
+
+#define NE_SEG_TABLE(pModule) \
+ ((SEGTABLEENTRY *)((char *)(pModule) + (pModule)->seg_table))
+
+#define NE_MODULE_TABLE(pModule) \
+ ((WORD *)((char *)(pModule) + (pModule)->modref_table))
+
+#define NE_MODULE_NAME(pModule) \
+ (((OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo))->szPathName)
+
+/* module.c */
+extern FARPROC MODULE_GetProcAddress( HMODULE hModule, LPCSTR function, WIN_BOOL snoop );
+extern WINE_MODREF *MODULE32_LookupHMODULE( HMODULE hModule );
+extern WIN_BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved );
+extern void MODULE_DllProcessDetach( WINE_MODREF *wm, WIN_BOOL bForceDetach, LPVOID lpReserved );
+extern void MODULE_DllThreadAttach( LPVOID lpReserved );
+extern void MODULE_DllThreadDetach( LPVOID lpReserved );
+extern WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags );
+extern WIN_BOOL MODULE_FreeLibrary( WINE_MODREF *wm );
+extern WINE_MODREF *MODULE_FindModule( LPCSTR path );
+extern HMODULE MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 );
+extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE hmodule, LPCSTR name );
+extern SEGPTR WINAPI HasGPHandler16( SEGPTR address );
+extern void MODULE_WalkModref( DWORD id );
+
+/* resource.c */
+extern INT WINAPI AccessResource(HMODULE,HRSRC);
+/*
+/ loader/ne/module.c
+extern NE_MODULE *NE_GetPtr( HMODULE16 hModule );
+extern void NE_DumpModule( HMODULE16 hModule );
+extern void NE_WalkModules(void);
+extern void NE_RegisterModule( NE_MODULE *pModule );
+extern WORD NE_GetOrdinal( HMODULE16 hModule, const char *name );
+extern FARPROC16 WINAPI NE_GetEntryPoint( HMODULE16 hModule, WORD ordinal );
+extern FARPROC16 NE_GetEntryPointEx( HMODULE16 hModule, WORD ordinal, WIN_BOOL16 snoop );
+extern WIN_BOOL16 NE_SetEntryPoint( HMODULE16 hModule, WORD ordinal, WORD offset );
+extern int NE_OpenFile( NE_MODULE *pModule );
+extern WIN_BOOL NE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env,
+ LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
+ WIN_BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
+ LPPROCESS_INFORMATION info );
+extern WIN_BOOL NE_InitProcess( NE_MODULE *pModule );
+
+
+/ loader/ne/resource.c
+extern HGLOBAL16 WINAPI NE_DefResourceHandler(HGLOBAL16,HMODULE16,HRSRC16);
+extern WIN_BOOL NE_InitResourceHandler( HMODULE16 hModule );
+extern HRSRC16 NE_FindResource( NE_MODULE *pModule, LPCSTR name, LPCSTR type );
+extern INT16 NE_AccessResource( NE_MODULE *pModule, HRSRC16 hRsrc );
+extern DWORD NE_SizeofResource( NE_MODULE *pModule, HRSRC16 hRsrc );
+extern HGLOBAL16 NE_LoadResource( NE_MODULE *pModule, HRSRC16 hRsrc );
+extern WIN_BOOL16 NE_FreeResource( NE_MODULE *pModule, HGLOBAL16 handle );
+extern NE_TYPEINFO *NE_FindTypeSection( LPBYTE pResTab, NE_TYPEINFO *pTypeInfo, LPCSTR typeId );
+extern NE_NAMEINFO *NE_FindResourceFromType( LPBYTE pResTab, NE_TYPEINFO *pTypeInfo, LPCSTR resId );
+
+// loader/ne/segment.c
+extern WIN_BOOL NE_LoadSegment( NE_MODULE *pModule, WORD segnum );
+extern WIN_BOOL NE_LoadAllSegments( NE_MODULE *pModule );
+extern WIN_BOOL NE_CreateSegment( NE_MODULE *pModule, int segnum );
+extern WIN_BOOL NE_CreateAllSegments( NE_MODULE *pModule );
+extern HINSTANCE16 NE_GetInstance( NE_MODULE *pModule );
+extern void NE_InitializeDLLs( HMODULE16 hModule );
+extern void NE_DllProcessAttach( HMODULE16 hModule );
+
+// loader/ne/convert.c
+HGLOBAL16 NE_LoadPEResource( NE_MODULE *pModule, WORD type, LPVOID bits, DWORD size );
+*/
+/* relay32/builtin.c */
+extern WINE_MODREF *BUILTIN32_LoadLibraryExA(LPCSTR name, DWORD flags);
+extern HMODULE BUILTIN32_LoadExeModule( LPCSTR *filename );
+extern void BUILTIN32_UnloadLibrary(WINE_MODREF *wm);
+extern void *BUILTIN32_dlopen( const char *name );
+extern int BUILTIN32_dlclose( void *handle );
+
+#endif /* __WINE_MODULE_H */
diff --git a/src/libw32dll/wine/msacm.h b/src/libw32dll/wine/msacm.h
new file mode 100644
index 000000000..c359a4ca1
--- /dev/null
+++ b/src/libw32dll/wine/msacm.h
@@ -0,0 +1,942 @@
+/*
+ * msacm.h - Declarations for MSACM
+ */
+
+#ifndef __WINE_MSACM_H
+#define __WINE_MSACM_H
+
+#include "windef.h"
+#include "driver.h"
+#include "mmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+//typedef WORD VERSION; /* major (high byte), minor (low byte) */
+
+typedef UINT16 MMVERSION16;
+typedef UINT MMVERSION;
+typedef UINT16 MCIDEVICEID16;
+typedef UINT MCIDEVICEID;
+typedef UINT16 MMRESULT16;
+typedef UINT MMRESULT;
+typedef DWORD FOURCC; /* a four character code */
+
+
+
+#define WAVE_FORMAT_PCM 1
+
+/***********************************************************************
+ * Defines/Enums
+ */
+
+#define ACMERR_BASE 512
+#define ACMERR_NOTPOSSIBLE (ACMERR_BASE + 0)
+#define ACMERR_BUSY (ACMERR_BASE + 1)
+#define ACMERR_UNPREPARED (ACMERR_BASE + 2)
+#define ACMERR_CANCELED (ACMERR_BASE + 3)
+
+#define MM_ACM_OPEN MM_STREAM_OPEN
+#define MM_ACM_CLOSE MM_STREAM_CLOSE
+#define MM_ACM_DONE MM_STREAM_DONE
+
+#define ACM_DRIVERADDF_FUNCTION 0x00000003L
+#define ACM_DRIVERADDF_NOTIFYHWND 0x00000004L
+#define ACM_DRIVERADDF_TYPEMASK 0x00000007L
+#define ACM_DRIVERADDF_LOCAL 0x00000000L
+#define ACM_DRIVERADDF_GLOBAL 0x00000008L
+
+#define ACMDRIVERDETAILS_SHORTNAME_CHARS 32
+#define ACMDRIVERDETAILS_LONGNAME_CHARS 128
+#define ACMDRIVERDETAILS_COPYRIGHT_CHARS 80
+#define ACMDRIVERDETAILS_LICENSING_CHARS 128
+#define ACMDRIVERDETAILS_FEATURES_CHARS 512
+
+#define ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC mmioFOURCC('a', 'u', 'd', 'c')
+#define ACMDRIVERDETAILS_FCCCOMP_UNDEFINED mmioFOURCC('\0', '\0', '\0', '\0')
+
+#define ACMDRIVERDETAILS_SUPPORTF_CODEC 0x00000001L
+#define ACMDRIVERDETAILS_SUPPORTF_CONVERTER 0x00000002L
+#define ACMDRIVERDETAILS_SUPPORTF_FILTER 0x00000004L
+#define ACMDRIVERDETAILS_SUPPORTF_HARDWARE 0x00000008L
+#define ACMDRIVERDETAILS_SUPPORTF_ASYNC 0x00000010L
+#define ACMDRIVERDETAILS_SUPPORTF_LOCAL 0x40000000L
+#define ACMDRIVERDETAILS_SUPPORTF_DISABLED 0x80000000L
+
+#define ACM_DRIVERENUMF_NOLOCAL 0x40000000L
+#define ACM_DRIVERENUMF_DISABLED 0x80000000L
+
+#define ACM_DRIVERPRIORITYF_ENABLE 0x00000001L
+#define ACM_DRIVERPRIORITYF_DISABLE 0x00000002L
+#define ACM_DRIVERPRIORITYF_ABLEMASK 0x00000003L
+#define ACM_DRIVERPRIORITYF_BEGIN 0x00010000L
+#define ACM_DRIVERPRIORITYF_END 0x00020000L
+#define ACM_DRIVERPRIORITYF_DEFERMASK 0x00030000L
+
+#define MM_ACM_FILTERCHOOSE 0x8000
+
+#define FILTERCHOOSE_MESSAGE 0
+#define FILTERCHOOSE_FILTERTAG_VERIFY (FILTERCHOOSE_MESSAGE+0)
+#define FILTERCHOOSE_FILTER_VERIFY (FILTERCHOOSE_MESSAGE+1)
+#define FILTERCHOOSE_CUSTOM_VERIFY (FILTERCHOOSE_MESSAGE+2)
+
+#define ACMFILTERCHOOSE_STYLEF_SHOWHELP 0x00000004L
+#define ACMFILTERCHOOSE_STYLEF_ENABLEHOOK 0x00000008L
+#define ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATE 0x00000010L
+#define ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATEHANDLE 0x00000020L
+#define ACMFILTERCHOOSE_STYLEF_INITTOFILTERSTRUCT 0x00000040L
+#define ACMFILTERCHOOSE_STYLEF_CONTEXTHELP 0x00000080L
+
+#define ACMFILTERDETAILS_FILTER_CHARS 128
+
+#define ACM_FILTERDETAILSF_INDEX 0x00000000L
+#define ACM_FILTERDETAILSF_FILTER 0x00000001L
+#define ACM_FILTERDETAILSF_QUERYMASK 0x0000000FL
+
+#define ACMFILTERTAGDETAILS_FILTERTAG_CHARS 48
+
+#define ACM_FILTERTAGDETAILSF_INDEX 0x00000000L
+#define ACM_FILTERTAGDETAILSF_FILTERTAG 0x00000001L
+#define ACM_FILTERTAGDETAILSF_LARGESTSIZE 0x00000002L
+#define ACM_FILTERTAGDETAILSF_QUERYMASK 0x0000000FL
+
+#define ACM_FILTERENUMF_DWFILTERTAG 0x00010000L
+
+#define ACMHELPMSGSTRINGA "acmchoose_help"
+#define ACMHELPMSGSTRINGW L"acmchoose_help"
+#define ACMHELPMSGSTRING16 "acmchoose_help"
+
+#define ACMHELPMSGCONTEXTMENUA "acmchoose_contextmenu"
+#define ACMHELPMSGCONTEXTMENUW L"acmchoose_contextmenu"
+#define ACMHELPMSGCONTEXTMENU16 "acmchoose_contextmenu"
+
+#define ACMHELPMSGCONTEXTHELPA "acmchoose_contexthelp"
+#define ACMHELPMSGCONTEXTHELPW L"acmchoose_contexthelp"
+#define ACMHELPMSGCONTEXTHELP16 "acmchoose_contexthelp"
+
+#define MM_ACM_FORMATCHOOSE 0x8000
+
+#define FORMATCHOOSE_MESSAGE 0
+#define FORMATCHOOSE_FORMATTAG_VERIFY (FORMATCHOOSE_MESSAGE+0)
+#define FORMATCHOOSE_FORMAT_VERIFY (FORMATCHOOSE_MESSAGE+1)
+#define FORMATCHOOSE_CUSTOM_VERIFY (FORMATCHOOSE_MESSAGE+2)
+
+#define ACMFORMATCHOOSE_STYLEF_SHOWHELP 0x00000004L
+#define ACMFORMATCHOOSE_STYLEF_ENABLEHOOK 0x00000008L
+#define ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE 0x00000010L
+#define ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATEHANDLE 0x00000020L
+#define ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT 0x00000040L
+#define ACMFORMATCHOOSE_STYLEF_CONTEXTHELP 0x00000080L
+
+#define ACMFORMATDETAILS_FORMAT_CHARS 128
+
+#define ACM_FORMATDETAILSF_INDEX 0x00000000L
+#define ACM_FORMATDETAILSF_FORMAT 0x00000001L
+#define ACM_FORMATDETAILSF_QUERYMASK 0x0000000FL
+
+#define ACM_FORMATENUMF_WFORMATTAG 0x00010000L
+#define ACM_FORMATENUMF_NCHANNELS 0x00020000L
+#define ACM_FORMATENUMF_NSAMPLESPERSEC 0x00040000L
+#define ACM_FORMATENUMF_WBITSPERSAMPLE 0x00080000L
+#define ACM_FORMATENUMF_CONVERT 0x00100000L
+#define ACM_FORMATENUMF_SUGGEST 0x00200000L
+#define ACM_FORMATENUMF_HARDWARE 0x00400000L
+#define ACM_FORMATENUMF_INPUT 0x00800000L
+#define ACM_FORMATENUMF_OUTPUT 0x01000000L
+
+#define ACM_FORMATSUGGESTF_WFORMATTAG 0x00010000L
+#define ACM_FORMATSUGGESTF_NCHANNELS 0x00020000L
+#define ACM_FORMATSUGGESTF_NSAMPLESPERSEC 0x00040000L
+#define ACM_FORMATSUGGESTF_WBITSPERSAMPLE 0x00080000L
+#define ACM_FORMATSUGGESTF_TYPEMASK 0x00FF0000L
+
+#define ACMFORMATTAGDETAILS_FORMATTAG_CHARS 48
+
+#define ACM_FORMATTAGDETAILSF_INDEX 0x00000000L
+#define ACM_FORMATTAGDETAILSF_FORMATTAG 0x00000001L
+#define ACM_FORMATTAGDETAILSF_LARGESTSIZE 0x00000002L
+#define ACM_FORMATTAGDETAILSF_QUERYMASK 0x0000000FL
+
+#define ACM_METRIC_COUNT_DRIVERS 1
+#define ACM_METRIC_COUNT_CODECS 2
+#define ACM_METRIC_COUNT_CONVERTERS 3
+#define ACM_METRIC_COUNT_FILTERS 4
+#define ACM_METRIC_COUNT_DISABLED 5
+#define ACM_METRIC_COUNT_HARDWARE 6
+#define ACM_METRIC_COUNT_LOCAL_DRIVERS 20
+#define ACM_METRIC_COUNT_LOCAL_CODECS 21
+#define ACM_METRIC_COUNT_LOCAL_CONVERTERS 22
+#define ACM_METRIC_COUNT_LOCAL_FILTERS 23
+#define ACM_METRIC_COUNT_LOCAL_DISABLED 24
+#define ACM_METRIC_HARDWARE_WAVE_INPUT 30
+#define ACM_METRIC_HARDWARE_WAVE_OUTPUT 31
+#define ACM_METRIC_MAX_SIZE_FORMAT 50
+#define ACM_METRIC_MAX_SIZE_FILTER 51
+#define ACM_METRIC_DRIVER_SUPPORT 100
+#define ACM_METRIC_DRIVER_PRIORITY 101
+
+#define ACM_STREAMCONVERTF_BLOCKALIGN 0x00000004
+#define ACM_STREAMCONVERTF_START 0x00000010
+#define ACM_STREAMCONVERTF_END 0x00000020
+
+#define ACMSTREAMHEADER_STATUSF_DONE 0x00010000L
+#define ACMSTREAMHEADER_STATUSF_PREPARED 0x00020000L
+#define ACMSTREAMHEADER_STATUSF_INQUEUE 0x00100000L
+
+#define ACM_STREAMOPENF_QUERY 0x00000001
+#define ACM_STREAMOPENF_ASYNC 0x00000002
+#define ACM_STREAMOPENF_NONREALTIME 0x00000004
+
+#define ACM_STREAMSIZEF_SOURCE 0x00000000L
+#define ACM_STREAMSIZEF_DESTINATION 0x00000001L
+#define ACM_STREAMSIZEF_QUERYMASK 0x0000000FL
+
+#define ACMDM_USER (DRV_USER + 0x0000)
+#define ACMDM_RESERVED_LOW (DRV_USER + 0x2000)
+#define ACMDM_RESERVED_HIGH (DRV_USER + 0x2FFF)
+
+#define ACMDM_BASE ACMDM_RESERVED_LOW
+
+#define ACMDM_DRIVER_ABOUT (ACMDM_BASE + 11)
+
+/***********************************************************************
+ * Callbacks
+ */
+
+typedef WIN_BOOL CALLBACK ( *ACMDRIVERENUMCB)(
+ HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport
+);
+
+typedef WIN_BOOL16 CALLBACK ( *ACMDRIVERENUMCB16)(
+ HACMDRIVERID16 hadid, DWORD dwInstance, DWORD fdwSupport
+);
+
+typedef UINT CALLBACK ( *ACMFILTERCHOOSEHOOKPROCA)(
+ HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
+);
+
+typedef UINT CALLBACK ( *ACMFILTERCHOOSEHOOKPROCW)(
+ HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
+);
+
+typedef UINT CALLBACK ( *ACMFILTERCHOOSEHOOKPROC16)(
+ HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
+);
+
+typedef UINT CALLBACK ( *ACMFORMATCHOOSEHOOKPROCA)(
+ HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
+);
+
+typedef UINT CALLBACK ( *ACMFORMATCHOOSEHOOKPROCW)(
+ HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
+);
+
+typedef UINT16 CALLBACK ( *ACMFORMATCHOOSEHOOKPROC16)(
+ HWND16 hwnd, UINT16 uMsg, WPARAM16 wParam, LPARAM lParam
+);
+
+/***********************************************************************
+ * Structures
+ */
+
+typedef struct _ACMDRIVERDETAILSA
+{
+ DWORD cbStruct;
+
+ FOURCC fccType;
+ FOURCC fccComp;
+
+ WORD wMid;
+ WORD wPid;
+
+ DWORD vdwACM;
+ DWORD vdwDriver;
+
+ DWORD fdwSupport;
+ DWORD cFormatTags;
+ DWORD cFilterTags;
+
+ HICON hicon;
+
+ CHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS];
+ CHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS];
+ CHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS];
+ CHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS];
+ CHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS];
+} ACMDRIVERDETAILSA, *PACMDRIVERDETAILSA;
+
+typedef struct _ACMDRIVERDETAILSW
+{
+ DWORD cbStruct;
+
+ FOURCC fccType;
+ FOURCC fccComp;
+
+ WORD wMid;
+ WORD wPid;
+
+ DWORD vdwACM;
+ DWORD vdwDriver;
+
+ DWORD fdwSupport;
+ DWORD cFormatTags;
+ DWORD cFilterTags;
+
+ HICON hicon;
+
+ WCHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS];
+ WCHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS];
+ WCHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS];
+ WCHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS];
+ WCHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS];
+} ACMDRIVERDETAILSW, *PACMDRIVERDETAILSW;
+
+typedef struct _ACMDRIVERDETAILS16
+{
+ DWORD cbStruct;
+
+ FOURCC fccType;
+ FOURCC fccComp;
+
+ WORD wMid;
+ WORD wPid;
+
+ DWORD vdwACM;
+ DWORD vdwDriver;
+
+ DWORD fdwSupport;
+ DWORD cFormatTags;
+ DWORD cFilterTags;
+
+ HICON16 hicon;
+
+ CHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS];
+ CHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS];
+ CHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS];
+ CHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS];
+ CHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS];
+} ACMDRIVERDETAILS16, *NPACMDRIVERDETAILS16, *LPACMDRIVERDETAILS16;
+
+typedef struct _ACMFILTERCHOOSEA
+{
+ DWORD cbStruct;
+ DWORD fdwStyle;
+
+ HWND hwndOwner;
+
+ PWAVEFILTER pwfltr;
+ DWORD cbwfltr;
+
+ LPCSTR pszTitle;
+
+ CHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS];
+ CHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS];
+ LPSTR pszName;
+ DWORD cchName;
+
+ DWORD fdwEnum;
+ PWAVEFILTER pwfltrEnum;
+
+ HINSTANCE hInstance;
+ LPCSTR pszTemplateName;
+ LPARAM lCustData;
+ ACMFILTERCHOOSEHOOKPROCA pfnHook;
+} ACMFILTERCHOOSEA, *PACMFILTERCHOOSEA;
+
+typedef struct _ACMFILTERCHOOSEW
+{
+ DWORD cbStruct;
+ DWORD fdwStyle;
+
+ HWND hwndOwner;
+
+ PWAVEFILTER pwfltr;
+ DWORD cbwfltr;
+
+ LPCWSTR pszTitle;
+
+ WCHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS];
+ WCHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS];
+ LPWSTR pszName;
+ DWORD cchName;
+
+ DWORD fdwEnum;
+ PWAVEFILTER pwfltrEnum;
+
+ HINSTANCE hInstance;
+ LPCWSTR pszTemplateName;
+ LPARAM lCustData;
+ ACMFILTERCHOOSEHOOKPROCW pfnHook;
+} ACMFILTERCHOOSEW, *PACMFILTERCHOOSEW;
+
+typedef struct _ACMFILTERCHOOSE16
+{
+ DWORD cbStruct;
+ DWORD fdwStyle;
+
+ HWND16 hwndOwner;
+
+ LPWAVEFILTER pwfltr;
+ DWORD cbwfltr;
+
+ LPCSTR pszTitle;
+
+ char szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS];
+ char szFilter[ACMFILTERDETAILS_FILTER_CHARS];
+ LPSTR pszName;
+ DWORD cchName;
+
+ DWORD fdwEnum;
+ LPWAVEFILTER pwfltrEnum;
+
+ HINSTANCE16 hInstance;
+ LPCSTR pszTemplateName;
+ LPARAM lCustData;
+ ACMFILTERCHOOSEHOOKPROC16 pfnHook;
+} ACMFILTERCHOOSE16, *NPACMFILTERCHOOSE16, *LPACMFILTERCHOOSE16;
+
+typedef struct _ACMFILTERDETAILSA
+{
+ DWORD cbStruct;
+ DWORD dwFilterIndex;
+ DWORD dwFilterTag;
+ DWORD fdwSupport;
+ PWAVEFILTER pwfltr;
+ DWORD cbwfltr;
+ CHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS];
+} ACMFILTERDETAILSA, *PACMFILTERDETAILSA;
+
+typedef struct _ACMFILTERDETAILSW
+{
+ DWORD cbStruct;
+ DWORD dwFilterIndex;
+ DWORD dwFilterTag;
+ DWORD fdwSupport;
+ PWAVEFILTER pwfltr;
+ DWORD cbwfltr;
+ WCHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS];
+} ACMFILTERDETAILSW, *PACMFILTERDETAILSW;
+
+typedef struct _ACMFILTERDETAILS16
+{
+ DWORD cbStruct;
+ DWORD dwFilterIndex;
+ DWORD dwFilterTag;
+ DWORD fdwSupport;
+ LPWAVEFILTER pwfltr;
+ DWORD cbwfltr;
+ CHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS];
+} ACMFILTERDETAILS16, *NPACMFILTERDETAILS16, *LPACMFILTERDETAILS16;
+
+typedef struct _ACMFILTERTAGDETAILSA
+{
+ DWORD cbStruct;
+ DWORD dwFilterTagIndex;
+ DWORD dwFilterTag;
+ DWORD cbFilterSize;
+ DWORD fdwSupport;
+ DWORD cStandardFilters;
+ CHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS];
+} ACMFILTERTAGDETAILSA, *PACMFILTERTAGDETAILSA;
+
+typedef struct _ACMFILTERTAGDETAILSW
+{
+ DWORD cbStruct;
+ DWORD dwFilterTagIndex;
+ DWORD dwFilterTag;
+ DWORD cbFilterSize;
+ DWORD fdwSupport;
+ DWORD cStandardFilters;
+ WCHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS];
+} ACMFILTERTAGDETAILSW, *PACMFILTERTAGDETAILSW;
+
+typedef struct _ACMFILTERTAGDETAILS16
+{
+ DWORD cbStruct;
+ DWORD dwFilterTagIndex;
+ DWORD dwFilterTag;
+ DWORD cbFilterSize;
+ DWORD fdwSupport;
+ DWORD cStandardFilters;
+ CHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS];
+} ACMFILTERTAGDETAILS16, *NPACMFILTERTAGDETAILS16, *LPACMFILTERTAGDETAILS16;
+
+typedef struct _ACMFORMATCHOOSEA
+{
+ DWORD cbStruct;
+ DWORD fdwStyle;
+
+ HWND hwndOwner;
+
+ PWAVEFORMATEX pwfx;
+ DWORD cbwfx;
+ LPCSTR pszTitle;
+
+ CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];
+ CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS];
+
+ LPSTR pszName;
+ DWORD cchName;
+
+ DWORD fdwEnum;
+ PWAVEFORMATEX pwfxEnum;
+
+ HINSTANCE hInstance;
+ LPCSTR pszTemplateName;
+ LPARAM lCustData;
+ ACMFORMATCHOOSEHOOKPROCA pfnHook;
+} ACMFORMATCHOOSEA, *PACMFORMATCHOOSEA;
+
+typedef struct _ACMFORMATCHOOSEW
+{
+ DWORD cbStruct;
+ DWORD fdwStyle;
+
+ HWND hwndOwner;
+
+ PWAVEFORMATEX pwfx;
+ DWORD cbwfx;
+ LPCWSTR pszTitle;
+
+ WCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];
+ WCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS];
+
+ LPWSTR pszName;
+ DWORD cchName;
+
+ DWORD fdwEnum;
+ LPWAVEFORMATEX pwfxEnum;
+
+ HINSTANCE hInstance;
+ LPCWSTR pszTemplateName;
+ LPARAM lCustData;
+ ACMFORMATCHOOSEHOOKPROCW pfnHook;
+} ACMFORMATCHOOSEW, *PACMFORMATCHOOSEW;
+
+typedef struct _ACMFORMATCHOOSE16
+{
+ DWORD cbStruct;
+ DWORD fdwStyle;
+
+ HWND16 hwndOwner;
+
+ LPWAVEFORMATEX pwfx;
+ DWORD cbwfx;
+ LPCSTR pszTitle;
+
+ CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];
+ CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS];
+
+ LPSTR pszName;
+ DWORD cchName;
+
+ DWORD fdwEnum;
+ LPWAVEFORMATEX pwfxEnum;
+
+ HINSTANCE16 hInstance;
+ LPCSTR pszTemplateName;
+ LPARAM lCustData;
+ ACMFORMATCHOOSEHOOKPROC16 pfnHook;
+} ACMFORMATCHOOSE16, *NPACMFORMATCHOOSE16, *LPACMFORMATCHOOSE16;
+
+typedef struct _ACMFORMATDETAILSA
+{
+ DWORD cbStruct;
+ DWORD dwFormatIndex;
+ DWORD dwFormatTag;
+ DWORD fdwSupport;
+ PWAVEFORMATEX pwfx;
+ DWORD cbwfx;
+ CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS];
+} ACMFORMATDETAILSA, *PACMFORMATDETAILSA;
+
+typedef struct _ACMFORMATDETAILSW
+{
+ DWORD cbStruct;
+ DWORD dwFormatIndex;
+ DWORD dwFormatTag;
+ DWORD fdwSupport;
+ PWAVEFORMATEX pwfx;
+ DWORD cbwfx;
+ WCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS];
+} ACMFORMATDETAILSW, *PACMFORMATDETAILSW;
+
+typedef struct _ACMFORMATDETAILS16
+{
+ DWORD cbStruct;
+ DWORD dwFormatIndex;
+ DWORD dwFormatTag;
+ DWORD fdwSupport;
+ LPWAVEFORMATEX pwfx;
+ DWORD cbwfx;
+ CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS];
+} ACMFORMATDETAILS16, *NPACMFORMATDETAILS16, *LPACMFORMATDETAILS16;
+
+typedef struct _ACMFORMATTAGDETAILSA
+{
+ DWORD cbStruct;
+ DWORD dwFormatTagIndex;
+ DWORD dwFormatTag;
+ DWORD cbFormatSize;
+ DWORD fdwSupport;
+ DWORD cStandardFormats;
+ CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];
+} ACMFORMATTAGDETAILSA, *PACMFORMATTAGDETAILSA;
+
+typedef struct _ACMFORMATTAGDETAILSW
+{
+ DWORD cbStruct;
+ DWORD dwFormatTagIndex;
+ DWORD dwFormatTag;
+ DWORD cbFormatSize;
+ DWORD fdwSupport;
+ DWORD cStandardFormats;
+ WCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];
+} ACMFORMATTAGDETAILSW, *PACMFORMATTAGDETAILSW;
+
+typedef struct _ACMFORMATTAGDETAILS16
+{
+ DWORD cbStruct;
+ DWORD dwFormatTagIndex;
+ DWORD dwFormatTag;
+ DWORD cbFormatSize;
+ DWORD fdwSupport;
+ DWORD cStandardFormats;
+ CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS];
+} ACMFORMATTAGDETAILS16, *NPACMFORMATTAGDETAILS16, *LPACMFORMATTAGDETAILS16;
+
+typedef struct _ACMSTREAMHEADER
+{
+ DWORD cbStruct;
+ DWORD fdwStatus;
+ DWORD dwUser;
+ LPBYTE pbSrc;
+ DWORD cbSrcLength;
+ DWORD cbSrcLengthUsed;
+ DWORD dwSrcUser;
+ LPBYTE pbDst;
+ DWORD cbDstLength;
+ DWORD cbDstLengthUsed;
+ DWORD dwDstUser;
+ DWORD dwReservedDriver[10];
+} ACMSTREAMHEADER16, *NPACMSTREAMHEADER16, *LPACMSTREAMHEADER16,
+ ACMSTREAMHEADER, *PACMSTREAMHEADER;
+
+/***********************************************************************
+ * Callbacks 2
+ */
+
+typedef WIN_BOOL CALLBACK ( *ACMFILTERENUMCBA)(
+ HACMDRIVERID hadid, PACMFILTERDETAILSA pafd,
+ DWORD dwInstance, DWORD fdwSupport
+);
+
+typedef WIN_BOOL CALLBACK ( *ACMFILTERENUMCBW)(
+ HACMDRIVERID hadid, PACMFILTERDETAILSW pafd,
+ DWORD dwInstance, DWORD fdwSupport
+);
+
+typedef WIN_BOOL16 CALLBACK ( *ACMFILTERENUMCB16)(
+ HACMDRIVERID16 hadid, LPACMFILTERDETAILS16 pafd,
+ DWORD dwInstance, DWORD fdwSupport
+);
+
+typedef WIN_BOOL CALLBACK ( *ACMFILTERTAGENUMCBA)(
+ HACMDRIVERID hadid, PACMFILTERTAGDETAILSA paftd,
+ DWORD dwInstance, DWORD fdwSupport
+);
+
+typedef WIN_BOOL CALLBACK ( *ACMFILTERTAGENUMCBW)(
+ HACMDRIVERID hadid, PACMFILTERTAGDETAILSW paftd,
+ DWORD dwInstance, DWORD fdwSupport
+);
+
+typedef WIN_BOOL16 CALLBACK ( *ACMFILTERTAGENUMCB16)(
+ HACMDRIVERID16 hadid, LPACMFILTERTAGDETAILS16 paftd,
+ DWORD dwInstance, DWORD fdwSupport
+);
+
+typedef WIN_BOOL CALLBACK ( *ACMFORMATENUMCBA)(
+ HACMDRIVERID hadid, PACMFORMATDETAILSA pafd,
+ DWORD dwInstance, DWORD fdwSupport
+);
+
+typedef WIN_BOOL CALLBACK ( *ACMFORMATENUMCBW)(
+ HACMDRIVERID hadid, PACMFORMATDETAILSW pafd,
+ DWORD dwInstance, DWORD fdwSupport
+);
+
+typedef WIN_BOOL16 CALLBACK ( *ACMFORMATENUMCB16)(
+ HACMDRIVERID16 hadid, LPACMFORMATDETAILS16 pafd,
+ DWORD dwInstance, DWORD fdwSupport
+);
+
+typedef WIN_BOOL CALLBACK ( *ACMFORMATTAGENUMCBA)(
+ HACMDRIVERID hadid, PACMFORMATTAGDETAILSA paftd,
+ DWORD dwInstance, DWORD fdwSupport
+);
+
+typedef WIN_BOOL CALLBACK ( *ACMFORMATTAGENUMCBW)(
+ HACMDRIVERID hadid, PACMFORMATTAGDETAILSW paftd,
+ DWORD dwInstance, DWORD fdwSupport
+);
+
+typedef WIN_BOOL16 CALLBACK ( *ACMFORMATTAGENUMCB16)(
+ HACMDRIVERID16 hadid, LPACMFORMATTAGDETAILS16 paftd,
+ DWORD dwInstance, DWORD fdwSupport
+);
+
+/***********************************************************************
+ * Functions - Win16
+ */
+
+DWORD WINAPI acmGetVersion16(
+);
+MMRESULT16 WINAPI acmMetrics16(
+ HACMOBJ16 hao, UINT16 uMetric, LPVOID pMetric
+);
+MMRESULT16 WINAPI acmDriverEnum16(
+ ACMDRIVERENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT16 WINAPI acmDriverDetails16(
+ HACMDRIVERID16 hadid, LPACMDRIVERDETAILS16 padd, DWORD fdwDetails
+);
+MMRESULT16 WINAPI acmDriverAdd16(
+ LPHACMDRIVERID16 phadid, HINSTANCE16 hinstModule,
+ LPARAM lParam, DWORD dwPriority, DWORD fdwAdd
+);
+MMRESULT16 WINAPI acmDriverRemove16(
+ HACMDRIVERID16 hadid, DWORD fdwRemove
+);
+MMRESULT16 WINAPI acmDriverOpen16(
+ LPHACMDRIVER16 phad, HACMDRIVERID16 hadid, DWORD fdwOpen
+);
+MMRESULT16 WINAPI acmDriverClose16(
+ HACMDRIVER16 had, DWORD fdwClose
+);
+LRESULT WINAPI acmDriverMessage16(
+ HACMDRIVER16 had, UINT16 uMsg, LPARAM lParam1, LPARAM lParam2
+);
+MMRESULT16 WINAPI acmDriverID16(
+ HACMOBJ16 hao, LPHACMDRIVERID16 phadid, DWORD fdwDriverID
+);
+MMRESULT16 WINAPI acmDriverPriority16(
+ HACMDRIVERID16 hadid, DWORD dwPriority, DWORD fdwPriority
+);
+MMRESULT16 WINAPI acmFormatTagDetails16(
+ HACMDRIVER16 had, LPACMFORMATTAGDETAILS16 paftd, DWORD fdwDetails
+);
+MMRESULT16 WINAPI acmFormatTagEnum16(
+ HACMDRIVER16 had, LPACMFORMATTAGDETAILS16 paftd,
+ ACMFORMATTAGENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT16 WINAPI acmFormatChoose16(
+ LPACMFORMATCHOOSE16 pafmtc
+);
+MMRESULT16 WINAPI acmFormatDetails16(
+ HACMDRIVER16 had, LPACMFORMATDETAILS16 pafd, DWORD fdwDetails
+);
+MMRESULT16 WINAPI acmFormatEnum16(
+ HACMDRIVER16 had, LPACMFORMATDETAILS16 pafd,
+ ACMFORMATENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT16 WINAPI acmFormatSuggest16(
+ HACMDRIVER16 had, LPWAVEFORMATEX pwfxSrc,
+ LPWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest
+);
+MMRESULT16 WINAPI acmFilterTagDetails16(
+ HACMDRIVER16 had, LPACMFILTERTAGDETAILS16 paftd, DWORD fdwDetails
+);
+MMRESULT16 WINAPI acmFilterTagEnum16(
+ HACMDRIVER16 had, LPACMFILTERTAGDETAILS16 paftd,
+ ACMFILTERTAGENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT16 WINAPI acmFilterChoose16(
+ LPACMFILTERCHOOSE16 pafltrc
+);
+MMRESULT16 WINAPI acmFilterDetails16(
+ HACMDRIVER16 had, LPACMFILTERDETAILS16 pafd, DWORD fdwDetails
+);
+MMRESULT16 WINAPI acmFilterEnum16(
+ HACMDRIVER16 had, LPACMFILTERDETAILS16 pafd,
+ ACMFILTERENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT16 WINAPI acmStreamOpen16(
+ LPHACMSTREAM16 phas, HACMDRIVER16 had,
+ LPWAVEFORMATEX pwfxSrc, LPWAVEFORMATEX pwfxDst,
+ LPWAVEFILTER pwfltr, DWORD dwCallback,
+ DWORD dwInstance, DWORD fdwOpen
+);
+MMRESULT16 WINAPI acmStreamClose16(
+ HACMSTREAM16 has, DWORD fdwClose
+);
+MMRESULT16 WINAPI acmStreamSize16(
+ HACMSTREAM16 has, DWORD cbInput,
+ LPDWORD pdwOutputBytes, DWORD fdwSize
+);
+MMRESULT16 WINAPI acmStreamConvert16(
+ HACMSTREAM16 has, LPACMSTREAMHEADER16 pash, DWORD fdwConvert
+);
+MMRESULT16 WINAPI acmStreamReset16(
+ HACMSTREAM16 has, DWORD fdwReset
+);
+MMRESULT16 WINAPI acmStreamPrepareHeader16(
+ HACMSTREAM16 has, LPACMSTREAMHEADER16 pash, DWORD fdwPrepare
+);
+MMRESULT16 WINAPI acmStreamUnprepareHeader16(
+ HACMSTREAM16 has, LPACMSTREAMHEADER16 pash, DWORD fdwUnprepare
+);
+
+/***********************************************************************
+ * Functions - Win32
+ */
+
+MMRESULT WINAPI acmDriverAddA(
+ PHACMDRIVERID phadid, HINSTANCE hinstModule,
+ LPARAM lParam, DWORD dwPriority, DWORD fdwAdd
+);
+MMRESULT WINAPI acmDriverAddW(
+ PHACMDRIVERID phadid, HINSTANCE hinstModule,
+ LPARAM lParam, DWORD dwPriority, DWORD fdwAdd
+);
+MMRESULT WINAPI acmDriverClose(
+ HACMDRIVER had, DWORD fdwClose
+);
+MMRESULT WINAPI acmDriverDetailsA(
+ HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmDriverDetailsW(
+ HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmDriverEnum(
+ ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmDriverID(
+ HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID
+);
+LRESULT WINAPI acmDriverMessage(
+ HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2
+);
+MMRESULT WINAPI acmDriverOpen(
+ PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen
+);
+MMRESULT WINAPI acmDriverPriority(
+ HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority
+);
+MMRESULT WINAPI acmDriverRemove(
+ HACMDRIVERID hadid, DWORD fdwRemove
+);
+MMRESULT WINAPI acmFilterChooseA(
+ PACMFILTERCHOOSEA pafltrc
+);
+MMRESULT WINAPI acmFilterChooseW(
+ PACMFILTERCHOOSEW pafltrc
+);
+MMRESULT WINAPI acmFilterDetailsA(
+ HACMDRIVER had, PACMFILTERDETAILSA pafd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFilterDetailsW(
+ HACMDRIVER had, PACMFILTERDETAILSW pafd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFilterEnumA(
+ HACMDRIVER had, PACMFILTERDETAILSA pafd,
+ ACMFILTERENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFilterEnumW(
+ HACMDRIVER had, PACMFILTERDETAILSW pafd,
+ ACMFILTERENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFilterTagDetailsA(
+ HACMDRIVER had, PACMFILTERTAGDETAILSA paftd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFilterTagDetailsW(
+ HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFilterTagEnumA(
+ HACMDRIVER had, PACMFILTERTAGDETAILSA paftd,
+ ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFilterTagEnumW(
+ HACMDRIVER had, PACMFILTERTAGDETAILSW paftd,
+ ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFormatChooseA(
+ PACMFORMATCHOOSEA pafmtc
+);
+MMRESULT WINAPI acmFormatChooseW(
+ PACMFORMATCHOOSEW pafmtc
+);
+MMRESULT WINAPI acmFormatDetailsA(
+ HACMDRIVER had, PACMFORMATDETAILSA pafd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFormatDetailsW(
+ HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFormatEnumA(
+ HACMDRIVER had, PACMFORMATDETAILSA pafd,
+ ACMFORMATENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFormatEnumW(
+ HACMDRIVER had, PACMFORMATDETAILSW pafd,
+ ACMFORMATENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFormatSuggest(
+ HACMDRIVER had, PWAVEFORMATEX pwfxSrc, PWAVEFORMATEX pwfxDst,
+ DWORD cbwfxDst, DWORD fdwSuggest
+);
+MMRESULT WINAPI acmFormatTagDetailsA(
+ HACMDRIVER had, PACMFORMATTAGDETAILSA paftd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFormatTagDetailsW(
+ HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, DWORD fdwDetails
+);
+MMRESULT WINAPI acmFormatTagEnumA(
+ HACMDRIVER had, PACMFORMATTAGDETAILSA paftd,
+ ACMFORMATTAGENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+MMRESULT WINAPI acmFormatTagEnumW(
+ HACMDRIVER had, PACMFORMATTAGDETAILSW paftd,
+ ACMFORMATTAGENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum
+);
+DWORD WINAPI acmGetVersion(
+);
+MMRESULT WINAPI acmMetrics(
+ HACMOBJ hao, UINT uMetric, LPVOID pMetric
+);
+MMRESULT WINAPI acmStreamClose(
+ HACMSTREAM has, DWORD fdwClose
+);
+MMRESULT WINAPI acmStreamConvert(
+ HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwConvert
+);
+MMRESULT WINAPI acmStreamMessage(
+ HACMSTREAM has, UINT uMsg, LPARAM lParam1, LPARAM lParam2
+);
+MMRESULT WINAPI acmStreamOpen(
+ PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc,
+ PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback,
+ DWORD dwInstance, DWORD fdwOpen
+);
+MMRESULT WINAPI acmStreamPrepareHeader(
+ HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwPrepare
+);
+MMRESULT WINAPI acmStreamReset(
+ HACMSTREAM has, DWORD fdwReset
+);
+MMRESULT WINAPI acmStreamSize(
+ HACMSTREAM has, DWORD cbInput,
+ LPDWORD pdwOutputBytes, DWORD fdwSize
+);
+MMRESULT WINAPI acmStreamUnprepareHeader(
+ HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwUnprepare
+);
+void MSACM_RegisterAllDrivers(void);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* __WINE_MSACM_H */
+
+
diff --git a/src/libw32dll/wine/msacmdrv.h b/src/libw32dll/wine/msacmdrv.h
new file mode 100644
index 000000000..2e23a17d7
--- /dev/null
+++ b/src/libw32dll/wine/msacmdrv.h
@@ -0,0 +1,203 @@
+/*
+ * msacmdrv.h - Declarations for MSACM driver
+ */
+
+#ifndef __WINE_MSACMDRV_H
+#define __WINE_MSACMDRV_H
+
+#include "windef.h"
+#include "msacm.h"
+
+/***********************************************************************
+ * Types
+ */
+
+/***********************************************************************
+ * Defines/Enums
+ */
+
+#define MAKE_ACM_VERSION(mjr, mnr, bld) \
+ (((long)(mjr)<<24) | ((long)(mnr)<<16) | ((long)bld))
+
+#define ACMDRVOPENDESC_SECTIONNAME_CHARS
+
+#define ACMDM_DRIVER_NOTIFY (ACMDM_BASE + 1)
+#define ACMDM_DRIVER_DETAILS (ACMDM_BASE + 10)
+
+#define ACMDM_HARDWARE_WAVE_CAPS_INPUT (ACMDM_BASE + 20)
+#define ACMDM_HARDWARE_WAVE_CAPS_OUTPUT (ACMDM_BASE + 21)
+
+#define ACMDM_FORMATTAG_DETAILS (ACMDM_BASE + 25)
+#define ACMDM_FORMAT_DETAILS (ACMDM_BASE + 26)
+#define ACMDM_FORMAT_SUGGEST (ACMDM_BASE + 27)
+
+#define ACMDM_FILTERTAG_DETAILS (ACMDM_BASE + 50)
+#define ACMDM_FILTER_DETAILS (ACMDM_BASE + 51)
+
+#define ACMDM_STREAM_OPEN (ACMDM_BASE + 76)
+#define ACMDM_STREAM_CLOSE (ACMDM_BASE + 77)
+#define ACMDM_STREAM_SIZE (ACMDM_BASE + 78)
+#define ACMDM_STREAM_CONVERT (ACMDM_BASE + 79)
+#define ACMDM_STREAM_RESET (ACMDM_BASE + 80)
+#define ACMDM_STREAM_PREPARE (ACMDM_BASE + 81)
+#define ACMDM_STREAM_UNPREPARE (ACMDM_BASE + 82)
+#define ACMDM_STREAM_UPDATE (ACMDM_BASE + 83)
+
+/***********************************************************************
+ * Structures
+ */
+
+typedef struct _ACMDRVOPENDESCA
+{
+ DWORD cbStruct;
+ FOURCC fccType;
+ FOURCC fccComp;
+ DWORD dwVersion;
+ DWORD dwFlags;
+ DWORD dwError;
+ LPCSTR pszSectionName;
+ LPCSTR pszAliasName;
+ DWORD dnDevNode;
+} ACMDRVOPENDESCA, *PACMDRVOPENDESCA;
+
+typedef struct _ACMDRVOPENDESCW
+{
+ DWORD cbStruct;
+ FOURCC fccType;
+ FOURCC fccComp;
+ DWORD dwVersion;
+ DWORD dwFlags;
+ DWORD dwError;
+ LPCWSTR pszSectionName;
+ LPCWSTR pszAliasName;
+ DWORD dnDevNode;
+} ACMDRVOPENDESCW, *PACMDRVOPENDESCW;
+
+typedef struct _ACMDRVOPENDESC16
+{
+ DWORD cbStruct;
+ FOURCC fccType;
+ FOURCC fccComp;
+ DWORD dwVersion;
+ DWORD dwFlags;
+ DWORD dwError;
+ LPCSTR pszSectionName;
+ LPCSTR pszAliasName;
+ DWORD dnDevNode;
+} ACMDRVOPENDESC16, *NPACMDRVOPENDESC16, *LPACMDRVOPENDESC16;
+
+typedef struct _ACMDRVSTREAMINSTANCE16
+{
+ DWORD cbStruct;
+ LPWAVEFORMATEX pwfxSrc;
+ LPWAVEFORMATEX pwfxDst;
+ LPWAVEFILTER pwfltr;
+ DWORD dwCallback;
+ DWORD dwInstance;
+ DWORD fdwOpen;
+ DWORD fdwDriver;
+ DWORD dwDriver;
+ HACMSTREAM16 has;
+} ACMDRVSTREAMINSTANCE16, *NPACMDRVSTREAMINSTANCE16, *LPACMDRVSTREAMINSTANCE16;
+
+typedef struct _ACMDRVSTREAMINSTANCE
+{
+ DWORD cbStruct;
+ PWAVEFORMATEX pwfxSrc;
+ PWAVEFORMATEX pwfxDst;
+ PWAVEFILTER pwfltr;
+ DWORD dwCallback;
+ DWORD dwInstance;
+ DWORD fdwOpen;
+ DWORD fdwDriver;
+ DWORD dwDriver;
+ HACMSTREAM has;
+} ACMDRVSTREAMINSTANCE, *PACMDRVSTREAMINSTANCE;
+
+
+typedef struct _ACMDRVSTREAMHEADER16 *LPACMDRVSTREAMHEADER16;
+typedef struct _ACMDRVSTREAMHEADER16 {
+ DWORD cbStruct;
+ DWORD fdwStatus;
+ DWORD dwUser;
+ LPBYTE pbSrc;
+ DWORD cbSrcLength;
+ DWORD cbSrcLengthUsed;
+ DWORD dwSrcUser;
+ LPBYTE pbDst;
+ DWORD cbDstLength;
+ DWORD cbDstLengthUsed;
+ DWORD dwDstUser;
+
+ DWORD fdwConvert;
+ LPACMDRVSTREAMHEADER16 *padshNext;
+ DWORD fdwDriver;
+ DWORD dwDriver;
+
+ /* Internal fields for ACM */
+ DWORD fdwPrepared;
+ DWORD dwPrepared;
+ LPBYTE pbPreparedSrc;
+ DWORD cbPreparedSrcLength;
+ LPBYTE pbPreparedDst;
+ DWORD cbPreparedDstLength;
+} ACMDRVSTREAMHEADER16, *NPACMDRVSTREAMHEADER16;
+
+typedef struct _ACMDRVSTREAMHEADER *PACMDRVSTREAMHEADER;
+typedef struct _ACMDRVSTREAMHEADER {
+ DWORD cbStruct;
+ DWORD fdwStatus;
+ DWORD dwUser;
+ LPBYTE pbSrc;
+ DWORD cbSrcLength;
+ DWORD cbSrcLengthUsed;
+ DWORD dwSrcUser;
+ LPBYTE pbDst;
+ DWORD cbDstLength;
+ DWORD cbDstLengthUsed;
+ DWORD dwDstUser;
+
+ DWORD fdwConvert;
+ PACMDRVSTREAMHEADER *padshNext;
+ DWORD fdwDriver;
+ DWORD dwDriver;
+
+ /* Internal fields for ACM */
+ DWORD fdwPrepared;
+ DWORD dwPrepared;
+ LPBYTE pbPreparedSrc;
+ DWORD cbPreparedSrcLength;
+ LPBYTE pbPreparedDst;
+ DWORD cbPreparedDstLength;
+} ACMDRVSTREAMHEADER;
+
+typedef struct _ACMDRVSTREAMSIZE
+{
+ DWORD cbStruct;
+ DWORD fdwSize;
+ DWORD cbSrcLength;
+ DWORD cbDstLength;
+} ACMDRVSTREAMSIZE16, *NPACMDRVSTREAMSIZE16, *LPACMDRVSTREAMSIZE16,
+ ACMDRVSTREAMSIZE, *PACMDRVSTREAMSIZE;
+
+typedef struct _ACMDRVFORMATSUGGEST16
+{
+ DWORD cbStruct;
+ DWORD fdwSuggest;
+ LPWAVEFORMATEX pwfxSrc;
+ DWORD cbwfxSrc;
+ LPWAVEFORMATEX pwfxDst;
+ DWORD cbwfxDst;
+} ACMDRVFORMATSUGGEST16, *NPACMDRVFORMATSUGGEST, *LPACMDRVFORMATSUGGEST;
+
+typedef struct _ACMDRVFORMATSUGGEST
+{
+ DWORD cbStruct;
+ DWORD fdwSuggest;
+ PWAVEFORMATEX pwfxSrc;
+ DWORD cbwfxSrc;
+ PWAVEFORMATEX pwfxDst;
+ DWORD cbwfxDst;
+} ACMDRVFORMATSUGGEST, *PACMDRVFORMATSUGGEST;
+
+#endif /* __WINE_MSACMDRV_H */
diff --git a/src/libw32dll/wine/ntdef.h b/src/libw32dll/wine/ntdef.h
new file mode 100644
index 000000000..edf0af86c
--- /dev/null
+++ b/src/libw32dll/wine/ntdef.h
@@ -0,0 +1,101 @@
+#ifndef __WINE_NTDEF_H
+#define __WINE_NTDEF_H
+
+#include "basetsd.h"
+#include "windef.h"
+
+#include "pshpack1.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NTAPI __stdcall
+
+#ifndef IN
+#define IN
+#endif
+
+#ifndef OUT
+#define OUT
+#endif
+
+#ifndef OPTIONAL
+#define OPTIONAL
+#endif
+
+#ifndef VOID
+#define VOID void
+#endif
+
+typedef LONG NTSTATUS;
+typedef NTSTATUS *PNTSTATUS;
+
+typedef short CSHORT;
+typedef CSHORT *PCSHORT;
+
+typedef WCHAR * PWCHAR;
+
+/* NT lowlevel Strings (handled by Rtl* functions in NTDLL)
+ * If they are zero terminated, Length does not include the terminating 0.
+ */
+
+typedef struct _STRING {
+ USHORT Length;
+ USHORT MaximumLength;
+ PSTR Buffer;
+} STRING,*PSTRING,ANSI_STRING,*PANSI_STRING;
+
+typedef struct _CSTRING {
+ USHORT Length;
+ USHORT MaximumLength;
+ PCSTR Buffer;
+} CSTRING,*PCSTRING;
+
+typedef struct _UNICODE_STRING {
+ USHORT Length; /* bytes */
+ USHORT MaximumLength; /* bytes */
+ PWSTR Buffer;
+} UNICODE_STRING,*PUNICODE_STRING;
+
+/*
+ Objects
+*/
+
+#define OBJ_INHERIT 0x00000002L
+#define OBJ_PERMANENT 0x00000010L
+#define OBJ_EXCLUSIVE 0x00000020L
+#define OBJ_CASE_INSENSITIVE 0x00000040L
+#define OBJ_OPENIF 0x00000080L
+#define OBJ_OPENLINK 0x00000100L
+#define OBJ_KERNEL_HANDLE 0x00000200L
+#define OBJ_VALID_ATTRIBUTES 0x000003F2L
+
+typedef struct _OBJECT_ATTRIBUTES
+{ ULONG Length;
+ HANDLE RootDirectory;
+ PUNICODE_STRING ObjectName;
+ ULONG Attributes;
+ PVOID SecurityDescriptor; /* type SECURITY_DESCRIPTOR */
+ PVOID SecurityQualityOfService; /* type SECURITY_QUALITY_OF_SERVICE */
+} OBJECT_ATTRIBUTES;
+
+typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
+
+#define InitializeObjectAttributes(p,n,a,r,s) \
+{ (p)->Length = sizeof(OBJECT_ATTRIBUTES); \
+ (p)->RootDirectory = r; \
+ (p)->Attributes = a; \
+ (p)->ObjectName = n; \
+ (p)->SecurityDescriptor = s; \
+ (p)->SecurityQualityOfService = NULL; \
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "poppack.h"
+
+#endif
diff --git a/src/libw32dll/wine/pe_image.h b/src/libw32dll/wine/pe_image.h
new file mode 100644
index 000000000..9b4f322c6
--- /dev/null
+++ b/src/libw32dll/wine/pe_image.h
@@ -0,0 +1,81 @@
+#ifndef __WINE_PE_IMAGE_H
+#define __WINE_PE_IMAGE_H
+
+#include "windef.h"
+#include "winbase.h"
+
+#define PE_HEADER(module) \
+ ((IMAGE_NT_HEADERS*)((LPBYTE)(module) + \
+ (((IMAGE_DOS_HEADER*)(module))->e_lfanew)))
+
+#define PE_SECTIONS(module) \
+ ((IMAGE_SECTION_HEADER*)((LPBYTE)&PE_HEADER(module)->OptionalHeader + \
+ PE_HEADER(module)->FileHeader.SizeOfOptionalHeader))
+
+#define RVA_PTR(module,field) ((LPBYTE)(module) + PE_HEADER(module)->field)
+
+/* modreference used for attached processes
+ * all section are calculated here, relocations etc.
+ */
+typedef struct {
+ PIMAGE_IMPORT_DESCRIPTOR pe_import;
+ PIMAGE_EXPORT_DIRECTORY pe_export;
+ PIMAGE_RESOURCE_DIRECTORY pe_resource;
+ int tlsindex;
+} PE_MODREF;
+
+struct _wine_modref;
+extern int PE_unloadImage(HMODULE hModule);
+extern FARPROC PE_FindExportedFunction(struct _wine_modref *wm, LPCSTR funcName, WIN_BOOL snoop);
+extern WIN_BOOL PE_EnumResourceTypesA(HMODULE,ENUMRESTYPEPROCA,LONG);
+extern WIN_BOOL PE_EnumResourceTypesW(HMODULE,ENUMRESTYPEPROCW,LONG);
+extern WIN_BOOL PE_EnumResourceNamesA(HMODULE,LPCSTR,ENUMRESNAMEPROCA,LONG);
+extern WIN_BOOL PE_EnumResourceNamesW(HMODULE,LPCWSTR,ENUMRESNAMEPROCW,LONG);
+extern WIN_BOOL PE_EnumResourceLanguagesA(HMODULE,LPCSTR,LPCSTR,ENUMRESLANGPROCA,LONG);
+extern WIN_BOOL PE_EnumResourceLanguagesW(HMODULE,LPCWSTR,LPCWSTR,ENUMRESLANGPROCW,LONG);
+extern HRSRC PE_FindResourceExW(struct _wine_modref*,LPCWSTR,LPCWSTR,WORD);
+extern DWORD PE_SizeofResource(HMODULE,HRSRC);
+extern struct _wine_modref *PE_LoadLibraryExA(LPCSTR, DWORD);
+extern void PE_UnloadLibrary(struct _wine_modref *);
+extern HGLOBAL PE_LoadResource(struct _wine_modref *wm,HRSRC);
+extern HMODULE PE_LoadImage( int hFile, LPCSTR filename, WORD *version );
+extern struct _wine_modref *PE_CreateModule( HMODULE hModule, LPCSTR filename,
+ DWORD flags, WIN_BOOL builtin );
+extern WIN_BOOL PE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env,
+ LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa,
+ WIN_BOOL inherit, DWORD flags, LPSTARTUPINFOA startup,
+ LPPROCESS_INFORMATION info );
+
+extern void PE_InitTls(void);
+extern WIN_BOOL PE_InitDLL(struct _wine_modref *wm, DWORD type, LPVOID lpReserved);
+
+extern PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(PIMAGE_RESOURCE_DIRECTORY,LPCSTR,DWORD,WIN_BOOL);
+extern PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY,LPCWSTR,DWORD,WIN_BOOL);
+
+typedef DWORD CALLBACK (*DLLENTRYPROC)(HMODULE,DWORD,LPVOID);
+
+typedef struct {
+ WORD popl WINE_PACKED; /* 0x8f 0x05 */
+ DWORD addr_popped WINE_PACKED;/* ... */
+ BYTE pushl1 WINE_PACKED; /* 0x68 */
+ DWORD newret WINE_PACKED; /* ... */
+ BYTE pushl2 WINE_PACKED; /* 0x68 */
+ DWORD origfun WINE_PACKED; /* original function */
+ BYTE ret1 WINE_PACKED; /* 0xc3 */
+ WORD addesp WINE_PACKED; /* 0x83 0xc4 */
+ BYTE nrofargs WINE_PACKED; /* nr of arguments to add esp, */
+ BYTE pushl3 WINE_PACKED; /* 0x68 */
+ DWORD oldret WINE_PACKED; /* Filled out from popl above */
+ BYTE ret2 WINE_PACKED; /* 0xc3 */
+} ELF_STDCALL_STUB;
+
+typedef struct {
+ void* dlhandle;
+ ELF_STDCALL_STUB *stubs;
+} ELF_MODREF;
+
+extern struct _wine_modref *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags);
+extern void ELF_UnloadLibrary(struct _wine_modref *);
+extern FARPROC ELF_FindExportedFunction(struct _wine_modref *wm, LPCSTR funcName);
+
+#endif /* __WINE_PE_IMAGE_H */
diff --git a/src/libw32dll/wine/poppack.h b/src/libw32dll/wine/poppack.h
new file mode 100644
index 000000000..710479159
--- /dev/null
+++ b/src/libw32dll/wine/poppack.h
@@ -0,0 +1,15 @@
+#ifdef __WINE_PSHPACK_H
+#undef __WINE_PSHPACK_H
+
+#if defined(__GNUC__) || defined(__SUNPRO_C)
+#pragma pack()
+#elif defined(__SUNPRO_CC)
+#warning "Assumes default alignment is 4"
+#pragma pack(4)
+#elif !defined(RC_INVOKED)
+#error "Restoration of the previous alignment isn't supported by the compiler"
+#endif /* defined(__GNUC__) || defined(__SUNPRO_C) ; !defined(RC_INVOKED) */
+
+#else /* defined(__WINE_PSHPACK_H) */
+#error "Popping alignment isn't possible since no alignment has been pushed"
+#endif /* defined(__WINE_PSHPACK_H) */
diff --git a/src/libw32dll/wine/pshpack1.h b/src/libw32dll/wine/pshpack1.h
new file mode 100644
index 000000000..e560250c2
--- /dev/null
+++ b/src/libw32dll/wine/pshpack1.h
@@ -0,0 +1,13 @@
+#ifndef __WINE_PSHPACK_H
+#define __WINE_PSHPACK_H 1
+
+#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+//#pragma pack(1)
+#elif !defined(RC_INVOKED)
+#error "1 as alignment isn't supported by the compiler"
+#endif /* defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */
+
+#else /* !defined(__WINE_PSHPACK_H) */
+#error "Nested pushing of alignment isn't supported by the compiler"
+#endif /* !defined(__WINE_PSHPACK_H) */
+
diff --git a/src/libw32dll/wine/pshpack2.h b/src/libw32dll/wine/pshpack2.h
new file mode 100644
index 000000000..887b1e17b
--- /dev/null
+++ b/src/libw32dll/wine/pshpack2.h
@@ -0,0 +1,12 @@
+#ifndef __WINE_PSHPACK_H
+#define __WINE_PSHPACK_H 2
+
+#if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+//#pragma pack(2)
+#elif !defined(RC_INVOKED)
+#error "2 as alignment isn't supported by the compiler"
+#endif /* defined(__GNUC__) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */
+
+#else /* !defined(__WINE_PSHPACK_H) */
+#error "Nested pushing of alignment isn't supported by the compiler"
+#endif /* !defined(__WINE_PSHPACK_H) */
diff --git a/src/libw32dll/wine/pshpack4.h b/src/libw32dll/wine/pshpack4.h
new file mode 100644
index 000000000..9fdaf70a7
--- /dev/null
+++ b/src/libw32dll/wine/pshpack4.h
@@ -0,0 +1,15 @@
+#ifndef __WINE_PSHPACK_H
+#define __WINE_PSHPACK_H 4
+
+#if defined(__GNUC__) || defined(__SUNPRO_CC)
+//#pragma pack(4)
+#elif defined(__SUNPRO_C)
+//#pragma pack()
+#elif !defined(RC_INVOKED)
+#error "4 as alignment isn't supported by the compiler"
+#endif /* defined(__GNUC__) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */
+
+#else /* !defined(__WINE_PSHPACK_H) */
+#error "Nested pushing of alignment isn't supported by the compiler"
+#endif /* !defined(__WINE_PSHPACK_H) */
+
diff --git a/src/libw32dll/wine/pshpack8.h b/src/libw32dll/wine/pshpack8.h
new file mode 100644
index 000000000..74d13a472
--- /dev/null
+++ b/src/libw32dll/wine/pshpack8.h
@@ -0,0 +1,12 @@
+#ifndef __WINE_PSHPACK_H
+#define __WINE_PSHPACK_H 8
+
+#if 0
+//#pragma pack(8)
+#elif !defined(RC_INVOKED)
+#error "8 as alignment is not supported"
+#endif /* 0 ; !defined(RC_INVOKED) */
+
+#else /* !defined(__WINE_PSHPACK_H) */
+#error "Nested pushing of alignment isn't supported by the compiler"
+#endif /* !defined(__WINE_PSHPACK_H) */
diff --git a/src/libw32dll/wine/vfw.h b/src/libw32dll/wine/vfw.h
new file mode 100644
index 000000000..e2bc145d8
--- /dev/null
+++ b/src/libw32dll/wine/vfw.h
@@ -0,0 +1,654 @@
+#ifndef __WINE_VFW_H
+#define __WINE_VFW_H
+//#include "pshpack1.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifndef __WINE_WINGDI_H
+
+typedef struct
+{
+ short bfType;
+ long bfSize;
+ short bfReserved1;
+ short bfReserved2;
+ long bfOffBits;
+} BITMAPFILEHEADER;
+
+typedef struct
+{
+ long biSize;
+ long biWidth;
+ long biHeight;
+ short biPlanes;
+ short biBitCount;
+ long biCompression;
+ long biSizeImage;
+ long biXPelsPerMeter;
+ long biYPelsPerMeter;
+ long biClrUsed;
+ long biClrImportant;
+} BITMAPINFOHEADER, *PBITMAPINFOHEADER, *LPBITMAPINFOHEADER;
+typedef struct {
+ BITMAPINFOHEADER bmiHeader;
+ int bmiColors[1];
+} BITMAPINFO, *LPBITMAPINFO;
+#endif
+#define VFWAPI
+#define VFWAPIV
+#ifndef __WINE_WINDEF_H
+typedef long (__stdcall__ *DRIVERPROC)(long,HDRVR,unsigned int,long,long);
+#endif
+
+
+
+#ifndef mmioFOURCC
+#define mmioFOURCC( ch0, ch1, ch2, ch3 ) \
+ ( (long)(unsigned char)(ch0) | ( (long)(unsigned char)(ch1) << 8 ) | \
+ ( (long)(unsigned char)(ch2) << 16 ) | ( (long)(unsigned char)(ch3) << 24 ) )
+#endif
+
+#ifndef aviTWOCC
+#define aviTWOCC(ch0, ch1) ((short)(unsigned char)(ch0) | ((short)(unsigned char)(ch1) << 8))
+#endif
+
+#define ICTYPE_VIDEO mmioFOURCC('v', 'i', 'd', 'c')
+#define ICTYPE_AUDIO mmioFOURCC('a', 'u', 'd', 'c')
+
+
+/* Installable Compressor M? */
+
+/* HIC struct (same layout as Win95 one) */
+typedef struct tagWINE_HIC {
+ long magic; /* 00: 'Smag' */
+ HANDLE curthread; /* 04: */
+ long type; /* 08: */
+ long handler; /* 0C: */
+ HDRVR hdrv; /* 10: */
+#ifndef __cplusplus
+ long private; /* 14:(handled by SendDriverMessage)*/
+#else
+ long _private; /* 14:(handled by SendDriverMessage)*/
+#endif
+ DRIVERPROC driverproc; /* 18:(handled by SendDriverMessage)*/
+ long x1; /* 1c: name? */
+ short x2; /* 20: */
+ long x3; /* 22: */
+ /* 26: */
+} WINE_HIC;
+
+/* error return codes */
+#define ICERR_OK 0
+#define ICERR_DONTDRAW 1
+#define ICERR_NEWPALETTE 2
+#define ICERR_GOTOKEYFRAME 3
+#define ICERR_STOPDRAWING 4
+
+#define ICERR_UNSUPPORTED -1
+#define ICERR_BADFORMAT -2
+#define ICERR_MEMORY -3
+#define ICERR_INTERNAL -4
+#define ICERR_BADFLAGS -5
+#define ICERR_BADPARAM -6
+#define ICERR_BADSIZE -7
+#define ICERR_BADHANDLE -8
+#define ICERR_CANTUPDATE -9
+#define ICERR_ABORT -10
+#define ICERR_ERROR -100
+#define ICERR_BADBITDEPTH -200
+#define ICERR_BADIMAGESIZE -201
+
+#define ICERR_CUSTOM -400
+
+/* ICM Messages */
+#define ICM_USER (DRV_USER+0x0000)
+
+/* ICM driver message range */
+#define ICM_RESERVED_LOW (DRV_USER+0x1000)
+#define ICM_RESERVED_HIGH (DRV_USER+0x2000)
+#define ICM_RESERVED ICM_RESERVED_LOW
+
+#define ICM_GETSTATE (ICM_RESERVED+0)
+#define ICM_SETSTATE (ICM_RESERVED+1)
+#define ICM_GETINFO (ICM_RESERVED+2)
+
+#define ICM_CONFIGURE (ICM_RESERVED+10)
+#define ICM_ABOUT (ICM_RESERVED+11)
+/* */
+
+#define ICM_GETDEFAULTQUALITY (ICM_RESERVED+30)
+#define ICM_GETQUALITY (ICM_RESERVED+31)
+#define ICM_SETQUALITY (ICM_RESERVED+32)
+
+#define ICM_SET (ICM_RESERVED+40)
+#define ICM_GET (ICM_RESERVED+41)
+
+/* 2 constant FOURCC codes */
+#define ICM_FRAMERATE mmioFOURCC('F','r','m','R')
+#define ICM_KEYFRAMERATE mmioFOURCC('K','e','y','R')
+
+#define ICM_COMPRESS_GET_FORMAT (ICM_USER+4)
+#define ICM_COMPRESS_GET_SIZE (ICM_USER+5)
+#define ICM_COMPRESS_QUERY (ICM_USER+6)
+#define ICM_COMPRESS_BEGIN (ICM_USER+7)
+#define ICM_COMPRESS (ICM_USER+8)
+#define ICM_COMPRESS_END (ICM_USER+9)
+
+#define ICM_DECOMPRESS_GET_FORMAT (ICM_USER+10)
+#define ICM_DECOMPRESS_QUERY (ICM_USER+11)
+#define ICM_DECOMPRESS_BEGIN (ICM_USER+12)
+#define ICM_DECOMPRESS (ICM_USER+13)
+#define ICM_DECOMPRESS_END (ICM_USER+14)
+#define ICM_DECOMPRESS_SET_PALETTE (ICM_USER+29)
+#define ICM_DECOMPRESS_GET_PALETTE (ICM_USER+30)
+
+#define ICM_DRAW_QUERY (ICM_USER+31)
+#define ICM_DRAW_BEGIN (ICM_USER+15)
+#define ICM_DRAW_GET_PALETTE (ICM_USER+16)
+#define ICM_DRAW_START (ICM_USER+18)
+#define ICM_DRAW_STOP (ICM_USER+19)
+#define ICM_DRAW_END (ICM_USER+21)
+#define ICM_DRAW_GETTIME (ICM_USER+32)
+#define ICM_DRAW (ICM_USER+33)
+#define ICM_DRAW_WINDOW (ICM_USER+34)
+#define ICM_DRAW_SETTIME (ICM_USER+35)
+#define ICM_DRAW_REALIZE (ICM_USER+36)
+#define ICM_DRAW_FLUSH (ICM_USER+37)
+#define ICM_DRAW_RENDERBUFFER (ICM_USER+38)
+
+#define ICM_DRAW_START_PLAY (ICM_USER+39)
+#define ICM_DRAW_STOP_PLAY (ICM_USER+40)
+
+#define ICM_DRAW_SUGGESTFORMAT (ICM_USER+50)
+#define ICM_DRAW_CHANGEPALETTE (ICM_USER+51)
+
+#define ICM_GETBUFFERSWANTED (ICM_USER+41)
+
+#define ICM_GETDEFAULTKEYFRAMERATE (ICM_USER+42)
+
+#define ICM_DECOMPRESSEX_BEGIN (ICM_USER+60)
+#define ICM_DECOMPRESSEX_QUERY (ICM_USER+61)
+#define ICM_DECOMPRESSEX (ICM_USER+62)
+#define ICM_DECOMPRESSEX_END (ICM_USER+63)
+
+#define ICM_COMPRESS_FRAMES_INFO (ICM_USER+70)
+#define ICM_SET_STATUS_PROC (ICM_USER+72)
+
+/* structs */
+
+typedef struct {
+ long dwSize; /* 00: size */
+ long fccType; /* 04: type 'vidc' usually */
+ long fccHandler; /* 08: */
+ long dwVersion; /* 0c: version of compman opening you */
+ long dwFlags; /* 10: LOshort is type specific */
+ LRESULT dwError; /* 14: */
+ void* pV1Reserved; /* 18: */
+ void* pV2Reserved; /* 1c: */
+ long dnDevNode; /* 20: */
+ /* 24: */
+} ICOPEN,*LPICOPEN;
+
+#define ICCOMPRESS_KEYFRAME 0x00000001L
+
+typedef struct {
+ long dwFlags;
+ LPBITMAPINFOHEADER lpbiOutput;
+ void* lpOutput;
+ LPBITMAPINFOHEADER lpbiInput;
+ void* lpInput;
+ long* lpckid;
+ long* lpdwFlags;
+ long lFrameNum;
+ long dwFrameSize;
+ long dwQuality;
+ LPBITMAPINFOHEADER lpbiPrev;
+ void* lpPrev;
+} ICCOMPRESS;
+
+long VFWAPIV ICCompress(
+ HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpData,
+ LPBITMAPINFOHEADER lpbiInput,void* lpBits,long* lpckid,
+ long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality,
+ LPBITMAPINFOHEADER lpbiPrev,void* lpPrev
+);
+
+
+#define ICCompressGetFormat(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic,ICM_COMPRESS_GET_FORMAT,(long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ )
+
+#define ICCompressGetFormatSize(hic,lpbi) ICCompressGetFormat(hic,lpbi,NULL)
+
+#define ICGetDefaultKeyFrameRate(hic,lpint) \
+ ICSendMessage( \
+ hic, ICM_GETDEFAULTKEYFRAMERATE, \
+ (long)(void*)(lpint), \
+ 0 )
+
+#define ICGetDefaultQuality(hic,lpint) \
+ ICSendMessage( \
+ hic, ICM_GETDEFAULTQUALITY, \
+ (long)(void*)(lpint), \
+ 0 )
+
+
+#define ICCompressBegin(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic, ICM_COMPRESS_BEGIN, (long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ )
+
+#define ICCompressGetSize(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic, ICM_COMPRESS_GET_SIZE, (long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ )
+
+#define ICCompressQuery(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic, ICM_COMPRESS_QUERY, (long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ )
+
+
+#define ICCompressEnd(hic) ICSendMessage(hic, ICM_COMPRESS_END, 0, 0)
+
+/* ICCOMPRESSFRAMES.dwFlags */
+#define ICCOMPRESSFRAMES_PADDING 0x00000001
+typedef struct {
+ long dwFlags;
+ LPBITMAPINFOHEADER lpbiOutput;
+ LPARAM lOutput;
+ LPBITMAPINFOHEADER lpbiInput;
+ LPARAM lInput;
+ long lStartFrame;
+ long lFrameCount;
+ long lQuality;
+ long lDataRate;
+ long lKeyRate;
+ long dwRate;
+ long dwScale;
+ long dwOverheadPerFrame;
+ long dwReserved2;
+ long CALLBACK (*GetData)(LPARAM lInput,long lFrame,void* lpBits,long len);
+ long CALLBACK (*PutData)(LPARAM lOutput,long lFrame,void* lpBits,long len);
+} ICCOMPRESSFRAMES;
+
+/* Values for wMode of ICOpen() */
+#define ICMODE_COMPRESS 1
+#define ICMODE_DECOMPRESS 2
+#define ICMODE_FASTDECOMPRESS 3
+#define ICMODE_QUERY 4
+#define ICMODE_FASTCOMPRESS 5
+#define ICMODE_DRAW 8
+
+/* quality flags */
+#define ICQUALITY_LOW 0
+#define ICQUALITY_HIGH 10000
+#define ICQUALITY_DEFAULT -1
+
+typedef struct {
+ long dwSize; /* 00: */
+ long fccType; /* 04:compressor type 'vidc' 'audc' */
+ long fccHandler; /* 08:compressor sub-type 'rle ' 'jpeg' 'pcm '*/
+ long dwFlags; /* 0c:flags LOshort is type specific */
+ long dwVersion; /* 10:version of the driver */
+ long dwVersionICM; /* 14:version of the ICM used */
+ /*
+ * under Win32, the driver always returns UNICODE strings.
+ */
+ WCHAR szName[16]; /* 18:short name */
+ WCHAR szDescription[128]; /* 38:long name */
+ WCHAR szDriver[128]; /* 138:driver that contains compressor*/
+ /* 238: */
+} ICINFO;
+
+/* ICINFO.dwFlags */
+#define VIDCF_QUALITY 0x0001 /* supports quality */
+#define VIDCF_CRUNCH 0x0002 /* supports crunching to a frame size */
+#define VIDCF_TEMPORAL 0x0004 /* supports inter-frame compress */
+#define VIDCF_COMPRESSFRAMES 0x0008 /* wants the compress all frames message */
+#define VIDCF_DRAW 0x0010 /* supports drawing */
+#define VIDCF_FASTTEMPORALC 0x0020 /* does not need prev frame on compress */
+#define VIDCF_FASTTEMPORALD 0x0080 /* does not need prev frame on decompress */
+#define VIDCF_QUALITYTIME 0x0040 /* supports temporal quality */
+
+#define VIDCF_FASTTEMPORAL (VIDCF_FASTTEMPORALC|VIDCF_FASTTEMPORALD)
+
+
+/* function shortcuts */
+/* ICM_ABOUT */
+#define ICMF_ABOUT_QUERY 0x00000001
+
+#define ICQueryAbout(hic) \
+ (ICSendMessage(hic,ICM_ABOUT,(long)-1,ICMF_ABOUT_QUERY)==ICERR_OK)
+
+#define ICAbout(hic, hwnd) ICSendMessage(hic,ICM_ABOUT,(long)(unsigned int)(hwnd),0)
+
+/* ICM_CONFIGURE */
+#define ICMF_CONFIGURE_QUERY 0x00000001
+#define ICQueryConfigure(hic) \
+ (ICSendMessage(hic,ICM_CONFIGURE,(long)-1,ICMF_CONFIGURE_QUERY)==ICERR_OK)
+
+#define ICConfigure(hic,hwnd) \
+ ICSendMessage(hic,ICM_CONFIGURE,(long)(unsigned int)(hwnd),0)
+
+/* Decompression stuff */
+#define ICDECOMPRESS_HURRYUP 0x80000000 /* don't draw just buffer (hurry up!) */
+#define ICDECOMPRESS_UPDATE 0x40000000 /* don't draw just update screen */
+#define ICDECOMPRESS_PREROL 0x20000000 /* this frame is before real start */
+#define ICDECOMPRESS_NULLFRAME 0x10000000 /* repeat last frame */
+#define ICDECOMPRESS_NOTKEYFRAME 0x08000000 /* this frame is not a key frame */
+
+typedef struct {
+ long dwFlags; /* flags (from AVI index...) */
+ LPBITMAPINFOHEADER lpbiInput; /* BITMAPINFO of compressed data */
+ void* lpInput; /* compressed data */
+ LPBITMAPINFOHEADER lpbiOutput; /* DIB to decompress to */
+ void* lpOutput;
+ long ckid; /* ckid from AVI file */
+} ICDECOMPRESS;
+
+typedef struct {
+ long dwFlags;
+ LPBITMAPINFOHEADER lpbiSrc;
+ void* lpSrc;
+ LPBITMAPINFOHEADER lpbiDst;
+ void* lpDst;
+
+ /* changed for ICM_DECOMPRESSEX */
+ INT xDst; /* destination rectangle */
+ INT yDst;
+ INT dxDst;
+ INT dyDst;
+
+ INT xSrc; /* source rectangle */
+ INT ySrc;
+ INT dxSrc;
+ INT dySrc;
+} ICDECOMPRESSEX;
+
+
+long VFWAPIV ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits);
+
+
+#define ICDecompressBegin(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic, ICM_DECOMPRESS_BEGIN, (long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ )
+
+#define ICDecompressQuery(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic,ICM_DECOMPRESS_QUERY, (long)(void*)(lpbiInput), \
+ (long) (void*)(lpbiOutput) \
+ )
+
+#define ICDecompressGetFormat(hic, lpbiInput, lpbiOutput) \
+ ((long)ICSendMessage( \
+ hic,ICM_DECOMPRESS_GET_FORMAT, (long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ ))
+
+#define ICDecompressGetFormatSize(hic, lpbi) \
+ ICDecompressGetFormat(hic, lpbi, NULL)
+
+#define ICDecompressGetPalette(hic, lpbiInput, lpbiOutput) \
+ ICSendMessage( \
+ hic, ICM_DECOMPRESS_GET_PALETTE, (long)(void*)(lpbiInput), \
+ (long)(void*)(lpbiOutput) \
+ )
+
+#define ICDecompressSetPalette(hic,lpbiPalette) \
+ ICSendMessage( \
+ hic,ICM_DECOMPRESS_SET_PALETTE, \
+ (long)(void*)(lpbiPalette),0 \
+ )
+
+#define ICDecompressEnd(hic) ICSendMessage(hic, ICM_DECOMPRESS_END, 0, 0)
+
+
+#define ICDRAW_QUERY 0x00000001L /* test for support */
+#define ICDRAW_FULLSCREEN 0x00000002L /* draw to full screen */
+#define ICDRAW_HDC 0x00000004L /* draw to a HDC/HWND */
+
+
+WIN_BOOL VFWAPI ICInfo(long fccType, long fccHandler, ICINFO * lpicinfo);
+LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo, long cb);
+HIC VFWAPI ICOpen(long fccType, long fccHandler, UINT wMode);
+HIC VFWAPI ICOpenFunction(long fccType, long fccHandler, unsigned int wMode, void* lpfnHandler);
+
+LRESULT VFWAPI ICClose(HIC hic);
+LRESULT VFWAPI ICSendMessage(HIC hic, unsigned int msg, long dw1, long dw2);
+HIC VFWAPI ICLocate(long fccType, long fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, short wFlags);
+
+int VFWAPI ICDoSomething();
+
+long VFWAPIV ICDrawBegin(
+ HIC hic,
+ long dwFlags,/* flags */
+ HPALETTE hpal, /* palette to draw with */
+ HWND hwnd, /* window to draw to */
+ HDC hdc, /* HDC to draw to */
+ INT xDst, /* destination rectangle */
+ INT yDst,
+ INT dxDst,
+ INT dyDst,
+ LPBITMAPINFOHEADER lpbi, /* format of frame to draw */
+ INT xSrc, /* source rectangle */
+ INT ySrc,
+ INT dxSrc,
+ INT dySrc,
+ long dwRate, /* frames/second = (dwRate/dwScale) */
+ long dwScale
+);
+
+/* as passed to ICM_DRAW_BEGIN (FIXME: correct only for Win32?) */
+typedef struct {
+ long dwFlags;
+ HPALETTE hpal;
+ HWND hwnd;
+ HDC hdc;
+ INT xDst;
+ INT yDst;
+ INT dxDst;
+ INT dyDst;
+ LPBITMAPINFOHEADER lpbi;
+ INT xSrc;
+ INT ySrc;
+ INT dxSrc;
+ INT dySrc;
+ long dwRate;
+ long dwScale;
+} ICDRAWBEGIN;
+
+#define ICDRAW_HURRYUP 0x80000000L /* don't draw just buffer (hurry up!) */
+#define ICDRAW_UPDATE 0x40000000L /* don't draw just update screen */
+#define ICDRAW_PREROLL 0x20000000L /* this frame is before real start */
+#define ICDRAW_NULLFRAME 0x10000000L /* repeat last frame */
+#define ICDRAW_NOTKEYFRAME 0x08000000L /* this frame is not a key frame */
+
+typedef struct {
+ long dwFlags;
+ void* lpFormat;
+ void* lpData;
+ long cbData;
+ long lTime;
+} ICDRAW;
+
+long VFWAPIV ICDraw(HIC hic,long dwFlags,void* lpFormat,void* lpData,long cbData,long lTime);
+
+
+#define AVIGETFRAMEF_BESTDISPLAYFMT 1
+
+typedef struct _AVISTREAMINFOA {
+ long fccType;
+ long fccHandler;
+ long dwFlags; /* AVIIF_* */
+ long dwCaps;
+ short wPriority;
+ short wLanguage;
+ long dwScale;
+ long dwRate; /* dwRate / dwScale == samples/second */
+ long dwStart;
+ long dwLength; /* In units above... */
+ long dwInitialFrames;
+ long dwSuggestedBufferSize;
+ long dwQuality;
+ long dwSampleSize;
+ RECT rcFrame;
+ long dwEditCount;
+ long dwFormatChangeCount;
+ char szName[64];
+} AVISTREAMINFOA, * LPAVISTREAMINFOA, *PAVISTREAMINFOA;
+
+typedef struct _AVISTREAMINFOW {
+ long fccType;
+ long fccHandler;
+ long dwFlags;
+ long dwCaps;
+ short wPriority;
+ short wLanguage;
+ long dwScale;
+ long dwRate; /* dwRate / dwScale == samples/second */
+ long dwStart;
+ long dwLength; /* In units above... */
+ long dwInitialFrames;
+ long dwSuggestedBufferSize;
+ long dwQuality;
+ long dwSampleSize;
+ RECT rcFrame;
+ long dwEditCount;
+ long dwFormatChangeCount;
+ short szName[64];
+} AVISTREAMINFOW, * LPAVISTREAMINFOW, *PAVISTREAMINFOW;
+DECL_WINELIB_TYPE_AW(AVISTREAMINFO)
+DECL_WINELIB_TYPE_AW(LPAVISTREAMINFO)
+DECL_WINELIB_TYPE_AW(PAVISTREAMINFO)
+
+#define AVISTREAMINFO_DISABLED 0x00000001
+#define AVISTREAMINFO_FORMATCHANGES 0x00010000
+
+/* AVIFILEINFO.dwFlags */
+#define AVIFILEINFO_HASINDEX 0x00000010
+#define AVIFILEINFO_MUSTUSEINDEX 0x00000020
+#define AVIFILEINFO_ISINTERLEAVED 0x00000100
+#define AVIFILEINFO_WASCAPTUREFILE 0x00010000
+#define AVIFILEINFO_COPYRIGHTED 0x00020000
+
+/* AVIFILEINFO.dwCaps */
+#define AVIFILECAPS_CANREAD 0x00000001
+#define AVIFILECAPS_CANWRITE 0x00000002
+#define AVIFILECAPS_ALLKEYFRAMES 0x00000010
+#define AVIFILECAPS_NOCOMPRESSION 0x00000020
+
+typedef struct _AVIFILEINFOW {
+ long dwMaxBytesPerSec;
+ long dwFlags;
+ long dwCaps;
+ long dwStreams;
+ long dwSuggestedBufferSize;
+ long dwWidth;
+ long dwHeight;
+ long dwScale;
+ long dwRate;
+ long dwLength;
+ long dwEditCount;
+ short szFileType[64];
+} AVIFILEINFOW, * LPAVIFILEINFOW, *PAVIFILEINFOW;
+
+typedef struct _AVIFILEINFOA {
+ long dwMaxBytesPerSec;
+ long dwFlags;
+ long dwCaps;
+ long dwStreams;
+ long dwSuggestedBufferSize;
+ long dwWidth;
+ long dwHeight;
+ long dwScale;
+ long dwRate;
+ long dwLength;
+ long dwEditCount;
+ char szFileType[64];
+} AVIFILEINFOA, * LPAVIFILEINFOA, *PAVIFILEINFOA;
+
+DECL_WINELIB_TYPE_AW(AVIFILEINFO)
+DECL_WINELIB_TYPE_AW(PAVIFILEINFO)
+DECL_WINELIB_TYPE_AW(LPAVIFILEINFO)
+
+/* AVICOMPRESSOPTIONS.dwFlags. determines presence of fields in below struct */
+#define AVICOMPRESSF_INTERLEAVE 0x00000001
+#define AVICOMPRESSF_DATARATE 0x00000002
+#define AVICOMPRESSF_KEYFRAMES 0x00000004
+#define AVICOMPRESSF_VALID 0x00000008
+
+typedef struct {
+ long fccType; /* stream type, for consistency */
+ long fccHandler; /* compressor */
+ long dwKeyFrameEvery; /* keyframe rate */
+ long dwQuality; /* compress quality 0-10,000 */
+ long dwBytesPerSecond; /* unsigned chars per second */
+ long dwFlags; /* flags... see below */
+ void* lpFormat; /* save format */
+ long cbFormat;
+ void* lpParms; /* compressor options */
+ long cbParms;
+ long dwInterleaveEvery; /* for non-video streams only */
+} AVICOMPRESSOPTIONS, *LPAVICOMPRESSOPTIONS,*PAVICOMPRESSOPTIONS;
+
+
+
+typedef struct {
+ long cbSize; // set to sizeof(COMPVARS) before
+ // calling ICCompressorChoose
+ long dwFlags; // see below...
+ HIC hic; // HIC of chosen compressor
+ long fccType; // basically ICTYPE_VIDEO
+ long fccHandler; // handler of chosen compressor or
+ // "" or "DIB "
+ LPBITMAPINFO lpbiIn; // input format
+ LPBITMAPINFO lpbiOut; // output format - will compress to this
+ void* lpBitsOut;
+ void* lpBitsPrev;
+ long lFrame;
+ long lKey; // key frames how often?
+ long lDataRate; // desired data rate KB/Sec
+ long lQ; // desired quality
+ long lKeyCount;
+ void* lpState; // state of compressor
+ long cbState; // size of the state
+} COMPVARS, *PCOMPVARS;
+
+// FLAGS for dwFlags element of COMPVARS structure:
+
+
+#define AVIERR_OK 0
+#define MAKE_AVIERR(error) MAKE_SCODE(SEVERITY_ERROR,FACILITY_ITF,0x4000+error)
+
+#define AVIERR_UNSUPPORTED MAKE_AVIERR(101)
+#define AVIERR_BADFORMAT MAKE_AVIERR(102)
+#define AVIERR_MEMORY MAKE_AVIERR(103)
+#define AVIERR_INTERNAL MAKE_AVIERR(104)
+#define AVIERR_BADFLAGS MAKE_AVIERR(105)
+#define AVIERR_BADPARAM MAKE_AVIERR(106)
+#define AVIERR_BADSIZE MAKE_AVIERR(107)
+#define AVIERR_BADHANDLE MAKE_AVIERR(108)
+#define AVIERR_FILEREAD MAKE_AVIERR(109)
+#define AVIERR_FILEWRITE MAKE_AVIERR(110)
+#define AVIERR_FILEOPEN MAKE_AVIERR(111)
+#define AVIERR_COMPRESSOR MAKE_AVIERR(112)
+#define AVIERR_NOCOMPRESSOR MAKE_AVIERR(113)
+#define AVIERR_READONLY MAKE_AVIERR(114)
+#define AVIERR_NODATA MAKE_AVIERR(115)
+#define AVIERR_BUFFERTOOSMALL MAKE_AVIERR(116)
+#define AVIERR_CANTCOMPRESS MAKE_AVIERR(117)
+#define AVIERR_USERABORT MAKE_AVIERR(198)
+#define AVIERR_ERROR MAKE_AVIERR(199)
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __WINE_VFW_H */
diff --git a/src/libw32dll/wine/winbase.h b/src/libw32dll/wine/winbase.h
new file mode 100644
index 000000000..4be1595d8
--- /dev/null
+++ b/src/libw32dll/wine/winbase.h
@@ -0,0 +1,1792 @@
+#ifndef __WINE_WINBASE_H
+#define __WINE_WINBASE_H
+
+#include "basetsd.h"
+#include "winnt.h"
+#include "winestring.h"
+#include "pshpack1.h"
+
+#define __WINE__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct tagCOORD {
+ INT16 x;
+ INT16 y;
+} COORD, *LPCOORD;
+
+
+ /* Windows Exit Procedure flag values */
+#define WEP_FREE_DLL 0
+#define WEP_SYSTEM_EXIT 1
+
+typedef DWORD CALLBACK (*LPTHREAD_START_ROUTINE)(LPVOID);
+
+#define EXCEPTION_DEBUG_EVENT 1
+#define CREATE_THREAD_DEBUG_EVENT 2
+#define CREATE_PROCESS_DEBUG_EVENT 3
+#define EXIT_THREAD_DEBUG_EVENT 4
+#define EXIT_PROCESS_DEBUG_EVENT 5
+#define LOAD_DLL_DEBUG_EVENT 6
+#define UNLOAD_DLL_DEBUG_EVENT 7
+#define OUTPUT_DEBUG_STRING_EVENT 8
+#define RIP_EVENT 9
+
+typedef struct _EXCEPTION_DEBUG_INFO {
+ EXCEPTION_RECORD ExceptionRecord;
+ DWORD dwFirstChance;
+} EXCEPTION_DEBUG_INFO;
+
+typedef struct _CREATE_THREAD_DEBUG_INFO {
+ HANDLE hThread;
+ LPVOID lpThreadLocalBase;
+ LPTHREAD_START_ROUTINE lpStartAddress;
+} CREATE_THREAD_DEBUG_INFO;
+
+typedef struct _CREATE_PROCESS_DEBUG_INFO {
+ HANDLE hFile;
+ HANDLE hProcess;
+ HANDLE hThread;
+ LPVOID lpBaseOfImage;
+ DWORD dwDebugInfoFileOffset;
+ DWORD nDebugInfoSize;
+ LPVOID lpThreadLocalBase;
+ LPTHREAD_START_ROUTINE lpStartAddress;
+ LPVOID lpImageName;
+ WORD fUnicode;
+} CREATE_PROCESS_DEBUG_INFO;
+
+typedef struct _EXIT_THREAD_DEBUG_INFO {
+ DWORD dwExitCode;
+} EXIT_THREAD_DEBUG_INFO;
+
+typedef struct _EXIT_PROCESS_DEBUG_INFO {
+ DWORD dwExitCode;
+} EXIT_PROCESS_DEBUG_INFO;
+
+typedef struct _LOAD_DLL_DEBUG_INFO {
+ HANDLE hFile;
+ LPVOID lpBaseOfDll;
+ DWORD dwDebugInfoFileOffset;
+ DWORD nDebugInfoSize;
+ LPVOID lpImageName;
+ WORD fUnicode;
+} LOAD_DLL_DEBUG_INFO;
+
+typedef struct _UNLOAD_DLL_DEBUG_INFO {
+ LPVOID lpBaseOfDll;
+} UNLOAD_DLL_DEBUG_INFO;
+
+typedef struct _OUTPUT_DEBUG_STRING_INFO {
+ LPSTR lpDebugStringData;
+ WORD fUnicode;
+ WORD nDebugStringLength;
+} OUTPUT_DEBUG_STRING_INFO;
+
+typedef struct _RIP_INFO {
+ DWORD dwError;
+ DWORD dwType;
+} RIP_INFO;
+
+typedef struct _DEBUG_EVENT {
+ DWORD dwDebugEventCode;
+ DWORD dwProcessId;
+ DWORD dwThreadId;
+ union {
+ EXCEPTION_DEBUG_INFO Exception;
+ CREATE_THREAD_DEBUG_INFO CreateThread;
+ CREATE_PROCESS_DEBUG_INFO CreateProcessInfo;
+ EXIT_THREAD_DEBUG_INFO ExitThread;
+ EXIT_PROCESS_DEBUG_INFO ExitProcess;
+ LOAD_DLL_DEBUG_INFO LoadDll;
+ UNLOAD_DLL_DEBUG_INFO UnloadDll;
+ OUTPUT_DEBUG_STRING_INFO DebugString;
+ RIP_INFO RipInfo;
+ } u;
+} DEBUG_EVENT, *LPDEBUG_EVENT;
+
+#define OFS_MAXPATHNAME 128
+typedef struct
+{
+ BYTE cBytes;
+ BYTE fFixedDisk;
+ WORD nErrCode;
+ BYTE reserved[4];
+ BYTE szPathName[OFS_MAXPATHNAME];
+} OFSTRUCT, *LPOFSTRUCT;
+
+#define OF_READ 0x0000
+#define OF_WRITE 0x0001
+#define OF_READWRITE 0x0002
+#define OF_SHARE_COMPAT 0x0000
+#define OF_SHARE_EXCLUSIVE 0x0010
+#define OF_SHARE_DENY_WRITE 0x0020
+#define OF_SHARE_DENY_READ 0x0030
+#define OF_SHARE_DENY_NONE 0x0040
+#define OF_PARSE 0x0100
+#define OF_DELETE 0x0200
+#define OF_VERIFY 0x0400 /* Used with OF_REOPEN */
+#define OF_SEARCH 0x0400 /* Used without OF_REOPEN */
+#define OF_CANCEL 0x0800
+#define OF_CREATE 0x1000
+#define OF_PROMPT 0x2000
+#define OF_EXIST 0x4000
+#define OF_REOPEN 0x8000
+
+/* SetErrorMode values */
+#define SEM_FAILCRITICALERRORS 0x0001
+#define SEM_NOGPFAULTERRORBOX 0x0002
+#define SEM_NOALIGNMENTFAULTEXCEPT 0x0004
+#define SEM_NOOPENFILEERRORBOX 0x8000
+
+/* CopyFileEx flags */
+#define COPY_FILE_FAIL_IF_EXISTS 0x00000001
+#define COPY_FILE_RESTARTABLE 0x00000002
+#define COPY_FILE_OPEN_SOURCE_FOR_WRITE 0x00000004
+
+/* GetTempFileName() Flags */
+#define TF_FORCEDRIVE 0x80
+
+#define DRIVE_CANNOTDETERMINE 0
+#define DRIVE_DOESNOTEXIST 1
+#define DRIVE_REMOVABLE 2
+#define DRIVE_FIXED 3
+#define DRIVE_REMOTE 4
+/* Win32 additions */
+#define DRIVE_CDROM 5
+#define DRIVE_RAMDISK 6
+
+/* The security attributes structure */
+typedef struct _SECURITY_ATTRIBUTES
+{
+ DWORD nLength;
+ LPVOID lpSecurityDescriptor;
+ WIN_BOOL bInheritHandle;
+} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
+
+#ifndef _FILETIME_
+#define _FILETIME_
+/* 64 bit number of 100 nanoseconds intervals since January 1, 1601 */
+typedef struct
+{
+ DWORD dwLowDateTime;
+ DWORD dwHighDateTime;
+} FILETIME, *LPFILETIME;
+#endif /* _FILETIME_ */
+
+/* Find* structures */
+typedef struct
+{
+ DWORD dwFileAttributes;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ DWORD nFileSizeHigh;
+ DWORD nFileSizeLow;
+ DWORD dwReserved0;
+ DWORD dwReserved1;
+ CHAR cFileName[260];
+ CHAR cAlternateFileName[14];
+} WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
+
+typedef struct
+{
+ DWORD dwFileAttributes;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ DWORD nFileSizeHigh;
+ DWORD nFileSizeLow;
+ DWORD dwReserved0;
+ DWORD dwReserved1;
+ WCHAR cFileName[260];
+ WCHAR cAlternateFileName[14];
+} WIN32_FIND_DATAW, *LPWIN32_FIND_DATAW;
+
+DECL_WINELIB_TYPE_AW(WIN32_FIND_DATA)
+DECL_WINELIB_TYPE_AW(LPWIN32_FIND_DATA)
+
+typedef struct
+{
+ LPVOID lpData;
+ DWORD cbData;
+ BYTE cbOverhead;
+ BYTE iRegionIndex;
+ WORD wFlags;
+ union {
+ struct {
+ HANDLE hMem;
+ DWORD dwReserved[3];
+ } Block;
+ struct {
+ DWORD dwCommittedSize;
+ DWORD dwUnCommittedSize;
+ LPVOID lpFirstBlock;
+ LPVOID lpLastBlock;
+ } Region;
+ } Foo;
+} PROCESS_HEAP_ENTRY, *LPPROCESS_HEAP_ENTRY;
+
+#define PROCESS_HEAP_REGION 0x0001
+#define PROCESS_HEAP_UNCOMMITTED_RANGE 0x0002
+#define PROCESS_HEAP_ENTRY_BUSY 0x0004
+#define PROCESS_HEAP_ENTRY_MOVEABLE 0x0010
+#define PROCESS_HEAP_ENTRY_DDESHARE 0x0020
+
+#define INVALID_HANDLE_VALUE16 ((HANDLE16) -1)
+#define INVALID_HANDLE_VALUE ((HANDLE) -1)
+
+#define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
+
+/* comm */
+
+#define CBR_110 0xFF10
+#define CBR_300 0xFF11
+#define CBR_600 0xFF12
+#define CBR_1200 0xFF13
+#define CBR_2400 0xFF14
+#define CBR_4800 0xFF15
+#define CBR_9600 0xFF16
+#define CBR_14400 0xFF17
+#define CBR_19200 0xFF18
+#define CBR_38400 0xFF1B
+#define CBR_56000 0xFF1F
+#define CBR_128000 0xFF23
+#define CBR_256000 0xFF27
+
+#define NOPARITY 0
+#define ODDPARITY 1
+#define EVENPARITY 2
+#define MARKPARITY 3
+#define SPACEPARITY 4
+#define ONESTOPBIT 0
+#define ONE5STOPBITS 1
+#define TWOSTOPBITS 2
+
+#define IGNORE 0
+#define INFINITE16 0xFFFF
+#define INFINITE 0xFFFFFFFF
+
+#define CE_RXOVER 0x0001
+#define CE_OVERRUN 0x0002
+#define CE_RXPARITY 0x0004
+#define CE_FRAME 0x0008
+#define CE_BREAK 0x0010
+#define CE_CTSTO 0x0020
+#define CE_DSRTO 0x0040
+#define CE_RLSDTO 0x0080
+#define CE_TXFULL 0x0100
+#define CE_PTO 0x0200
+#define CE_IOE 0x0400
+#define CE_DNS 0x0800
+#define CE_OOP 0x1000
+#define CE_MODE 0x8000
+
+#define IE_BADID -1
+#define IE_OPEN -2
+#define IE_NOPEN -3
+#define IE_MEMORY -4
+#define IE_DEFAULT -5
+#define IE_HARDWARE -10
+#define IE_BYTESIZE -11
+#define IE_BAUDRATE -12
+
+#define EV_RXCHAR 0x0001
+#define EV_RXFLAG 0x0002
+#define EV_TXEMPTY 0x0004
+#define EV_CTS 0x0008
+#define EV_DSR 0x0010
+#define EV_RLSD 0x0020
+#define EV_BREAK 0x0040
+#define EV_ERR 0x0080
+#define EV_RING 0x0100
+#define EV_PERR 0x0200
+#define EV_CTSS 0x0400
+#define EV_DSRS 0x0800
+#define EV_RLSDS 0x1000
+#define EV_RINGTE 0x2000
+#define EV_RingTe EV_RINGTE
+
+#define SETXOFF 1
+#define SETXON 2
+#define SETRTS 3
+#define CLRRTS 4
+#define SETDTR 5
+#define CLRDTR 6
+#define RESETDEV 7
+#define SETBREAK 8
+#define CLRBREAK 9
+
+#define GETBASEIRQ 10
+
+/* Purge functions for Comm Port */
+#define PURGE_TXABORT 0x0001 /* Kill the pending/current writes to the
+ comm port */
+#define PURGE_RXABORT 0x0002 /*Kill the pending/current reads to
+ the comm port */
+#define PURGE_TXCLEAR 0x0004 /* Kill the transmit queue if there*/
+#define PURGE_RXCLEAR 0x0008 /* Kill the typeahead buffer if there*/
+
+
+/* Modem Status Flags */
+#define MS_CTS_ON ((DWORD)0x0010)
+#define MS_DSR_ON ((DWORD)0x0020)
+#define MS_RING_ON ((DWORD)0x0040)
+#define MS_RLSD_ON ((DWORD)0x0080)
+
+#define RTS_CONTROL_DISABLE 0
+#define RTS_CONTROL_ENABLE 1
+#define RTS_CONTROL_HANDSHAKE 2
+#define RTS_CONTROL_TOGGLE 3
+
+#define DTR_CONTROL_DISABLE 0
+#define DTR_CONTROL_ENABLE 1
+#define DTR_CONTROL_HANDSHAKE 2
+
+#define CSTF_CTSHOLD 0x01
+#define CSTF_DSRHOLD 0x02
+#define CSTF_RLSDHOLD 0x04
+#define CSTF_XOFFHOLD 0x08
+#define CSTF_XOFFSENT 0x10
+#define CSTF_EOF 0x20
+#define CSTF_TXIM 0x40
+
+#define MAKEINTRESOURCEA(i) (LPSTR)((DWORD)((WORD)(i)))
+#define MAKEINTRESOURCEW(i) (LPWSTR)((DWORD)((WORD)(i)))
+#define MAKEINTRESOURCE WINELIB_NAME_AW(MAKEINTRESOURCE)
+
+/* Predefined resource types */
+#define RT_CURSORA MAKEINTRESOURCEA(1)
+#define RT_CURSORW MAKEINTRESOURCEW(1)
+#define RT_CURSOR WINELIB_NAME_AW(RT_CURSOR)
+#define RT_BITMAPA MAKEINTRESOURCEA(2)
+#define RT_BITMAPW MAKEINTRESOURCEW(2)
+#define RT_BITMAP WINELIB_NAME_AW(RT_BITMAP)
+#define RT_ICONA MAKEINTRESOURCEA(3)
+#define RT_ICONW MAKEINTRESOURCEW(3)
+#define RT_ICON WINELIB_NAME_AW(RT_ICON)
+#define RT_MENUA MAKEINTRESOURCEA(4)
+#define RT_MENUW MAKEINTRESOURCEW(4)
+#define RT_MENU WINELIB_NAME_AW(RT_MENU)
+#define RT_DIALOGA MAKEINTRESOURCEA(5)
+#define RT_DIALOGW MAKEINTRESOURCEW(5)
+#define RT_DIALOG WINELIB_NAME_AW(RT_DIALOG)
+#define RT_STRINGA MAKEINTRESOURCEA(6)
+#define RT_STRINGW MAKEINTRESOURCEW(6)
+#define RT_STRING WINELIB_NAME_AW(RT_STRING)
+#define RT_FONTDIRA MAKEINTRESOURCEA(7)
+#define RT_FONTDIRW MAKEINTRESOURCEW(7)
+#define RT_FONTDIR WINELIB_NAME_AW(RT_FONTDIR)
+#define RT_FONTA MAKEINTRESOURCEA(8)
+#define RT_FONTW MAKEINTRESOURCEW(8)
+#define RT_FONT WINELIB_NAME_AW(RT_FONT)
+#define RT_ACCELERATORA MAKEINTRESOURCEA(9)
+#define RT_ACCELERATORW MAKEINTRESOURCEW(9)
+#define RT_ACCELERATOR WINELIB_NAME_AW(RT_ACCELERATOR)
+#define RT_RCDATAA MAKEINTRESOURCEA(10)
+#define RT_RCDATAW MAKEINTRESOURCEW(10)
+#define RT_RCDATA WINELIB_NAME_AW(RT_RCDATA)
+#define RT_MESSAGELISTA MAKEINTRESOURCEA(11)
+#define RT_MESSAGELISTW MAKEINTRESOURCEW(11)
+#define RT_MESSAGELIST WINELIB_NAME_AW(RT_MESSAGELIST)
+#define RT_GROUP_CURSORA MAKEINTRESOURCEA(12)
+#define RT_GROUP_CURSORW MAKEINTRESOURCEW(12)
+#define RT_GROUP_CURSOR WINELIB_NAME_AW(RT_GROUP_CURSOR)
+#define RT_GROUP_ICONA MAKEINTRESOURCEA(14)
+#define RT_GROUP_ICONW MAKEINTRESOURCEW(14)
+#define RT_GROUP_ICON WINELIB_NAME_AW(RT_GROUP_ICON)
+
+
+#define LMEM_FIXED 0
+#define LMEM_MOVEABLE 0x0002
+#define LMEM_NOCOMPACT 0x0010
+#define LMEM_NODISCARD 0x0020
+#define LMEM_ZEROINIT 0x0040
+#define LMEM_MODIFY 0x0080
+#define LMEM_DISCARDABLE 0x0F00
+#define LMEM_DISCARDED 0x4000
+#define LMEM_LOCKCOUNT 0x00FF
+
+#define LPTR (LMEM_FIXED | LMEM_ZEROINIT)
+
+#define GMEM_FIXED 0x0000
+#define GMEM_MOVEABLE 0x0002
+#define GMEM_NOCOMPACT 0x0010
+#define GMEM_NODISCARD 0x0020
+#define GMEM_ZEROINIT 0x0040
+#define GMEM_MODIFY 0x0080
+#define GMEM_DISCARDABLE 0x0100
+#define GMEM_NOT_BANKED 0x1000
+#define GMEM_SHARE 0x2000
+#define GMEM_DDESHARE 0x2000
+#define GMEM_NOTIFY 0x4000
+#define GMEM_LOWER GMEM_NOT_BANKED
+#define GMEM_DISCARDED 0x4000
+#define GMEM_LOCKCOUNT 0x00ff
+#define GMEM_INVALID_HANDLE 0x8000
+
+#define GHND (GMEM_MOVEABLE | GMEM_ZEROINIT)
+#define GPTR (GMEM_FIXED | GMEM_ZEROINIT)
+
+
+typedef struct tagMEMORYSTATUS
+{
+ DWORD dwLength;
+ DWORD dwMemoryLoad;
+ DWORD dwTotalPhys;
+ DWORD dwAvailPhys;
+ DWORD dwTotalPageFile;
+ DWORD dwAvailPageFile;
+ DWORD dwTotalVirtual;
+ DWORD dwAvailVirtual;
+} MEMORYSTATUS, *LPMEMORYSTATUS;
+
+
+#ifndef NOLOGERROR
+
+/* LogParamError and LogError values */
+
+/* Error modifier bits */
+#define ERR_WARNING 0x8000
+#define ERR_PARAM 0x4000
+
+#define ERR_SIZE_MASK 0x3000
+#define ERR_BYTE 0x1000
+#define ERR_WORD 0x2000
+#define ERR_DWORD 0x3000
+
+/* LogParamError() values */
+
+/* Generic parameter values */
+#define ERR_BAD_VALUE 0x6001
+#define ERR_BAD_FLAGS 0x6002
+#define ERR_BAD_INDEX 0x6003
+#define ERR_BAD_DVALUE 0x7004
+#define ERR_BAD_DFLAGS 0x7005
+#define ERR_BAD_DINDEX 0x7006
+#define ERR_BAD_PTR 0x7007
+#define ERR_BAD_FUNC_PTR 0x7008
+#define ERR_BAD_SELECTOR 0x6009
+#define ERR_BAD_STRING_PTR 0x700a
+#define ERR_BAD_HANDLE 0x600b
+
+/* KERNEL parameter errors */
+#define ERR_BAD_HINSTANCE 0x6020
+#define ERR_BAD_HMODULE 0x6021
+#define ERR_BAD_GLOBAL_HANDLE 0x6022
+#define ERR_BAD_LOCAL_HANDLE 0x6023
+#define ERR_BAD_ATOM 0x6024
+#define ERR_BAD_HFILE 0x6025
+
+/* USER parameter errors */
+#define ERR_BAD_HWND 0x6040
+#define ERR_BAD_HMENU 0x6041
+#define ERR_BAD_HCURSOR 0x6042
+#define ERR_BAD_HICON 0x6043
+#define ERR_BAD_HDWP 0x6044
+#define ERR_BAD_CID 0x6045
+#define ERR_BAD_HDRVR 0x6046
+
+/* GDI parameter errors */
+#define ERR_BAD_COORDS 0x7060
+#define ERR_BAD_GDI_OBJECT 0x6061
+#define ERR_BAD_HDC 0x6062
+#define ERR_BAD_HPEN 0x6063
+#define ERR_BAD_HFONT 0x6064
+#define ERR_BAD_HBRUSH 0x6065
+#define ERR_BAD_HBITMAP 0x6066
+#define ERR_BAD_HRGN 0x6067
+#define ERR_BAD_HPALETTE 0x6068
+#define ERR_BAD_HMETAFILE 0x6069
+
+
+/* LogError() values */
+
+/* KERNEL errors */
+#define ERR_GALLOC 0x0001
+#define ERR_GREALLOC 0x0002
+#define ERR_GLOCK 0x0003
+#define ERR_LALLOC 0x0004
+#define ERR_LREALLOC 0x0005
+#define ERR_LLOCK 0x0006
+#define ERR_ALLOCRES 0x0007
+#define ERR_LOCKRES 0x0008
+#define ERR_LOADMODULE 0x0009
+
+/* USER errors */
+#define ERR_CREATEDLG 0x0040
+#define ERR_CREATEDLG2 0x0041
+#define ERR_REGISTERCLASS 0x0042
+#define ERR_DCBUSY 0x0043
+#define ERR_CREATEWND 0x0044
+#define ERR_STRUCEXTRA 0x0045
+#define ERR_LOADSTR 0x0046
+#define ERR_LOADMENU 0x0047
+#define ERR_NESTEDBEGINPAINT 0x0048
+#define ERR_BADINDEX 0x0049
+#define ERR_CREATEMENU 0x004a
+
+/* GDI errors */
+#define ERR_CREATEDC 0x0080
+#define ERR_CREATEMETA 0x0081
+#define ERR_DELOBJSELECTED 0x0082
+#define ERR_SELBITMAP 0x0083
+
+
+
+/* Debugging support (DEBUG SYSTEM ONLY) */
+typedef struct
+{
+ UINT16 flags;
+ DWORD dwOptions WINE_PACKED;
+ DWORD dwFilter WINE_PACKED;
+ CHAR achAllocModule[8] WINE_PACKED;
+ DWORD dwAllocBreak WINE_PACKED;
+ DWORD dwAllocCount WINE_PACKED;
+} WINDEBUGINFO, *LPWINDEBUGINFO;
+
+/* WINDEBUGINFO flags values */
+#define WDI_OPTIONS 0x0001
+#define WDI_FILTER 0x0002
+#define WDI_ALLOCBREAK 0x0004
+
+/* dwOptions values */
+#define DBO_CHECKHEAP 0x0001
+#define DBO_BUFFERFILL 0x0004
+#define DBO_DISABLEGPTRAPPING 0x0010
+#define DBO_CHECKFREE 0x0020
+
+#define DBO_SILENT 0x8000
+
+#define DBO_TRACEBREAK 0x2000
+#define DBO_WARNINGBREAK 0x1000
+#define DBO_NOERRORBREAK 0x0800
+#define DBO_NOFATALBREAK 0x0400
+#define DBO_INT3BREAK 0x0100
+
+/* DebugOutput flags values */
+#define DBF_TRACE 0x0000
+#define DBF_WARNING 0x4000
+#define DBF_ERROR 0x8000
+#define DBF_FATAL 0xc000
+
+/* dwFilter values */
+#define DBF_KERNEL 0x1000
+#define DBF_KRN_MEMMAN 0x0001
+#define DBF_KRN_LOADMODULE 0x0002
+#define DBF_KRN_SEGMENTLOAD 0x0004
+#define DBF_USER 0x0800
+#define DBF_GDI 0x0400
+#define DBF_MMSYSTEM 0x0040
+#define DBF_PENWIN 0x0020
+#define DBF_APPLICATION 0x0008
+#define DBF_DRIVER 0x0010
+
+#endif /* NOLOGERROR */
+
+typedef struct {
+ WORD wYear;
+ WORD wMonth;
+ WORD wDayOfWeek;
+ WORD wDay;
+ WORD wHour;
+ WORD wMinute;
+ WORD wSecond;
+ WORD wMilliseconds;
+} SYSTEMTIME, *LPSYSTEMTIME;
+
+/* The 'overlapped' data structure used by async I/O functions.
+ */
+typedef struct {
+ DWORD Internal;
+ DWORD InternalHigh;
+ DWORD Offset;
+ DWORD OffsetHigh;
+ HANDLE hEvent;
+} OVERLAPPED, *LPOVERLAPPED;
+
+/* Process startup information.
+ */
+
+/* STARTUPINFO.dwFlags */
+#define STARTF_USESHOWWINDOW 0x00000001
+#define STARTF_USESIZE 0x00000002
+#define STARTF_USEPOSITION 0x00000004
+#define STARTF_USECOUNTCHARS 0x00000008
+#define STARTF_USEFILLATTRIBUTE 0x00000010
+#define STARTF_RUNFULLSCREEN 0x00000020
+#define STARTF_FORCEONFEEDBACK 0x00000040
+#define STARTF_FORCEOFFFEEDBACK 0x00000080
+#define STARTF_USESTDHANDLES 0x00000100
+#define STARTF_USEHOTKEY 0x00000200
+
+typedef struct {
+ DWORD cb; /* 00: size of struct */
+ LPSTR lpReserved; /* 04: */
+ LPSTR lpDesktop; /* 08: */
+ LPSTR lpTitle; /* 0c: */
+ DWORD dwX; /* 10: */
+ DWORD dwY; /* 14: */
+ DWORD dwXSize; /* 18: */
+ DWORD dwYSize; /* 1c: */
+ DWORD dwXCountChars; /* 20: */
+ DWORD dwYCountChars; /* 24: */
+ DWORD dwFillAttribute; /* 28: */
+ DWORD dwFlags; /* 2c: */
+ WORD wShowWindow; /* 30: */
+ WORD cbReserved2; /* 32: */
+ BYTE *lpReserved2; /* 34: */
+ HANDLE hStdInput; /* 38: */
+ HANDLE hStdOutput; /* 3c: */
+ HANDLE hStdError; /* 40: */
+} STARTUPINFOA, *LPSTARTUPINFOA;
+
+typedef struct {
+ DWORD cb;
+ LPWSTR lpReserved;
+ LPWSTR lpDesktop;
+ LPWSTR lpTitle;
+ DWORD dwX;
+ DWORD dwY;
+ DWORD dwXSize;
+ DWORD dwYSize;
+ DWORD dwXCountChars;
+ DWORD dwYCountChars;
+ DWORD dwFillAttribute;
+ DWORD dwFlags;
+ WORD wShowWindow;
+ WORD cbReserved2;
+ BYTE *lpReserved2;
+ HANDLE hStdInput;
+ HANDLE hStdOutput;
+ HANDLE hStdError;
+} STARTUPINFOW, *LPSTARTUPINFOW;
+
+DECL_WINELIB_TYPE_AW(STARTUPINFO)
+DECL_WINELIB_TYPE_AW(LPSTARTUPINFO)
+
+typedef struct {
+ HANDLE hProcess;
+ HANDLE hThread;
+ DWORD dwProcessId;
+ DWORD dwThreadId;
+} PROCESS_INFORMATION,*LPPROCESS_INFORMATION;
+
+typedef struct {
+ LONG Bias;
+ WCHAR StandardName[32];
+ SYSTEMTIME StandardDate;
+ LONG StandardBias;
+ WCHAR DaylightName[32];
+ SYSTEMTIME DaylightDate;
+ LONG DaylightBias;
+} TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
+
+#define TIME_ZONE_ID_UNKNOWN 0
+#define TIME_ZONE_ID_STANDARD 1
+#define TIME_ZONE_ID_DAYLIGHT 2
+
+/* CreateProcess: dwCreationFlag values
+ */
+#define DEBUG_PROCESS 0x00000001
+#define DEBUG_ONLY_THIS_PROCESS 0x00000002
+#define CREATE_SUSPENDED 0x00000004
+#define DETACHED_PROCESS 0x00000008
+#define CREATE_NEW_CONSOLE 0x00000010
+#define NORMAL_PRIORITY_CLASS 0x00000020
+#define IDLE_PRIORITY_CLASS 0x00000040
+#define HIGH_PRIORITY_CLASS 0x00000080
+#define REALTIME_PRIORITY_CLASS 0x00000100
+#define CREATE_NEW_PROCESS_GROUP 0x00000200
+#define CREATE_UNICODE_ENVIRONMENT 0x00000400
+#define CREATE_SEPARATE_WOW_VDM 0x00000800
+#define CREATE_SHARED_WOW_VDM 0x00001000
+#define CREATE_DEFAULT_ERROR_MODE 0x04000000
+#define CREATE_NO_WINDOW 0x08000000
+#define PROFILE_USER 0x10000000
+#define PROFILE_KERNEL 0x20000000
+#define PROFILE_SERVER 0x40000000
+
+
+/* File object type definitions
+ */
+#define FILE_TYPE_UNKNOWN 0
+#define FILE_TYPE_DISK 1
+#define FILE_TYPE_CHAR 2
+#define FILE_TYPE_PIPE 3
+#define FILE_TYPE_REMOTE 32768
+
+/* File creation flags
+ */
+#define FILE_FLAG_WRITE_THROUGH 0x80000000UL
+#define FILE_FLAG_OVERLAPPED 0x40000000L
+#define FILE_FLAG_NO_BUFFERING 0x20000000L
+#define FILE_FLAG_RANDOM_ACCESS 0x10000000L
+#define FILE_FLAG_SEQUENTIAL_SCAN 0x08000000L
+#define FILE_FLAG_DELETE_ON_CLOSE 0x04000000L
+#define FILE_FLAG_BACKUP_SEMANTICS 0x02000000L
+#define FILE_FLAG_POSIX_SEMANTICS 0x01000000L
+#define CREATE_NEW 1
+#define CREATE_ALWAYS 2
+#define OPEN_EXISTING 3
+#define OPEN_ALWAYS 4
+#define TRUNCATE_EXISTING 5
+
+/* Standard handle identifiers
+ */
+#define STD_INPUT_HANDLE ((DWORD) -10)
+#define STD_OUTPUT_HANDLE ((DWORD) -11)
+#define STD_ERROR_HANDLE ((DWORD) -12)
+
+typedef struct
+{
+ int dwFileAttributes;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ int dwVolumeSerialNumber;
+ int nFileSizeHigh;
+ int nFileSizeLow;
+ int nNumberOfLinks;
+ int nFileIndexHigh;
+ int nFileIndexLow;
+} BY_HANDLE_FILE_INFORMATION ;
+
+
+typedef struct _SYSTEM_POWER_STATUS
+{
+ WIN_BOOL16 ACLineStatus;
+ BYTE BatteryFlag;
+ BYTE BatteryLifePercent;
+ BYTE reserved;
+ DWORD BatteryLifeTime;
+ DWORD BatteryFullLifeTime;
+} SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS;
+
+typedef struct _MEMORY_BASIC_INFORMATION
+{
+ LPVOID BaseAddress;
+ LPVOID AllocationBase;
+ DWORD AllocationProtect;
+ DWORD RegionSize;
+ DWORD State;
+ DWORD Protect;
+ DWORD Type;
+} MEMORY_BASIC_INFORMATION,*LPMEMORY_BASIC_INFORMATION;
+
+
+typedef WIN_BOOL CALLBACK (*CODEPAGE_ENUMPROCA)(LPSTR);
+typedef WIN_BOOL CALLBACK (*CODEPAGE_ENUMPROCW)(LPWSTR);
+DECL_WINELIB_TYPE_AW(CODEPAGE_ENUMPROC)
+typedef WIN_BOOL CALLBACK (*LOCALE_ENUMPROCA)(LPSTR);
+typedef WIN_BOOL CALLBACK (*LOCALE_ENUMPROCW)(LPWSTR);
+DECL_WINELIB_TYPE_AW(LOCALE_ENUMPROC)
+
+typedef struct tagSYSTEM_INFO
+{
+ union {
+ DWORD dwOemId; /* Obsolete field - do not use */
+ struct {
+ WORD wProcessorArchitecture;
+ WORD wReserved;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME;
+ DWORD dwPageSize;
+ LPVOID lpMinimumApplicationAddress;
+ LPVOID lpMaximumApplicationAddress;
+ DWORD dwActiveProcessorMask;
+ DWORD dwNumberOfProcessors;
+ DWORD dwProcessorType;
+ DWORD dwAllocationGranularity;
+ WORD wProcessorLevel;
+ WORD wProcessorRevision;
+} SYSTEM_INFO, *LPSYSTEM_INFO;
+
+/* {G,S}etPriorityClass */
+#define NORMAL_PRIORITY_CLASS 0x00000020
+#define IDLE_PRIORITY_CLASS 0x00000040
+#define HIGH_PRIORITY_CLASS 0x00000080
+#define REALTIME_PRIORITY_CLASS 0x00000100
+
+typedef WIN_BOOL CALLBACK (*ENUMRESTYPEPROCA)(HMODULE,LPSTR,LONG);
+typedef WIN_BOOL CALLBACK (*ENUMRESTYPEPROCW)(HMODULE,LPWSTR,LONG);
+typedef WIN_BOOL CALLBACK (*ENUMRESNAMEPROCA)(HMODULE,LPCSTR,LPSTR,LONG);
+typedef WIN_BOOL CALLBACK (*ENUMRESNAMEPROCW)(HMODULE,LPCWSTR,LPWSTR,LONG);
+typedef WIN_BOOL CALLBACK (*ENUMRESLANGPROCA)(HMODULE,LPCSTR,LPCSTR,WORD,LONG);
+typedef WIN_BOOL CALLBACK (*ENUMRESLANGPROCW)(HMODULE,LPCWSTR,LPCWSTR,WORD,LONG);
+
+DECL_WINELIB_TYPE_AW(ENUMRESTYPEPROC)
+DECL_WINELIB_TYPE_AW(ENUMRESNAMEPROC)
+DECL_WINELIB_TYPE_AW(ENUMRESLANGPROC)
+
+/* flags that can be passed to LoadLibraryEx */
+#define DONT_RESOLVE_DLL_REFERENCES 0x00000001
+#define LOAD_LIBRARY_AS_DATAFILE 0x00000002
+#define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008
+
+/* ifdef _x86_ ... */
+typedef struct _LDT_ENTRY {
+ WORD LimitLow;
+ WORD BaseLow;
+ union {
+ struct {
+ BYTE BaseMid;
+ BYTE Flags1;/*Declare as bytes to avoid alignment problems */
+ BYTE Flags2;
+ BYTE BaseHi;
+ } Bytes;
+ struct {
+ unsigned BaseMid : 8;
+ unsigned Type : 5;
+ unsigned Dpl : 2;
+ unsigned Pres : 1;
+ unsigned LimitHi : 4;
+ unsigned Sys : 1;
+ unsigned Reserved_0 : 1;
+ unsigned Default_Big : 1;
+ unsigned Granularity : 1;
+ unsigned BaseHi : 8;
+ } Bits;
+ } HighWord;
+} LDT_ENTRY, *LPLDT_ENTRY;
+
+
+typedef enum _GET_FILEEX_INFO_LEVELS {
+ GetFileExInfoStandard
+} GET_FILEEX_INFO_LEVELS;
+
+typedef struct _WIN32_FILE_ATTRIBUTES_DATA {
+ DWORD dwFileAttributes;
+ FILETIME ftCreationTime;
+ FILETIME ftLastAccessTime;
+ FILETIME ftLastWriteTime;
+ DWORD nFileSizeHigh;
+ DWORD nFileSizeLow;
+} WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA;
+
+typedef struct _DllVersionInfo {
+ DWORD cbSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformID;
+} DLLVERSIONINFO;
+
+/*
+ * This one seems to be a Win32 only definition. It also is defined with
+ * WINAPI instead of CALLBACK in the windows headers.
+ */
+typedef DWORD WINAPI (*LPPROGRESS_ROUTINE)(LARGE_INTEGER, LARGE_INTEGER, LARGE_INTEGER,
+ LARGE_INTEGER, DWORD, DWORD, HANDLE,
+ HANDLE, LPVOID);
+
+
+#define WAIT_FAILED 0xffffffff
+#define WAIT_OBJECT_0 0
+#define WAIT_ABANDONED STATUS_ABANDONED_WAIT_0
+#define WAIT_ABANDONED_0 STATUS_ABANDONED_WAIT_0
+#define WAIT_IO_COMPLETION STATUS_USER_APC
+#define WAIT_TIMEOUT STATUS_TIMEOUT
+#define STILL_ACTIVE STATUS_PENDING
+
+#define PAGE_NOACCESS 0x01
+#define PAGE_READONLY 0x02
+#define PAGE_READWRITE 0x04
+#define PAGE_WRITECOPY 0x08
+#define PAGE_EXECUTE 0x10
+#define PAGE_EXECUTE_READ 0x20
+#define PAGE_EXECUTE_READWRITE 0x40
+#define PAGE_EXECUTE_WRITECOPY 0x80
+#define PAGE_GUARD 0x100
+#define PAGE_NOCACHE 0x200
+
+#define MEM_COMMIT 0x00001000
+#define MEM_RESERVE 0x00002000
+#define MEM_DECOMMIT 0x00004000
+#define MEM_RELEASE 0x00008000
+#define MEM_FREE 0x00010000
+#define MEM_PRIVATE 0x00020000
+#define MEM_MAPPED 0x00040000
+#define MEM_TOP_DOWN 0x00100000
+#ifdef __WINE__
+#define MEM_SYSTEM 0x80000000
+#endif
+
+#define SEC_FILE 0x00800000
+#define SEC_IMAGE 0x01000000
+#define SEC_RESERVE 0x04000000
+#define SEC_COMMIT 0x08000000
+#define SEC_NOCACHE 0x10000000
+
+#define FILE_BEGIN 0
+#define FILE_CURRENT 1
+#define FILE_END 2
+
+#define FILE_CASE_SENSITIVE_SEARCH 0x00000001
+#define FILE_CASE_PRESERVED_NAMES 0x00000002
+#define FILE_UNICODE_ON_DISK 0x00000004
+#define FILE_PERSISTENT_ACLS 0x00000008
+
+#define FILE_MAP_COPY 0x00000001
+#define FILE_MAP_WRITE 0x00000002
+#define FILE_MAP_READ 0x00000004
+#define FILE_MAP_ALL_ACCESS 0x000f001f
+
+#define MOVEFILE_REPLACE_EXISTING 0x00000001
+#define MOVEFILE_COPY_ALLOWED 0x00000002
+#define MOVEFILE_DELAY_UNTIL_REBOOT 0x00000004
+
+#define FS_CASE_SENSITIVE FILE_CASE_SENSITIVE_SEARCH
+#define FS_CASE_IS_PRESERVED FILE_CASE_PRESERVED_NAMES
+#define FS_UNICODE_STORED_ON_DISK FILE_UNICODE_ON_DISK
+
+#define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION
+#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT
+#define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT
+#define EXCEPTION_SINGLE_STEP STATUS_SINGLE_STEP
+#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED
+#define EXCEPTION_FLT_DENORMAL_OPERAND STATUS_FLOAT_DENORMAL_OPERAND
+#define EXCEPTION_FLT_DIVIDE_BY_ZERO STATUS_FLOAT_DIVIDE_BY_ZERO
+#define EXCEPTION_FLT_INEXACT_RESULT STATUS_FLOAT_INEXACT_RESULT
+#define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION
+#define EXCEPTION_FLT_OVERFLOW STATUS_FLOAT_OVERFLOW
+#define EXCEPTION_FLT_STACK_CHECK STATUS_FLOAT_STACK_CHECK
+#define EXCEPTION_FLT_UNDERFLOW STATUS_FLOAT_UNDERFLOW
+#define EXCEPTION_INT_DIVIDE_BY_ZERO STATUS_INTEGER_DIVIDE_BY_ZERO
+#define EXCEPTION_INT_OVERFLOW STATUS_INTEGER_OVERFLOW
+#define EXCEPTION_PRIV_INSTRUCTION STATUS_PRIVILEGED_INSTRUCTION
+#define EXCEPTION_IN_PAGE_ERROR STATUS_IN_PAGE_ERROR
+#define EXCEPTION_ILLEGAL_INSTRUCTION STATUS_ILLEGAL_INSTRUCTION
+#define EXCEPTION_NONCONTINUABLE_EXCEPTION STATUS_NONCONTINUABLE_EXCEPTION
+#define EXCEPTION_STACK_OVERFLOW STATUS_STACK_OVERFLOW
+#define EXCEPTION_INVALID_DISPOSITION STATUS_INVALID_DISPOSITION
+#define EXCEPTION_GUARD_PAGE STATUS_GUARD_PAGE_VIOLATION
+#define EXCEPTION_INVALID_HANDLE STATUS_INVALID_HANDLE
+#define CONTROL_C_EXIT STATUS_CONTROL_C_EXIT
+
+/* Wine extension; Windows doesn't have a name for this code */
+#define EXCEPTION_CRITICAL_SECTION_WAIT 0xc0000194
+
+#define DUPLICATE_CLOSE_SOURCE 0x00000001
+#define DUPLICATE_SAME_ACCESS 0x00000002
+
+#define HANDLE_FLAG_INHERIT 0x00000001
+#define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x00000002
+
+#define HINSTANCE_ERROR 32
+
+#define THREAD_PRIORITY_LOWEST THREAD_BASE_PRIORITY_MIN
+#define THREAD_PRIORITY_BELOW_NORMAL (THREAD_PRIORITY_LOWEST+1)
+#define THREAD_PRIORITY_NORMAL 0
+#define THREAD_PRIORITY_HIGHEST THREAD_BASE_PRIORITY_MAX
+#define THREAD_PRIORITY_ABOVE_NORMAL (THREAD_PRIORITY_HIGHEST-1)
+#define THREAD_PRIORITY_ERROR_RETURN (0x7fffffff)
+#define THREAD_PRIORITY_TIME_CRITICAL THREAD_BASE_PRIORITY_LOWRT
+#define THREAD_PRIORITY_IDLE THREAD_BASE_PRIORITY_IDLE
+
+/* Could this type be considered opaque? */
+typedef struct {
+ LPVOID DebugInfo;
+ LONG LockCount;
+ LONG RecursionCount;
+ HANDLE OwningThread;
+ HANDLE LockSemaphore;
+ DWORD Reserved;
+}CRITICAL_SECTION;
+
+#ifdef __WINE__
+#define CRITICAL_SECTION_INIT { 0, -1, 0, 0, 0, 0 }
+#endif
+
+typedef struct {
+ DWORD dwOSVersionInfoSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformId;
+ CHAR szCSDVersion[128];
+} OSVERSIONINFO16;
+
+typedef struct {
+ DWORD dwOSVersionInfoSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformId;
+ CHAR szCSDVersion[128];
+} OSVERSIONINFOA;
+
+typedef struct {
+ DWORD dwOSVersionInfoSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformId;
+ WCHAR szCSDVersion[128];
+} OSVERSIONINFOW;
+
+DECL_WINELIB_TYPE_AW(OSVERSIONINFO)
+
+#define VER_PLATFORM_WIN32s 0
+#define VER_PLATFORM_WIN32_WINDOWS 1
+#define VER_PLATFORM_WIN32_NT 2
+
+typedef struct tagCOMSTAT
+{
+ DWORD status;
+ DWORD cbInQue;
+ DWORD cbOutQue;
+} COMSTAT,*LPCOMSTAT;
+
+typedef struct tagDCB
+{
+ DWORD DCBlength;
+ DWORD BaudRate;
+ unsigned fBinary :1;
+ unsigned fParity :1;
+ unsigned fOutxCtsFlow :1;
+ unsigned fOutxDsrFlow :1;
+ unsigned fDtrControl :2;
+ unsigned fDsrSensitivity :1;
+ unsigned fTXContinueOnXoff :1;
+ unsigned fOutX :1;
+ unsigned fInX :1;
+ unsigned fErrorChar :1;
+ unsigned fNull :1;
+ unsigned fRtsControl :2;
+ unsigned fAbortOnError :1;
+ unsigned fDummy2 :17;
+ WORD wReserved;
+ WORD XonLim;
+ WORD XoffLim;
+ BYTE ByteSize;
+ BYTE Parity;
+ BYTE StopBits;
+ char XonChar;
+ char XoffChar;
+ char ErrorChar;
+ char EofChar;
+ char EvtChar;
+} DCB, *LPDCB;
+
+
+
+typedef struct tagCOMMTIMEOUTS {
+ DWORD ReadIntervalTimeout;
+ DWORD ReadTotalTimeoutMultiplier;
+ DWORD ReadTotalTimeoutConstant;
+ DWORD WriteTotalTimeoutMultiplier;
+ DWORD WriteTotalTimeoutConstant;
+} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
+
+#include "poppack.h"
+
+typedef void CALLBACK (*PAPCFUNC)(ULONG_PTR);
+typedef void CALLBACK (*PTIMERAPCROUTINE)(LPVOID,DWORD,DWORD);
+
+WIN_BOOL WINAPI ClearCommError(INT,LPDWORD,LPCOMSTAT);
+WIN_BOOL WINAPI BuildCommDCBA(LPCSTR,LPDCB);
+WIN_BOOL WINAPI BuildCommDCBW(LPCWSTR,LPDCB);
+#define BuildCommDCB WINELIB_NAME_AW(BuildCommDCB)
+WIN_BOOL WINAPI BuildCommDCBAndTimeoutsA(LPCSTR,LPDCB,LPCOMMTIMEOUTS);
+WIN_BOOL WINAPI BuildCommDCBAndTimeoutsW(LPCWSTR,LPDCB,LPCOMMTIMEOUTS);
+#define BuildCommDCBAndTimeouts WINELIB_NAME_AW(BuildCommDCBAndTimeouts)
+WIN_BOOL WINAPI GetCommTimeouts(HANDLE,LPCOMMTIMEOUTS);
+WIN_BOOL WINAPI SetCommTimeouts(HANDLE,LPCOMMTIMEOUTS);
+WIN_BOOL WINAPI GetCommState(INT,LPDCB);
+WIN_BOOL WINAPI SetCommState(INT,LPDCB);
+WIN_BOOL WINAPI TransmitCommChar(INT,CHAR);
+WIN_BOOL WINAPI SetupComm(HANDLE, DWORD, DWORD);
+WIN_BOOL WINAPI GetCommProperties(HANDLE, LPDCB *);
+
+/*DWORD WINAPI GetVersion( void );*/
+WIN_BOOL16 WINAPI GetVersionEx16(OSVERSIONINFO16*);
+WIN_BOOL WINAPI GetVersionExA(OSVERSIONINFOA*);
+WIN_BOOL WINAPI GetVersionExW(OSVERSIONINFOW*);
+#define GetVersionEx WINELIB_NAME_AW(GetVersionEx)
+
+/*int WinMain(HINSTANCE, HINSTANCE prev, char *cmd, int show);*/
+
+void WINAPI DeleteCriticalSection(CRITICAL_SECTION *lpCrit);
+void WINAPI EnterCriticalSection(CRITICAL_SECTION *lpCrit);
+WIN_BOOL WINAPI TryEnterCriticalSection(CRITICAL_SECTION *lpCrit);
+void WINAPI InitializeCriticalSection(CRITICAL_SECTION *lpCrit);
+void WINAPI LeaveCriticalSection(CRITICAL_SECTION *lpCrit);
+void WINAPI MakeCriticalSectionGlobal(CRITICAL_SECTION *lpCrit);
+WIN_BOOL WINAPI GetProcessWorkingSetSize(HANDLE,LPDWORD,LPDWORD);
+DWORD WINAPI QueueUserAPC(PAPCFUNC,HANDLE,ULONG_PTR);
+void WINAPI RaiseException(DWORD,DWORD,DWORD,const LPDWORD);
+WIN_BOOL WINAPI SetProcessWorkingSetSize(HANDLE,DWORD,DWORD);
+WIN_BOOL WINAPI TerminateProcess(HANDLE,DWORD);
+WIN_BOOL WINAPI TerminateThread(HANDLE,DWORD);
+WIN_BOOL WINAPI GetExitCodeThread(HANDLE,LPDWORD);
+
+/* GetBinaryType return values.
+ */
+
+#define SCS_32BIT_BINARY 0
+#define SCS_DOS_BINARY 1
+#define SCS_WOW_BINARY 2
+#define SCS_PIF_BINARY 3
+#define SCS_POSIX_BINARY 4
+#define SCS_OS216_BINARY 5
+
+WIN_BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType );
+WIN_BOOL WINAPI GetBinaryTypeW( LPCWSTR lpApplicationName, LPDWORD lpBinaryType );
+#define GetBinaryType WINELIB_NAME_AW(GetBinaryType)
+
+WIN_BOOL16 WINAPI GetWinDebugInfo16(LPWINDEBUGINFO,UINT16);
+WIN_BOOL16 WINAPI SetWinDebugInfo16(LPWINDEBUGINFO);
+/* Declarations for functions that exist only in Win32 */
+
+
+WIN_BOOL WINAPI AttachThreadInput(DWORD,DWORD,WIN_BOOL);
+WIN_BOOL WINAPI AccessCheck(PSECURITY_DESCRIPTOR,HANDLE,DWORD,PGENERIC_MAPPING,PPRIVILEGE_SET,LPDWORD,LPDWORD,LPWIN_BOOL);
+WIN_BOOL WINAPI AdjustTokenPrivileges(HANDLE,WIN_BOOL,LPVOID,DWORD,LPVOID,LPDWORD);
+WIN_BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY,BYTE,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,PSID *);
+WIN_BOOL WINAPI AllocateLocallyUniqueId(PLUID);
+WIN_BOOL WINAPI AllocConsole(void);
+WIN_BOOL WINAPI AreFileApisANSI(void);
+WIN_BOOL WINAPI BackupEventLogA(HANDLE,LPCSTR);
+WIN_BOOL WINAPI BackupEventLogW(HANDLE,LPCWSTR);
+#define BackupEventLog WINELIB_NAME_AW(BackupEventLog)
+WIN_BOOL WINAPI Beep(DWORD,DWORD);
+WIN_BOOL WINAPI CancelWaitableTimer(HANDLE);
+WIN_BOOL WINAPI ClearEventLogA(HANDLE,LPCSTR);
+WIN_BOOL WINAPI ClearEventLogW(HANDLE,LPCWSTR);
+#define ClearEventLog WINELIB_NAME_AW(ClearEventLog)
+WIN_BOOL WINAPI CloseEventLog(HANDLE);
+WIN_BOOL WINAPI CloseHandle(HANDLE);
+WIN_BOOL WINAPI ContinueDebugEvent(DWORD,DWORD,DWORD);
+HANDLE WINAPI ConvertToGlobalHandle(HANDLE hSrc);
+WIN_BOOL WINAPI CopyFileA(LPCSTR,LPCSTR,WIN_BOOL);
+WIN_BOOL WINAPI CopyFileW(LPCWSTR,LPCWSTR,WIN_BOOL);
+#define CopyFile WINELIB_NAME_AW(CopyFile)
+WIN_BOOL WINAPI CopyFileExA(LPCSTR, LPCSTR, LPPROGRESS_ROUTINE, LPVOID, LPWIN_BOOL, DWORD);
+WIN_BOOL WINAPI CopyFileExW(LPCWSTR, LPCWSTR, LPPROGRESS_ROUTINE, LPVOID, LPWIN_BOOL, DWORD);
+#define CopyFileEx WINELIB_NAME_AW(CopyFileEx)
+WIN_BOOL WINAPI CopySid(DWORD,PSID,PSID);
+INT WINAPI CompareFileTime(LPFILETIME,LPFILETIME);
+HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES,WIN_BOOL,WIN_BOOL,LPCSTR);
+HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES,WIN_BOOL,WIN_BOOL,LPCWSTR);
+#define CreateEvent WINELIB_NAME_AW(CreateEvent)
+HANDLE WINAPI CreateFileA(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,
+ DWORD,DWORD,HANDLE);
+HANDLE WINAPI CreateFileW(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES,
+ DWORD,DWORD,HANDLE);
+#define CreateFile WINELIB_NAME_AW(CreateFile)
+HANDLE WINAPI CreateFileMappingA(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,
+ DWORD,DWORD,LPCSTR);
+HANDLE WINAPI CreateFileMappingW(HANDLE,LPSECURITY_ATTRIBUTES,DWORD,
+ DWORD,DWORD,LPCWSTR);
+#define CreateFileMapping WINELIB_NAME_AW(CreateFileMapping)
+HANDLE WINAPI CreateMutexA(LPSECURITY_ATTRIBUTES,WIN_BOOL,LPCSTR);
+HANDLE WINAPI CreateMutexW(LPSECURITY_ATTRIBUTES,WIN_BOOL,LPCWSTR);
+#define CreateMutex WINELIB_NAME_AW(CreateMutex)
+WIN_BOOL WINAPI CreatePipe(PHANDLE,PHANDLE,LPSECURITY_ATTRIBUTES,DWORD);
+WIN_BOOL WINAPI CreateProcessA(LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,
+ LPSECURITY_ATTRIBUTES,WIN_BOOL,DWORD,LPVOID,LPCSTR,
+ LPSTARTUPINFOA,LPPROCESS_INFORMATION);
+WIN_BOOL WINAPI CreateProcessW(LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES,
+ LPSECURITY_ATTRIBUTES,WIN_BOOL,DWORD,LPVOID,LPCWSTR,
+ LPSTARTUPINFOW,LPPROCESS_INFORMATION);
+#define CreateProcess WINELIB_NAME_AW(CreateProcess)
+HANDLE WINAPI CreateSemaphoreA(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCSTR);
+HANDLE WINAPI CreateSemaphoreW(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCWSTR);
+#define CreateSemaphore WINELIB_NAME_AW(CreateSemaphore)
+HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES,DWORD,LPTHREAD_START_ROUTINE,LPVOID,DWORD,LPDWORD);
+HANDLE WINAPI CreateWaitableTimerA(LPSECURITY_ATTRIBUTES,WIN_BOOL,LPCSTR);
+HANDLE WINAPI CreateWaitableTimerW(LPSECURITY_ATTRIBUTES,WIN_BOOL,LPCWSTR);
+#define CreateWaitableTimer WINELIB_NAME_AW(CreateWaitableTimer)
+WIN_BOOL WINAPI DebugActiveProcess(DWORD);
+void WINAPI DebugBreak(void);
+WIN_BOOL WINAPI DeregisterEventSource(HANDLE);
+WIN_BOOL WINAPI DisableThreadLibraryCalls(HMODULE);
+WIN_BOOL WINAPI DosDateTimeToFileTime(WORD,WORD,LPFILETIME);
+WIN_BOOL WINAPI DuplicateHandle(HANDLE,HANDLE,HANDLE,HANDLE*,DWORD,WIN_BOOL,DWORD);
+WIN_BOOL WINAPI EnumDateFormatsA(DATEFMT_ENUMPROCA lpDateFmtEnumProc, LCID Locale, DWORD dwFlags);
+WIN_BOOL WINAPI EnumDateFormatsW(DATEFMT_ENUMPROCW lpDateFmtEnumProc, LCID Locale, DWORD dwFlags);
+#define EnumDateFormats WINELIB_NAME_AW(EnumDateFormats)
+WIN_BOOL WINAPI EnumResourceLanguagesA(HMODULE,LPCSTR,LPCSTR,
+ ENUMRESLANGPROCA,LONG);
+WIN_BOOL WINAPI EnumResourceLanguagesW(HMODULE,LPCWSTR,LPCWSTR,
+ ENUMRESLANGPROCW,LONG);
+#define EnumResourceLanguages WINELIB_NAME_AW(EnumResourceLanguages)
+WIN_BOOL WINAPI EnumResourceNamesA(HMODULE,LPCSTR,ENUMRESNAMEPROCA,
+ LONG);
+WIN_BOOL WINAPI EnumResourceNamesW(HMODULE,LPCWSTR,ENUMRESNAMEPROCW,
+ LONG);
+#define EnumResourceNames WINELIB_NAME_AW(EnumResourceNames)
+WIN_BOOL WINAPI EnumResourceTypesA(HMODULE,ENUMRESTYPEPROCA,LONG);
+WIN_BOOL WINAPI EnumResourceTypesW(HMODULE,ENUMRESTYPEPROCW,LONG);
+#define EnumResourceTypes WINELIB_NAME_AW(EnumResourceTypes)
+WIN_BOOL WINAPI EnumSystemCodePagesA(CODEPAGE_ENUMPROCA,DWORD);
+WIN_BOOL WINAPI EnumSystemCodePagesW(CODEPAGE_ENUMPROCW,DWORD);
+#define EnumSystemCodePages WINELIB_NAME_AW(EnumSystemCodePages)
+WIN_BOOL WINAPI EnumSystemLocalesA(LOCALE_ENUMPROCA,DWORD);
+WIN_BOOL WINAPI EnumSystemLocalesW(LOCALE_ENUMPROCW,DWORD);
+#define EnumSystemLocales WINELIB_NAME_AW(EnumSystemLocales)
+WIN_BOOL WINAPI EnumTimeFormatsA(TIMEFMT_ENUMPROCA lpTimeFmtEnumProc, LCID Locale, DWORD dwFlags);
+WIN_BOOL WINAPI EnumTimeFormatsW(TIMEFMT_ENUMPROCW lpTimeFmtEnumProc, LCID Locale, DWORD dwFlags);
+#define EnumTimeFormats WINELIB_NAME_AW(EnumTimeFormats)
+WIN_BOOL WINAPI EqualSid(PSID, PSID);
+WIN_BOOL WINAPI EqualPrefixSid(PSID,PSID);
+VOID WINAPI ExitProcess(DWORD) WINE_NORETURN;
+VOID WINAPI ExitThread(DWORD) WINE_NORETURN;
+DWORD WINAPI ExpandEnvironmentStringsA(LPCSTR,LPSTR,DWORD);
+DWORD WINAPI ExpandEnvironmentStringsW(LPCWSTR,LPWSTR,DWORD);
+#define ExpandEnvironmentStrings WINELIB_NAME_AW(ExpandEnvironmentStrings)
+WIN_BOOL WINAPI FileTimeToDosDateTime(const FILETIME*,LPWORD,LPWORD);
+WIN_BOOL WINAPI FileTimeToLocalFileTime(const FILETIME*,LPFILETIME);
+WIN_BOOL WINAPI FileTimeToSystemTime(const FILETIME*,LPSYSTEMTIME);
+HANDLE WINAPI FindFirstChangeNotificationA(LPCSTR,WIN_BOOL,DWORD);
+HANDLE WINAPI FindFirstChangeNotificationW(LPCWSTR,WIN_BOOL,DWORD);
+#define FindFirstChangeNotification WINELIB_NAME_AW(FindFirstChangeNotification)
+WIN_BOOL WINAPI FindNextChangeNotification(HANDLE);
+WIN_BOOL WINAPI FindCloseChangeNotification(HANDLE);
+HRSRC WINAPI FindResourceExA(HMODULE,LPCSTR,LPCSTR,WORD);
+HRSRC WINAPI FindResourceExW(HMODULE,LPCWSTR,LPCWSTR,WORD);
+#define FindResourceEx WINELIB_NAME_AW(FindResourceEx)
+WIN_BOOL WINAPI FlushConsoleInputBuffer(HANDLE);
+WIN_BOOL WINAPI FlushFileBuffers(HANDLE);
+WIN_BOOL WINAPI FlushViewOfFile(LPCVOID, DWORD);
+DWORD WINAPI FormatMessageA(DWORD,LPCVOID,DWORD,DWORD,LPSTR,
+ DWORD,LPDWORD);
+DWORD WINAPI FormatMessageW(DWORD,LPCVOID,DWORD,DWORD,LPWSTR,
+ DWORD,LPDWORD);
+#define FormatMessage WINELIB_NAME_AW(FormatMessage)
+WIN_BOOL WINAPI FreeConsole(void);
+WIN_BOOL WINAPI FreeEnvironmentStringsA(LPSTR);
+WIN_BOOL WINAPI FreeEnvironmentStringsW(LPWSTR);
+#define FreeEnvironmentStrings WINELIB_NAME_AW(FreeEnvironmentStrings)
+PVOID WINAPI FreeSid(PSID);
+UINT WINAPI GetACP(void);
+LPCSTR WINAPI GetCommandLineA(void);
+LPCWSTR WINAPI GetCommandLineW(void);
+#define GetCommandLine WINELIB_NAME_AW(GetCommandLine)
+WIN_BOOL WINAPI GetComputerNameA(LPSTR,LPDWORD);
+WIN_BOOL WINAPI GetComputerNameW(LPWSTR,LPDWORD);
+#define GetComputerName WINELIB_NAME_AW(GetComputerName)
+UINT WINAPI GetConsoleCP(void);
+WIN_BOOL WINAPI GetConsoleMode(HANDLE,LPDWORD);
+UINT WINAPI GetConsoleOutputCP(void);
+DWORD WINAPI GetConsoleTitleA(LPSTR,DWORD);
+DWORD WINAPI GetConsoleTitleW(LPWSTR,DWORD);
+#define GetConsoleTitle WINELIB_NAME_AW(GetConsoleTitle)
+WIN_BOOL WINAPI GetCommMask(HANDLE, LPDWORD);
+WIN_BOOL WINAPI GetCommModemStatus(HANDLE, LPDWORD);
+HANDLE WINAPI GetCurrentProcess(void);
+HANDLE WINAPI GetCurrentThread(void);
+INT WINAPI GetDateFormatA(LCID,DWORD,LPSYSTEMTIME,LPCSTR,LPSTR,INT);
+INT WINAPI GetDateFormatW(LCID,DWORD,LPSYSTEMTIME,LPCWSTR,LPWSTR,INT);
+#define GetDateFormat WINELIB_NAME_AW(GetDateFormat)
+LPSTR WINAPI GetEnvironmentStringsA(void);
+LPWSTR WINAPI GetEnvironmentStringsW(void);
+#define GetEnvironmentStrings WINELIB_NAME_AW(GetEnvironmentStrings)
+DWORD WINAPI GetEnvironmentVariableA(LPCSTR,LPSTR,DWORD);
+DWORD WINAPI GetEnvironmentVariableW(LPCWSTR,LPWSTR,DWORD);
+#define GetEnvironmentVariable WINELIB_NAME_AW(GetEnvironmentVariable)
+WIN_BOOL WINAPI GetFileAttributesExA(LPCSTR,GET_FILEEX_INFO_LEVELS,LPVOID);
+WIN_BOOL WINAPI GetFileAttributesExW(LPCWSTR,GET_FILEEX_INFO_LEVELS,LPVOID);
+#define GetFileattributesEx WINELIB_NAME_AW(GetFileAttributesEx)
+DWORD WINAPI GetFileInformationByHandle(HANDLE,BY_HANDLE_FILE_INFORMATION*);
+WIN_BOOL WINAPI GetFileSecurityA(LPCSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,LPDWORD);
+WIN_BOOL WINAPI GetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,LPDWORD);
+#define GetFileSecurity WINELIB_NAME_AW(GetFileSecurity)
+DWORD WINAPI GetFileSize(HANDLE,LPDWORD);
+WIN_BOOL WINAPI GetFileTime(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME);
+DWORD WINAPI GetFileType(HANDLE);
+DWORD WINAPI GetFullPathNameA(LPCSTR,DWORD,LPSTR,LPSTR*);
+DWORD WINAPI GetFullPathNameW(LPCWSTR,DWORD,LPWSTR,LPWSTR*);
+#define GetFullPathName WINELIB_NAME_AW(GetFullPathName)
+WIN_BOOL WINAPI GetHandleInformation(HANDLE,LPDWORD);
+COORD WINAPI GetLargestConsoleWindowSize(HANDLE);
+DWORD WINAPI GetLengthSid(PSID);
+VOID WINAPI GetLocalTime(LPSYSTEMTIME);
+DWORD WINAPI GetLogicalDrives(void);
+DWORD WINAPI GetLongPathNameA(LPCSTR,LPSTR,DWORD);
+DWORD WINAPI GetLongPathNameW(LPCWSTR,LPWSTR,DWORD);
+#define GetLongPathName WINELIB_NAME_AW(GetLongPathName)
+WIN_BOOL WINAPI GetNumberOfConsoleInputEvents(HANDLE,LPDWORD);
+WIN_BOOL WINAPI GetNumberOfConsoleMouseButtons(LPDWORD);
+WIN_BOOL WINAPI GetNumberOfEventLogRecords(HANDLE,PDWORD);
+UINT WINAPI GetOEMCP(void);
+WIN_BOOL WINAPI GetOldestEventLogRecord(HANDLE,PDWORD);
+DWORD WINAPI GetPriorityClass(HANDLE);
+DWORD WINAPI GetProcessVersion(DWORD);
+WIN_BOOL WINAPI GetSecurityDescriptorControl(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR_CONTROL,LPDWORD);
+WIN_BOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR,LPWIN_BOOL,PACL *,LPWIN_BOOL);
+WIN_BOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR,PSID *,LPWIN_BOOL);
+DWORD WINAPI GetSecurityDescriptorLength(PSECURITY_DESCRIPTOR);
+WIN_BOOL WINAPI GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR,PSID *,LPWIN_BOOL);
+WIN_BOOL WINAPI GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR,LPWIN_BOOL,PACL *,LPWIN_BOOL);
+PSID_IDENTIFIER_AUTHORITY WINAPI GetSidIdentifierAuthority(PSID);
+DWORD WINAPI GetSidLengthRequired(BYTE);
+PDWORD WINAPI GetSidSubAuthority(PSID,DWORD);
+PUCHAR WINAPI GetSidSubAuthorityCount(PSID);
+DWORD WINAPI GetShortPathNameA(LPCSTR,LPSTR,DWORD);
+DWORD WINAPI GetShortPathNameW(LPCWSTR,LPWSTR,DWORD);
+#define GetShortPathName WINELIB_NAME_AW(GetShortPathName)
+HFILE WINAPI GetStdHandle(DWORD);
+WIN_BOOL WINAPI GetStringTypeExA(LCID,DWORD,LPCSTR,INT,LPWORD);
+WIN_BOOL WINAPI GetStringTypeExW(LCID,DWORD,LPCWSTR,INT,LPWORD);
+#define GetStringTypeEx WINELIB_NAME_AW(GetStringTypeEx)
+VOID WINAPI GetSystemInfo(LPSYSTEM_INFO);
+WIN_BOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS);
+VOID WINAPI GetSystemTime(LPSYSTEMTIME);
+VOID WINAPI GetSystemTimeAsFileTime(LPFILETIME);
+INT WINAPI GetTimeFormatA(LCID,DWORD,LPSYSTEMTIME,LPCSTR,LPSTR,INT);
+INT WINAPI GetTimeFormatW(LCID,DWORD,LPSYSTEMTIME,LPCWSTR,LPWSTR,INT);
+#define GetTimeFormat WINELIB_NAME_AW(GetTimeFormat)
+WIN_BOOL WINAPI GetThreadContext(HANDLE,CONTEXT *);
+LCID WINAPI GetThreadLocale(void);
+INT WINAPI GetThreadPriority(HANDLE);
+WIN_BOOL WINAPI GetThreadSelectorEntry(HANDLE,DWORD,LPLDT_ENTRY);
+WIN_BOOL WINAPI GetThreadTimes(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME,LPFILETIME);
+WIN_BOOL WINAPI GetTokenInformation(HANDLE,TOKEN_INFORMATION_CLASS,LPVOID,DWORD,LPDWORD);
+WIN_BOOL WINAPI GetUserNameA(LPSTR,LPDWORD);
+WIN_BOOL WINAPI GetUserNameW(LPWSTR,LPDWORD);
+#define GetUserName WINELIB_NAME_AW(GetUserName)
+VOID WINAPI GlobalMemoryStatus(LPMEMORYSTATUS);
+LPVOID WINAPI HeapAlloc(HANDLE,DWORD,DWORD);
+DWORD WINAPI HeapCompact(HANDLE,DWORD);
+HANDLE WINAPI HeapCreate(DWORD,DWORD,DWORD);
+WIN_BOOL WINAPI HeapDestroy(HANDLE);
+WIN_BOOL WINAPI HeapFree(HANDLE,DWORD,LPVOID);
+WIN_BOOL WINAPI HeapLock(HANDLE);
+LPVOID WINAPI HeapReAlloc(HANDLE,DWORD,LPVOID,DWORD);
+DWORD WINAPI HeapSize(HANDLE,DWORD,LPVOID);
+WIN_BOOL WINAPI HeapUnlock(HANDLE);
+WIN_BOOL WINAPI HeapValidate(HANDLE,DWORD,LPCVOID);
+WIN_BOOL WINAPI HeapWalk(HANDLE,LPPROCESS_HEAP_ENTRY);
+WIN_BOOL WINAPI InitializeSid(PSID,PSID_IDENTIFIER_AUTHORITY,BYTE);
+WIN_BOOL WINAPI IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR);
+WIN_BOOL WINAPI IsValidSid(PSID);
+WIN_BOOL WINAPI ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL);
+WIN_BOOL WINAPI IsDBCSLeadByteEx(UINT,BYTE);
+WIN_BOOL WINAPI IsProcessorFeaturePresent(DWORD);
+WIN_BOOL WINAPI IsValidLocale(DWORD,DWORD);
+WIN_BOOL WINAPI LookupAccountSidA(LPCSTR,PSID,LPSTR,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE);
+WIN_BOOL WINAPI LookupAccountSidW(LPCWSTR,PSID,LPWSTR,LPDWORD,LPWSTR,LPDWORD,PSID_NAME_USE);
+#define LookupAccountSid WINELIB_NAME_AW(LookupAccountSidW)
+WIN_BOOL WINAPI LocalFileTimeToFileTime(const FILETIME*,LPFILETIME);
+WIN_BOOL WINAPI LockFile(HANDLE,DWORD,DWORD,DWORD,DWORD);
+WIN_BOOL WINAPI LockFileEx(HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED);
+WIN_BOOL WINAPI LookupPrivilegeValueA(LPCSTR,LPCSTR,LPVOID);
+WIN_BOOL WINAPI LookupPrivilegeValueW(LPCWSTR,LPCWSTR,LPVOID);
+#define LookupPrivilegeValue WINELIB_NAME_AW(LookupPrivilegeValue)
+WIN_BOOL WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD);
+HMODULE WINAPI MapHModuleSL(HMODULE16);
+HMODULE16 WINAPI MapHModuleLS(HMODULE);
+SEGPTR WINAPI MapLS(LPVOID);
+LPVOID WINAPI MapSL(SEGPTR);
+LPVOID WINAPI MapViewOfFile(HANDLE,DWORD,DWORD,DWORD,DWORD);
+LPVOID WINAPI MapViewOfFileEx(HANDLE,DWORD,DWORD,DWORD,DWORD,LPVOID);
+WIN_BOOL WINAPI MoveFileA(LPCSTR,LPCSTR);
+WIN_BOOL WINAPI MoveFileW(LPCWSTR,LPCWSTR);
+#define MoveFile WINELIB_NAME_AW(MoveFile)
+WIN_BOOL WINAPI MoveFileExA(LPCSTR,LPCSTR,DWORD);
+WIN_BOOL WINAPI MoveFileExW(LPCWSTR,LPCWSTR,DWORD);
+#define MoveFileEx WINELIB_NAME_AW(MoveFileEx)
+INT WINAPI MultiByteToWideChar(UINT,DWORD,LPCSTR,INT,LPWSTR,INT);
+WIN_BOOL WINAPI NotifyChangeEventLog(HANDLE,HANDLE);
+INT WINAPI WideCharToMultiByte(UINT,DWORD,LPCWSTR,INT,LPSTR,INT,LPCSTR,WIN_BOOL*);
+HANDLE WINAPI OpenBackupEventLogA(LPCSTR,LPCSTR);
+HANDLE WINAPI OpenBackupEventLogW(LPCWSTR,LPCWSTR);
+#define OpenBackupEventLog WINELIB_NAME_AW(OpenBackupEventLog)
+HANDLE WINAPI OpenEventA(DWORD,WIN_BOOL,LPCSTR);
+HANDLE WINAPI OpenEventW(DWORD,WIN_BOOL,LPCWSTR);
+#define OpenEvent WINELIB_NAME_AW(OpenEvent)
+HANDLE WINAPI OpenEventLogA(LPCSTR,LPCSTR);
+HANDLE WINAPI OpenEventLogW(LPCWSTR,LPCWSTR);
+#define OpenEventLog WINELIB_NAME_AW(OpenEventLog)
+HANDLE WINAPI OpenFileMappingA(DWORD,WIN_BOOL,LPCSTR);
+HANDLE WINAPI OpenFileMappingW(DWORD,WIN_BOOL,LPCWSTR);
+#define OpenFileMapping WINELIB_NAME_AW(OpenFileMapping)
+HANDLE WINAPI OpenMutexA(DWORD,WIN_BOOL,LPCSTR);
+HANDLE WINAPI OpenMutexW(DWORD,WIN_BOOL,LPCWSTR);
+#define OpenMutex WINELIB_NAME_AW(OpenMutex)
+HANDLE WINAPI OpenProcess(DWORD,WIN_BOOL,DWORD);
+WIN_BOOL WINAPI OpenProcessToken(HANDLE,DWORD,PHANDLE);
+HANDLE WINAPI OpenSemaphoreA(DWORD,WIN_BOOL,LPCSTR);
+HANDLE WINAPI OpenSemaphoreW(DWORD,WIN_BOOL,LPCWSTR);
+#define OpenSemaphore WINELIB_NAME_AW(OpenSemaphore)
+WIN_BOOL WINAPI OpenThreadToken(HANDLE,DWORD,WIN_BOOL,PHANDLE);
+HANDLE WINAPI OpenWaitableTimerA(DWORD,WIN_BOOL,LPCSTR);
+HANDLE WINAPI OpenWaitableTimerW(DWORD,WIN_BOOL,LPCWSTR);
+#define OpenWaitableTimer WINELIB_NAME_AW(OpenWaitableTimer)
+WIN_BOOL WINAPI PulseEvent(HANDLE);
+WIN_BOOL WINAPI PurgeComm(HANDLE,DWORD);
+DWORD WINAPI QueryDosDeviceA(LPCSTR,LPSTR,DWORD);
+DWORD WINAPI QueryDosDeviceW(LPCWSTR,LPWSTR,DWORD);
+#define QueryDosDevice WINELIB_NAME_AW(QueryDosDevice)
+WIN_BOOL WINAPI QueryPerformanceCounter(PLARGE_INTEGER);
+WIN_BOOL WINAPI ReadConsoleA(HANDLE,LPVOID,DWORD,LPDWORD,LPVOID);
+WIN_BOOL WINAPI ReadConsoleW(HANDLE,LPVOID,DWORD,LPDWORD,LPVOID);
+#define ReadConsole WINELIB_NAME_AW(ReadConsole)
+WIN_BOOL WINAPI ReadConsoleOutputCharacterA(HANDLE,LPSTR,DWORD,
+ COORD,LPDWORD);
+#define ReadConsoleOutputCharacter WINELIB_NAME_AW(ReadConsoleOutputCharacter)
+WIN_BOOL WINAPI ReadEventLogA(HANDLE,DWORD,DWORD,LPVOID,DWORD,DWORD *,DWORD *);
+WIN_BOOL WINAPI ReadEventLogW(HANDLE,DWORD,DWORD,LPVOID,DWORD,DWORD *,DWORD *);
+#define ReadEventLog WINELIB_NAME_AW(ReadEventLog)
+WIN_BOOL WINAPI ReadFile(HANDLE,LPVOID,DWORD,LPDWORD,LPOVERLAPPED);
+HANDLE WINAPI RegisterEventSourceA(LPCSTR,LPCSTR);
+HANDLE WINAPI RegisterEventSourceW(LPCWSTR,LPCWSTR);
+#define RegisterEventSource WINELIB_NAME_AW(RegisterEventSource)
+WIN_BOOL WINAPI ReleaseMutex(HANDLE);
+WIN_BOOL WINAPI ReleaseSemaphore(HANDLE,LONG,LPLONG);
+WIN_BOOL WINAPI ReportEventA(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCSTR *,LPVOID);
+WIN_BOOL WINAPI ReportEventW(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCWSTR *,LPVOID);
+#define ReportEvent WINELIB_NAME_AW(ReportEvent)
+WIN_BOOL WINAPI ResetEvent(HANDLE);
+DWORD WINAPI ResumeThread(HANDLE);
+WIN_BOOL WINAPI RevertToSelf(void);
+DWORD WINAPI SearchPathA(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*);
+DWORD WINAPI SearchPathW(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,LPWSTR,LPWSTR*);
+#define SearchPath WINELIB_NAME_AW(SearchPath)
+WIN_BOOL WINAPI SetCommMask(INT,DWORD);
+WIN_BOOL WINAPI SetComputerNameA(LPCSTR);
+WIN_BOOL WINAPI SetComputerNameW(LPCWSTR);
+#define SetComputerName WINELIB_NAME_AW(SetComputerName)
+WIN_BOOL WINAPI SetConsoleCursorPosition(HANDLE,COORD);
+WIN_BOOL WINAPI SetConsoleMode(HANDLE,DWORD);
+WIN_BOOL WINAPI SetConsoleTitleA(LPCSTR);
+WIN_BOOL WINAPI SetConsoleTitleW(LPCWSTR);
+#define SetConsoleTitle WINELIB_NAME_AW(SetConsoleTitle)
+WIN_BOOL WINAPI SetEndOfFile(HANDLE);
+WIN_BOOL WINAPI SetEnvironmentVariableA(LPCSTR,LPCSTR);
+WIN_BOOL WINAPI SetEnvironmentVariableW(LPCWSTR,LPCWSTR);
+#define SetEnvironmentVariable WINELIB_NAME_AW(SetEnvironmentVariable)
+WIN_BOOL WINAPI SetEvent(HANDLE);
+VOID WINAPI SetFileApisToANSI(void);
+VOID WINAPI SetFileApisToOEM(void);
+DWORD WINAPI SetFilePointer(HANDLE,LONG,LPLONG,DWORD);
+WIN_BOOL WINAPI SetFileSecurityA(LPCSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
+WIN_BOOL WINAPI SetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR);
+#define SetFileSecurity WINELIB_NAME_AW(SetFileSecurity)
+WIN_BOOL WINAPI SetFileTime(HANDLE,const FILETIME*,const FILETIME*,const FILETIME*);
+WIN_BOOL WINAPI SetHandleInformation(HANDLE,DWORD,DWORD);
+WIN_BOOL WINAPI SetPriorityClass(HANDLE,DWORD);
+WIN_BOOL WINAPI SetLocalTime(const SYSTEMTIME*);
+WIN_BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR,WIN_BOOL,PACL,WIN_BOOL);
+WIN_BOOL WINAPI SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR,PSID,WIN_BOOL);
+WIN_BOOL WINAPI SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR,PSID,WIN_BOOL);
+WIN_BOOL WINAPI SetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR,WIN_BOOL,PACL,WIN_BOOL);
+WIN_BOOL WINAPI SetStdHandle(DWORD,HANDLE);
+WIN_BOOL WINAPI SetSystemPowerState(WIN_BOOL,WIN_BOOL);
+WIN_BOOL WINAPI SetSystemTime(const SYSTEMTIME*);
+DWORD WINAPI SetThreadAffinityMask(HANDLE,DWORD);
+WIN_BOOL WINAPI SetThreadContext(HANDLE,const CONTEXT *);
+WIN_BOOL WINAPI SetThreadLocale(LCID);
+WIN_BOOL WINAPI SetThreadPriority(HANDLE,INT);
+WIN_BOOL WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION);
+WIN_BOOL WINAPI SetWaitableTimer(HANDLE,const LARGE_INTEGER*,LONG,PTIMERAPCROUTINE,LPVOID,WIN_BOOL);
+VOID WINAPI Sleep(DWORD);
+DWORD WINAPI SleepEx(DWORD,WIN_BOOL);
+DWORD WINAPI SuspendThread(HANDLE);
+WIN_BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME*,LPFILETIME);
+DWORD WINAPI TlsAlloc(void);
+WIN_BOOL WINAPI TlsFree(DWORD);
+LPVOID WINAPI TlsGetValue(DWORD);
+WIN_BOOL WINAPI TlsSetValue(DWORD,LPVOID);
+VOID WINAPI UnMapLS(SEGPTR);
+WIN_BOOL WINAPI UnlockFile(HANDLE,DWORD,DWORD,DWORD,DWORD);
+WIN_BOOL WINAPI UnmapViewOfFile(LPVOID);
+LPVOID WINAPI VirtualAlloc(LPVOID,DWORD,DWORD,DWORD);
+WIN_BOOL WINAPI VirtualFree(LPVOID,DWORD,DWORD);
+WIN_BOOL WINAPI VirtualLock(LPVOID,DWORD);
+WIN_BOOL WINAPI VirtualProtect(LPVOID,DWORD,DWORD,LPDWORD);
+WIN_BOOL WINAPI VirtualProtectEx(HANDLE,LPVOID,DWORD,DWORD,LPDWORD);
+DWORD WINAPI VirtualQuery(LPCVOID,LPMEMORY_BASIC_INFORMATION,DWORD);
+DWORD WINAPI VirtualQueryEx(HANDLE,LPCVOID,LPMEMORY_BASIC_INFORMATION,DWORD);
+WIN_BOOL WINAPI VirtualUnlock(LPVOID,DWORD);
+WIN_BOOL WINAPI WaitCommEvent(HANDLE,LPDWORD,LPOVERLAPPED);
+WIN_BOOL WINAPI WaitForDebugEvent(LPDEBUG_EVENT,DWORD);
+DWORD WINAPI WaitForMultipleObjects(DWORD,const HANDLE*,WIN_BOOL,DWORD);
+DWORD WINAPI WaitForMultipleObjectsEx(DWORD,const HANDLE*,WIN_BOOL,DWORD,WIN_BOOL);
+DWORD WINAPI WaitForSingleObject(HANDLE,DWORD);
+DWORD WINAPI WaitForSingleObjectEx(HANDLE,DWORD,WIN_BOOL);
+WIN_BOOL WINAPI WriteConsoleA(HANDLE,LPCVOID,DWORD,LPDWORD,LPVOID);
+WIN_BOOL WINAPI WriteConsoleW(HANDLE,LPCVOID,DWORD,LPDWORD,LPVOID);
+#define WriteConsole WINELIB_NAME_AW(WriteConsole)
+WIN_BOOL WINAPI WriteFile(HANDLE,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED);
+LANGID WINAPI GetSystemDefaultLangID(void);
+LCID WINAPI GetSystemDefaultLCID(void);
+LANGID WINAPI GetUserDefaultLangID(void);
+LCID WINAPI GetUserDefaultLCID(void);
+ATOM WINAPI AddAtomA(LPCSTR);
+ATOM WINAPI AddAtomW(LPCWSTR);
+#define AddAtom WINELIB_NAME_AW(AddAtom)
+UINT WINAPI CompareStringA(DWORD,DWORD,LPCSTR,DWORD,LPCSTR,DWORD);
+UINT WINAPI CompareStringW(DWORD,DWORD,LPCWSTR,DWORD,LPCWSTR,DWORD);
+#define CompareString WINELIB_NAME_AW(CompareString)
+WIN_BOOL WINAPI CreateDirectoryA(LPCSTR,LPSECURITY_ATTRIBUTES);
+WIN_BOOL WINAPI CreateDirectoryW(LPCWSTR,LPSECURITY_ATTRIBUTES);
+#define CreateDirectory WINELIB_NAME_AW(CreateDirectory)
+WIN_BOOL WINAPI CreateDirectoryExA(LPCSTR,LPCSTR,LPSECURITY_ATTRIBUTES);
+WIN_BOOL WINAPI CreateDirectoryExW(LPCWSTR,LPCWSTR,LPSECURITY_ATTRIBUTES);
+#define CreateDirectoryEx WINELIB_NAME_AW(CreateDirectoryEx)
+WIN_BOOL WINAPI DefineDosDeviceA(DWORD,LPCSTR,LPCSTR);
+#define DefineHandleTable(w) ((w),TRUE)
+ATOM WINAPI DeleteAtom(ATOM);
+WIN_BOOL WINAPI DeleteFileA(LPCSTR);
+WIN_BOOL WINAPI DeleteFileW(LPCWSTR);
+#define DeleteFile WINELIB_NAME_AW(DeleteFile)
+void WINAPI FatalAppExitA(UINT,LPCSTR);
+void WINAPI FatalAppExitW(UINT,LPCWSTR);
+#define FatalAppExit WINELIB_NAME_AW(FatalAppExit)
+ATOM WINAPI FindAtomA(LPCSTR);
+ATOM WINAPI FindAtomW(LPCWSTR);
+#define FindAtom WINELIB_NAME_AW(FindAtom)
+WIN_BOOL WINAPI FindClose(HANDLE);
+HANDLE16 WINAPI FindFirstFile16(LPCSTR,LPWIN32_FIND_DATAA);
+HANDLE WINAPI FindFirstFileA(LPCSTR,LPWIN32_FIND_DATAA);
+HANDLE WINAPI FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW);
+#define FindFirstFile WINELIB_NAME_AW(FindFirstFile)
+WIN_BOOL16 WINAPI FindNextFile16(HANDLE16,LPWIN32_FIND_DATAA);
+WIN_BOOL WINAPI FindNextFileA(HANDLE,LPWIN32_FIND_DATAA);
+WIN_BOOL WINAPI FindNextFileW(HANDLE,LPWIN32_FIND_DATAW);
+#define FindNextFile WINELIB_NAME_AW(FindNextFile)
+HRSRC WINAPI FindResourceA(HMODULE,LPCSTR,LPCSTR);
+HRSRC WINAPI FindResourceW(HMODULE,LPCWSTR,LPCWSTR);
+#define FindResource WINELIB_NAME_AW(FindResource)
+VOID WINAPI FreeLibrary16(HINSTANCE16);
+WIN_BOOL WINAPI FreeLibrary(HMODULE);
+#define FreeModule(handle) FreeLibrary(handle)
+#define FreeProcInstance(proc) /*nothing*/
+WIN_BOOL WINAPI FreeResource(HGLOBAL);
+UINT WINAPI GetAtomNameA(ATOM,LPSTR,INT);
+UINT WINAPI GetAtomNameW(ATOM,LPWSTR,INT);
+#define GetAtomName WINELIB_NAME_AW(GetAtomName)
+UINT WINAPI GetCurrentDirectoryA(UINT,LPSTR);
+UINT WINAPI GetCurrentDirectoryW(UINT,LPWSTR);
+#define GetCurrentDirectory WINELIB_NAME_AW(GetCurrentDirectory)
+WIN_BOOL WINAPI GetDiskFreeSpaceA(LPCSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD);
+WIN_BOOL WINAPI GetDiskFreeSpaceW(LPCWSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD);
+#define GetDiskFreeSpace WINELIB_NAME_AW(GetDiskFreeSpace)
+WIN_BOOL WINAPI GetDiskFreeSpaceExA(LPCSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER);
+WIN_BOOL WINAPI GetDiskFreeSpaceExW(LPCWSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER);
+#define GetDiskFreeSpaceEx WINELIB_NAME_AW(GetDiskFreeSpaceEx)
+UINT WINAPI GetDriveTypeA(LPCSTR);
+UINT WINAPI GetDriveTypeW(LPCWSTR);
+#define GetDriveType WINELIB_NAME_AW(GetDriveType)
+DWORD WINAPI GetFileAttributesA(LPCSTR);
+DWORD WINAPI GetFileAttributesW(LPCWSTR);
+#define GetFileAttributes WINELIB_NAME_AW(GetFileAttributes)
+#define GetFreeSpace(w) (0x100000L)
+UINT WINAPI GetLogicalDriveStringsA(UINT,LPSTR);
+UINT WINAPI GetLogicalDriveStringsW(UINT,LPWSTR);
+#define GetLogicalDriveStrings WINELIB_NAME_AW(GetLogicalDriveStrings)
+INT WINAPI GetLocaleInfoA(LCID,LCTYPE,LPSTR,INT);
+INT WINAPI GetLocaleInfoW(LCID,LCTYPE,LPWSTR,INT);
+#define GetLocaleInfo WINELIB_NAME_AW(GetLocaleInfo)
+DWORD WINAPI GetModuleFileNameA(HMODULE,LPSTR,DWORD);
+DWORD WINAPI GetModuleFileNameW(HMODULE,LPWSTR,DWORD);
+#define GetModuleFileName WINELIB_NAME_AW(GetModuleFileName)
+HMODULE WINAPI GetModuleHandleA(LPCSTR);
+HMODULE WINAPI GetModuleHandleW(LPCWSTR);
+#define GetModuleHandle WINELIB_NAME_AW(GetModuleHandle)
+WIN_BOOL WINAPI GetOverlappedResult(HANDLE,LPOVERLAPPED,LPDWORD,WIN_BOOL);
+UINT WINAPI GetPrivateProfileIntA(LPCSTR,LPCSTR,INT,LPCSTR);
+UINT WINAPI GetPrivateProfileIntW(LPCWSTR,LPCWSTR,INT,LPCWSTR);
+#define GetPrivateProfileInt WINELIB_NAME_AW(GetPrivateProfileInt)
+INT WINAPI GetPrivateProfileSectionA(LPCSTR,LPSTR,DWORD,LPCSTR);
+INT WINAPI GetPrivateProfileSectionW(LPCWSTR,LPWSTR,DWORD,LPCWSTR);
+#define GetPrivateProfileSection WINELIB_NAME_AW(GetPrivateProfileSection)
+DWORD WINAPI GetPrivateProfileSectionNamesA(LPSTR,DWORD,LPCSTR);
+DWORD WINAPI GetPrivateProfileSectionNamesW(LPWSTR,DWORD,LPCWSTR);
+#define GetPrivateProfileSectionNames WINELIB_NAME_AW(GetPrivateProfileSectionNames)
+INT WINAPI GetPrivateProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT,LPCSTR);
+INT WINAPI GetPrivateProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,UINT,LPCWSTR);
+#define GetPrivateProfileString WINELIB_NAME_AW(GetPrivateProfileString)
+WIN_BOOL WINAPI GetPrivateProfileStructA(LPCSTR,LPCSTR,LPVOID,UINT,LPCSTR);
+WIN_BOOL WINAPI GetPrivateProfileStructW(LPCWSTR,LPCWSTR,LPVOID,UINT,LPCWSTR);
+#define GetPrivateProfileStruct WINELIB_NAME_AW(GetPrivateProfileStruct)
+FARPROC WINAPI GetProcAddress(HMODULE,LPCSTR);
+UINT WINAPI GetProfileIntA(LPCSTR,LPCSTR,INT);
+UINT WINAPI GetProfileIntW(LPCWSTR,LPCWSTR,INT);
+#define GetProfileInt WINELIB_NAME_AW(GetProfileInt)
+INT WINAPI GetProfileSectionA(LPCSTR,LPSTR,DWORD);
+INT WINAPI GetProfileSectionW(LPCWSTR,LPWSTR,DWORD);
+#define GetProfileSection WINELIB_NAME_AW(GetProfileSection)
+INT WINAPI GetProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT);
+INT WINAPI GetProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,UINT);
+#define GetProfileString WINELIB_NAME_AW(GetProfileString)
+VOID WINAPI GetStartupInfoA(LPSTARTUPINFOA);
+VOID WINAPI GetStartupInfoW(LPSTARTUPINFOW);
+#define GetStartupInfo WINELIB_NAME_AW(GetStartupInfo)
+WIN_BOOL WINAPI GetStringTypeA(LCID,DWORD,LPCSTR,INT,LPWORD);
+WIN_BOOL WINAPI GetStringTypeW(DWORD,LPCWSTR,INT,LPWORD);
+#define GetStringType WINELIB_NAME_AW(GetStringType)
+UINT WINAPI GetSystemDirectoryA(LPSTR,UINT);
+UINT WINAPI GetSystemDirectoryW(LPWSTR,UINT);
+#define GetSystemDirectory WINELIB_NAME_AW(GetSystemDirectory)
+UINT WINAPI GetTempFileNameA(LPCSTR,LPCSTR,UINT,LPSTR);
+UINT WINAPI GetTempFileNameW(LPCWSTR,LPCWSTR,UINT,LPWSTR);
+#define GetTempFileName WINELIB_NAME_AW(GetTempFileName)
+UINT WINAPI GetTempPathA(UINT,LPSTR);
+UINT WINAPI GetTempPathW(UINT,LPWSTR);
+#define GetTempPath WINELIB_NAME_AW(GetTempPath)
+LONG WINAPI GetVersion(void);
+WIN_BOOL WINAPI GetExitCodeProcess(HANDLE,LPDWORD);
+WIN_BOOL WINAPI GetVolumeInformationA(LPCSTR,LPSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPSTR,DWORD);
+WIN_BOOL WINAPI GetVolumeInformationW(LPCWSTR,LPWSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPWSTR,DWORD);
+#define GetVolumeInformation WINELIB_NAME_AW(GetVolumeInformation)
+UINT WINAPI GetWindowsDirectoryA(LPSTR,UINT);
+UINT WINAPI GetWindowsDirectoryW(LPWSTR,UINT);
+#define GetWindowsDirectory WINELIB_NAME_AW(GetWindowsDirectory)
+HGLOBAL16 WINAPI GlobalAlloc16(UINT16,DWORD);
+HGLOBAL WINAPI GlobalAlloc(UINT,DWORD);
+DWORD WINAPI GlobalCompact(DWORD);
+UINT WINAPI GlobalFlags(HGLOBAL);
+HGLOBAL16 WINAPI GlobalFree16(HGLOBAL16);
+HGLOBAL WINAPI GlobalFree(HGLOBAL);
+HGLOBAL WINAPI GlobalHandle(LPCVOID);
+WORD WINAPI GlobalFix16(HGLOBAL16);
+VOID WINAPI GlobalFix(HGLOBAL);
+LPVOID WINAPI GlobalLock16(HGLOBAL16);
+LPVOID WINAPI GlobalLock(HGLOBAL);
+HGLOBAL WINAPI GlobalReAlloc(HGLOBAL,DWORD,UINT);
+DWORD WINAPI GlobalSize16(HGLOBAL16);
+DWORD WINAPI GlobalSize(HGLOBAL);
+VOID WINAPI GlobalUnfix16(HGLOBAL16);
+VOID WINAPI GlobalUnfix(HGLOBAL);
+WIN_BOOL16 WINAPI GlobalUnlock16(HGLOBAL16);
+WIN_BOOL WINAPI GlobalUnlock(HGLOBAL);
+WIN_BOOL16 WINAPI GlobalUnWire16(HGLOBAL16);
+WIN_BOOL WINAPI GlobalUnWire(HGLOBAL);
+SEGPTR WINAPI GlobalWire16(HGLOBAL16);
+LPVOID WINAPI GlobalWire(HGLOBAL);
+WIN_BOOL WINAPI InitAtomTable(DWORD);
+WIN_BOOL WINAPI IsBadCodePtr(FARPROC);
+WIN_BOOL WINAPI IsBadHugeReadPtr(LPCVOID,UINT);
+WIN_BOOL WINAPI IsBadHugeWritePtr(LPVOID,UINT);
+WIN_BOOL WINAPI IsBadReadPtr(LPCVOID,UINT);
+WIN_BOOL WINAPI IsBadStringPtrA(LPCSTR,UINT);
+WIN_BOOL WINAPI IsBadStringPtrW(LPCWSTR,UINT);
+#define IsBadStringPtr WINELIB_NAME_AW(IsBadStringPtr)
+WIN_BOOL WINAPI IsBadWritePtr(LPVOID,UINT);
+WIN_BOOL WINAPI IsDBCSLeadByte(BYTE);
+WIN_BOOL WINAPI IsDebuggerPresent(void);
+HINSTANCE16 WINAPI LoadLibrary16(LPCSTR);
+HMODULE WINAPI LoadLibraryA(LPCSTR);
+HMODULE WINAPI LoadLibraryW(LPCWSTR);
+#define LoadLibrary WINELIB_NAME_AW(LoadLibrary)
+HMODULE WINAPI LoadLibraryExA(LPCSTR,HANDLE,DWORD);
+HMODULE WINAPI LoadLibraryExW(LPCWSTR,HANDLE,DWORD);
+#define LoadLibraryEx WINELIB_NAME_AW(LoadLibraryEx)
+HINSTANCE16 WINAPI LoadModule16(LPCSTR,LPVOID);
+HINSTANCE WINAPI LoadModule(LPCSTR,LPVOID);
+HGLOBAL WINAPI LoadResource(HMODULE,HRSRC);
+HLOCAL WINAPI LocalAlloc(UINT,DWORD);
+UINT WINAPI LocalCompact(UINT);
+UINT WINAPI LocalFlags(HLOCAL);
+HLOCAL WINAPI LocalFree(HLOCAL);
+HLOCAL WINAPI LocalHandle(LPCVOID);
+LPVOID WINAPI LocalLock(HLOCAL);
+HLOCAL WINAPI LocalReAlloc(HLOCAL,DWORD,UINT);
+UINT WINAPI LocalShrink(HGLOBAL,UINT);
+UINT WINAPI LocalSize(HLOCAL);
+WIN_BOOL WINAPI LocalUnlock(HLOCAL);
+LPVOID WINAPI LockResource(HGLOBAL);
+#define LockSegment(handle) GlobalFix((HANDLE)(handle))
+#define MakeProcInstance(proc,inst) (proc)
+HFILE16 WINAPI OpenFile16(LPCSTR,OFSTRUCT*,UINT16);
+HFILE WINAPI OpenFile(LPCSTR,OFSTRUCT*,UINT);
+VOID WINAPI OutputDebugStringA(LPCSTR);
+VOID WINAPI OutputDebugStringW(LPCWSTR);
+#define OutputDebugString WINELIB_NAME_AW(OutputDebugString)
+WIN_BOOL WINAPI ReadProcessMemory(HANDLE, LPCVOID, LPVOID, DWORD, LPDWORD);
+WIN_BOOL WINAPI RemoveDirectoryA(LPCSTR);
+WIN_BOOL WINAPI RemoveDirectoryW(LPCWSTR);
+#define RemoveDirectory WINELIB_NAME_AW(RemoveDirectory)
+WIN_BOOL WINAPI SetCurrentDirectoryA(LPCSTR);
+WIN_BOOL WINAPI SetCurrentDirectoryW(LPCWSTR);
+#define SetCurrentDirectory WINELIB_NAME_AW(SetCurrentDirectory)
+UINT WINAPI SetErrorMode(UINT);
+WIN_BOOL WINAPI SetFileAttributesA(LPCSTR,DWORD);
+WIN_BOOL WINAPI SetFileAttributesW(LPCWSTR,DWORD);
+#define SetFileAttributes WINELIB_NAME_AW(SetFileAttributes)
+UINT WINAPI SetHandleCount(UINT);
+#define SetSwapAreaSize(w) (w)
+WIN_BOOL WINAPI SetVolumeLabelA(LPCSTR,LPCSTR);
+WIN_BOOL WINAPI SetVolumeLabelW(LPCWSTR,LPCWSTR);
+#define SetVolumeLabel WINELIB_NAME_AW(SetVolumeLabel)
+DWORD WINAPI SizeofResource(HMODULE,HRSRC);
+#define UnlockSegment(handle) GlobalUnfix((HANDLE)(handle))
+WIN_BOOL WINAPI WritePrivateProfileSectionA(LPCSTR,LPCSTR,LPCSTR);
+WIN_BOOL WINAPI WritePrivateProfileSectionW(LPCWSTR,LPCWSTR,LPCWSTR);
+#define WritePrivateProfileSection WINELIB_NAME_AW(WritePrivateProfileSection)
+WIN_BOOL WINAPI WritePrivateProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPCSTR);
+WIN_BOOL WINAPI WritePrivateProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR);
+#define WritePrivateProfileString WINELIB_NAME_AW(WritePrivateProfileString)
+WIN_BOOL WINAPI WriteProfileSectionA(LPCSTR,LPCSTR);
+WIN_BOOL WINAPI WriteProfileSectionW(LPCWSTR,LPCWSTR);
+#define WritePrivateProfileSection WINELIB_NAME_AW(WritePrivateProfileSection)
+WIN_BOOL WINAPI WritePrivateProfileStructA(LPCSTR,LPCSTR,LPVOID,UINT,LPCSTR);
+WIN_BOOL WINAPI WritePrivateProfileStructW(LPCWSTR,LPCWSTR,LPVOID,UINT,LPCWSTR);
+#define WritePrivateProfileStruct WINELIB_NAME_AW(WritePrivateProfileStruct)
+WIN_BOOL WINAPI WriteProcessMemory(HANDLE, LPVOID, LPVOID, DWORD, LPDWORD);
+WIN_BOOL WINAPI WriteProfileStringA(LPCSTR,LPCSTR,LPCSTR);
+WIN_BOOL WINAPI WriteProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR);
+#define WriteProfileString WINELIB_NAME_AW(WriteProfileString)
+#define Yield32()
+LPSTR WINAPI lstrcatA(LPSTR,LPCSTR);
+LPWSTR WINAPI lstrcatW(LPWSTR,LPCWSTR);
+#define lstrcat WINELIB_NAME_AW(lstrcat)
+LPSTR WINAPI lstrcpyA(LPSTR,LPCSTR);
+LPWSTR WINAPI lstrcpyW(LPWSTR,LPCWSTR);
+#define lstrcpy WINELIB_NAME_AW(lstrcpy)
+LPSTR WINAPI lstrcpynA(LPSTR,LPCSTR,INT);
+LPWSTR WINAPI lstrcpynW(LPWSTR,LPCWSTR,INT);
+#define lstrcpyn WINELIB_NAME_AW(lstrcpyn)
+INT WINAPI lstrlenA(LPCSTR);
+INT WINAPI lstrlenW(LPCWSTR);
+#define lstrlen WINELIB_NAME_AW(lstrlen)
+HINSTANCE WINAPI WinExec(LPCSTR,UINT);
+LONG WINAPI _hread(HFILE,LPVOID,LONG);
+LONG WINAPI _hwrite(HFILE,LPCSTR,LONG);
+HFILE WINAPI _lcreat(LPCSTR,INT);
+HFILE WINAPI _lclose(HFILE);
+LONG WINAPI _llseek(HFILE,LONG,INT);
+HFILE WINAPI _lopen(LPCSTR,INT);
+UINT WINAPI _lread(HFILE,LPVOID,UINT);
+UINT WINAPI _lwrite(HFILE,LPCSTR,UINT);
+SEGPTR WINAPI WIN16_GlobalLock16(HGLOBAL16);
+INT WINAPI lstrcmpA(LPCSTR,LPCSTR);
+INT WINAPI lstrcmpW(LPCWSTR,LPCWSTR);
+#define lstrcmp WINELIB_NAME_AW(lstrcmp)
+INT WINAPI lstrcmpiA(LPCSTR,LPCSTR);
+INT WINAPI lstrcmpiW(LPCWSTR,LPCWSTR);
+#define lstrcmpi WINELIB_NAME_AW(lstrcmpi)
+
+/* compatibility macros */
+#define FillMemory RtlFillMemory
+#define MoveMemory RtlMoveMemory
+#define ZeroMemory RtlZeroMemory
+#define CopyMemory RtlCopyMemory
+
+DWORD WINAPI GetCurrentProcessId(void);
+DWORD WINAPI GetCurrentThreadId(void);
+DWORD WINAPI GetLastError(void);
+HANDLE WINAPI GetProcessHeap(void);
+PVOID WINAPI InterlockedCompareExchange(PVOID*,PVOID,PVOID);
+LONG WINAPI InterlockedDecrement(PLONG);
+LONG WINAPI InterlockedExchange(PLONG,LONG);
+LONG WINAPI InterlockedExchangeAdd(PLONG,LONG);
+LONG WINAPI InterlockedIncrement(PLONG);
+VOID WINAPI SetLastError(DWORD);
+
+#ifdef __WINE__
+#define GetCurrentProcess() ((HANDLE)0xffffffff)
+#define GetCurrentThread() ((HANDLE)0xfffffffe)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WINE_WINBASE_H */
diff --git a/src/libw32dll/wine/windef.h b/src/libw32dll/wine/windef.h
new file mode 100644
index 000000000..d6dfcfae2
--- /dev/null
+++ b/src/libw32dll/wine/windef.h
@@ -0,0 +1,656 @@
+/*
+ * Basic types definitions
+ *
+ * Copyright 1996 Alexandre Julliard
+ */
+
+#ifndef __WINE_WINDEF_H
+#define __WINE_WINDEF_H
+
+#ifdef __WINE__
+# include "config.h"
+# undef UNICODE
+#endif
+
+#ifdef _EGCS_
+#define __stdcall
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Misc. constants. */
+
+#ifdef FALSE
+#undef FALSE
+#endif
+#define FALSE 0
+
+#ifdef TRUE
+#undef TRUE
+#endif
+#define TRUE 1
+
+#ifdef NULL
+#undef NULL
+#endif
+#define NULL 0
+
+/* Macros to map Winelib names to the correct implementation name */
+/* depending on __WINE__ and UNICODE macros. */
+/* Note that Winelib is purely Win32. */
+
+#ifdef __WINE__
+# define WINELIB_NAME_AW(func) \
+ func##_must_be_suffixed_with_W_or_A_in_this_context \
+ func##_must_be_suffixed_with_W_or_A_in_this_context
+#else /* __WINE__ */
+# ifdef UNICODE
+# define WINELIB_NAME_AW(func) func##W
+# else
+# define WINELIB_NAME_AW(func) func##A
+# endif /* UNICODE */
+#endif /* __WINE__ */
+
+#ifdef __WINE__
+# define DECL_WINELIB_TYPE_AW(type) /* nothing */
+#else /* __WINE__ */
+# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type;
+#endif /* __WINE__ */
+
+#ifndef NONAMELESSSTRUCT
+# if defined(__WINE__) || !defined(_FORCENAMELESSSTRUCT)
+# define NONAMELESSSTRUCT
+# endif
+#endif /* !defined(NONAMELESSSTRUCT) */
+
+#ifndef NONAMELESSUNION
+# if defined(__WINE__) || !defined(_FORCENAMELESSUNION) || !defined(__cplusplus)
+# define NONAMELESSUNION
+# endif
+#endif /* !defined(NONAMELESSUNION) */
+
+#ifndef NONAMELESSSTRUCT
+#define DUMMYSTRUCTNAME
+#define DUMMYSTRUCTNAME1
+#define DUMMYSTRUCTNAME2
+#define DUMMYSTRUCTNAME3
+#define DUMMYSTRUCTNAME4
+#define DUMMYSTRUCTNAME5
+#else /* !defined(NONAMELESSSTRUCT) */
+#define DUMMYSTRUCTNAME s
+#define DUMMYSTRUCTNAME1 s1
+#define DUMMYSTRUCTNAME2 s2
+#define DUMMYSTRUCTNAME3 s3
+#define DUMMYSTRUCTNAME4 s4
+#define DUMMYSTRUCTNAME5 s5
+#endif /* !defined(NONAMELESSSTRUCT) */
+
+#ifndef NONAMELESSUNION
+#define DUMMYUNIONNAME
+#define DUMMYUNIONNAME1
+#define DUMMYUNIONNAME2
+#define DUMMYUNIONNAME3
+#define DUMMYUNIONNAME4
+#define DUMMYUNIONNAME5
+#else /* !defined(NONAMELESSUNION) */
+#define DUMMYUNIONNAME u
+#define DUMMYUNIONNAME1 u1
+#define DUMMYUNIONNAME2 u2
+#define DUMMYUNIONNAME3 u3
+#define DUMMYUNIONNAME4 u4
+#define DUMMYUNIONNAME5 u5
+#endif /* !defined(NONAMELESSUNION) */
+
+/* Calling conventions definitions */
+
+#ifdef __i386__
+# if defined(__GNUC__) && ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)))
+# ifndef _EGCS_
+#define __stdcall __attribute__((__stdcall__))
+#define __cdecl __attribute__((__cdecl__))
+# define __RESTORE_ES __asm__ __volatile__("pushl %ds\n\tpopl %es")
+# endif
+# else
+# error You need gcc >= 2.7 to build Wine on a 386
+# endif
+#else
+# define __stdcall
+# define __cdecl
+# define __RESTORE_ES
+#endif
+
+#define CALLBACK __stdcall
+#define WINAPI __stdcall
+#define APIPRIVATE __stdcall
+#define PASCAL __stdcall
+#define pascal __stdcall
+#define _pascal __stdcall
+#define _stdcall __stdcall
+#define _fastcall __stdcall
+#define __fastcall __stdcall
+#define __export __stdcall
+#define CDECL __cdecl
+#define _CDECL __cdecl
+#define cdecl __cdecl
+#define _cdecl __cdecl
+#define WINAPIV __cdecl
+#define APIENTRY WINAPI
+
+#define __declspec(x)
+#define dllimport
+#define dllexport
+
+#define CONST const
+
+/* Standard data types. These are the same for emulator and library. */
+
+typedef void VOID;
+typedef int INT;
+typedef unsigned int UINT;
+typedef unsigned short WORD;
+typedef unsigned long DWORD;
+typedef unsigned long ULONG;
+typedef unsigned char BYTE;
+typedef long LONG;
+typedef short SHORT;
+typedef unsigned short USHORT;
+typedef char CHAR;
+typedef unsigned char UCHAR;
+
+typedef LONG SCODE;
+
+/* Some systems might have wchar_t, but we really need 16 bit characters */
+typedef unsigned short WCHAR;
+typedef int WIN_BOOL;
+typedef double DATE;
+typedef double DOUBLE;
+typedef double LONGLONG;
+typedef double ULONGLONG;
+
+/* FIXME: Wine does not compile with strict on, therefore strict
+ * handles are presently only usable on machines where sizeof(UINT) ==
+ * sizeof(void*). HANDLEs are supposed to be void* but a large amount
+ * of WINE code operates on HANDLES as if they are UINTs. So to WINE
+ * they exist as UINTs but to the Winelib user who turns on strict,
+ * they exist as void*. If there is a size difference between UINT and
+ * void* then things get ugly. */
+#ifdef STRICT
+typedef VOID* HANDLE;
+#else
+typedef UINT HANDLE;
+#endif
+
+
+typedef HANDLE *LPHANDLE;
+
+/* Integer types. These are the same for emulator and library. */
+typedef UINT WPARAM;
+typedef LONG LPARAM;
+typedef LONG HRESULT;
+typedef LONG LRESULT;
+typedef WORD ATOM;
+typedef WORD CATCHBUF[9];
+typedef WORD *LPCATCHBUF;
+typedef HANDLE HHOOK;
+typedef HANDLE HMONITOR;
+typedef DWORD LCID;
+typedef WORD LANGID;
+typedef DWORD LCTYPE;
+typedef float FLOAT;
+
+/* Pointers types. These are the same for emulator and library. */
+/* winnt types */
+typedef VOID *PVOID;
+typedef const void *PCVOID;
+typedef CHAR *PCHAR;
+typedef UCHAR *PUCHAR;
+typedef BYTE *PBYTE;
+typedef WORD *PWORD;
+typedef USHORT *PUSHORT;
+typedef SHORT *PSHORT;
+typedef ULONG *PULONG;
+typedef LONG *PLONG;
+typedef DWORD *PDWORD;
+/* common win32 types */
+typedef CHAR *LPSTR;
+typedef CHAR *PSTR;
+typedef const CHAR *LPCSTR;
+typedef const CHAR *PCSTR;
+typedef WCHAR *LPWSTR;
+typedef WCHAR *PWSTR;
+typedef const WCHAR *LPCWSTR;
+typedef const WCHAR *PCWSTR;
+typedef BYTE *LPBYTE;
+typedef WORD *LPWORD;
+typedef DWORD *LPDWORD;
+typedef LONG *LPLONG;
+typedef VOID *LPVOID;
+typedef const VOID *LPCVOID;
+typedef INT *PINT;
+typedef INT *LPINT;
+typedef UINT *PUINT;
+typedef UINT *LPUINT;
+typedef FLOAT *PFLOAT;
+typedef FLOAT *LPFLOAT;
+typedef WIN_BOOL *PWIN_BOOL;
+typedef WIN_BOOL *LPWIN_BOOL;
+
+/* Special case: a segmented pointer is just a pointer in the user's code. */
+
+#ifdef __WINE__
+typedef DWORD SEGPTR;
+#else
+typedef void* SEGPTR;
+#endif /* __WINE__ */
+
+/* Handle types that exist both in Win16 and Win32. */
+
+#ifdef STRICT
+#define DECLARE_HANDLE(a) \
+ typedef struct a##__ { int unused; } *a; \
+ typedef a *P##a; \
+ typedef a *LP##a
+#else /*STRICT*/
+#define DECLARE_HANDLE(a) \
+ typedef HANDLE a; \
+ typedef a *P##a; \
+ typedef a *LP##a
+#endif /*STRICT*/
+
+DECLARE_HANDLE(HACMDRIVERID);
+DECLARE_HANDLE(HACMDRIVER);
+DECLARE_HANDLE(HACMOBJ);
+DECLARE_HANDLE(HACMSTREAM);
+DECLARE_HANDLE(HMETAFILEPICT);
+
+DECLARE_HANDLE(HACCEL);
+DECLARE_HANDLE(HBITMAP);
+DECLARE_HANDLE(HBRUSH);
+DECLARE_HANDLE(HCOLORSPACE);
+DECLARE_HANDLE(HCURSOR);
+DECLARE_HANDLE(HDC);
+DECLARE_HANDLE(HDROP);
+DECLARE_HANDLE(HDRVR);
+DECLARE_HANDLE(HDWP);
+DECLARE_HANDLE(HENHMETAFILE);
+DECLARE_HANDLE(HFILE);
+DECLARE_HANDLE(HFONT);
+DECLARE_HANDLE(HICON);
+DECLARE_HANDLE(HINSTANCE);
+DECLARE_HANDLE(HKEY);
+DECLARE_HANDLE(HMENU);
+DECLARE_HANDLE(HMETAFILE);
+DECLARE_HANDLE(HMIDI);
+DECLARE_HANDLE(HMIDIIN);
+DECLARE_HANDLE(HMIDIOUT);
+DECLARE_HANDLE(HMIDISTRM);
+DECLARE_HANDLE(HMIXER);
+DECLARE_HANDLE(HMIXEROBJ);
+DECLARE_HANDLE(HMMIO);
+DECLARE_HANDLE(HPALETTE);
+DECLARE_HANDLE(HPEN);
+DECLARE_HANDLE(HQUEUE);
+DECLARE_HANDLE(HRGN);
+DECLARE_HANDLE(HRSRC);
+DECLARE_HANDLE(HTASK);
+DECLARE_HANDLE(HWAVE);
+DECLARE_HANDLE(HWAVEIN);
+DECLARE_HANDLE(HWAVEOUT);
+DECLARE_HANDLE(HWINSTA);
+DECLARE_HANDLE(HDESK);
+DECLARE_HANDLE(HWND);
+DECLARE_HANDLE(HKL);
+DECLARE_HANDLE(HIC);
+DECLARE_HANDLE(HRASCONN);
+
+/* Handle types that must remain interchangeable even with strict on */
+
+typedef HINSTANCE HMODULE;
+typedef HANDLE HGDIOBJ;
+typedef HANDLE HGLOBAL;
+typedef HANDLE HLOCAL;
+typedef HANDLE GLOBALHANDLE;
+typedef HANDLE LOCALHANDLE;
+
+/* Callback function pointers types */
+//WIN_BOOL CALLBACK DATEFMT_ENUMPROCA(LPSTR);
+
+typedef WIN_BOOL CALLBACK (* DATEFMT_ENUMPROCA)(LPSTR);
+typedef WIN_BOOL CALLBACK (* DATEFMT_ENUMPROCW)(LPWSTR);
+DECL_WINELIB_TYPE_AW(DATEFMT_ENUMPROC)
+typedef WIN_BOOL CALLBACK (*DLGPROC)(HWND,UINT,WPARAM,LPARAM);
+typedef LRESULT CALLBACK (*DRIVERPROC)(DWORD,HDRVR,UINT,LPARAM,LPARAM);
+typedef INT CALLBACK (*EDITWORDBREAKPROCA)(LPSTR,INT,INT,INT);
+typedef INT CALLBACK (*EDITWORDBREAKPROCW)(LPWSTR,INT,INT,INT);
+DECL_WINELIB_TYPE_AW(EDITWORDBREAKPROC)
+typedef LRESULT CALLBACK (*FARPROC)();
+typedef INT CALLBACK (*PROC)();
+typedef WIN_BOOL CALLBACK (*GRAYSTRINGPROC)(HDC,LPARAM,INT);
+typedef LRESULT CALLBACK (*HOOKPROC)(INT,WPARAM,LPARAM);
+typedef WIN_BOOL CALLBACK (*PROPENUMPROCA)(HWND,LPCSTR,HANDLE);
+typedef WIN_BOOL CALLBACK (*PROPENUMPROCW)(HWND,LPCWSTR,HANDLE);
+DECL_WINELIB_TYPE_AW(PROPENUMPROC)
+typedef WIN_BOOL CALLBACK (*PROPENUMPROCEXA)(HWND,LPCSTR,HANDLE,LPARAM);
+typedef WIN_BOOL CALLBACK (*PROPENUMPROCEXW)(HWND,LPCWSTR,HANDLE,LPARAM);
+DECL_WINELIB_TYPE_AW(PROPENUMPROCEX)
+typedef WIN_BOOL CALLBACK (* TIMEFMT_ENUMPROCA)(LPSTR);
+typedef WIN_BOOL CALLBACK (* TIMEFMT_ENUMPROCW)(LPWSTR);
+DECL_WINELIB_TYPE_AW(TIMEFMT_ENUMPROC)
+typedef VOID CALLBACK (*TIMERPROC)(HWND,UINT,UINT,DWORD);
+typedef WIN_BOOL CALLBACK (*WNDENUMPROC)(HWND,LPARAM);
+typedef LRESULT CALLBACK (*WNDPROC)(HWND,UINT,WPARAM,LPARAM);
+
+/*----------------------------------------------------------------------------
+** FIXME: Better isolate Wine's reliance on the xxx16 type definitions.
+** For now, we just isolate them to make the situation clear.
+**--------------------------------------------------------------------------*/
+/*
+ * Basic type definitions for 16 bit variations on Windows types.
+ * These types are provided mostly to insure compatibility with
+ * 16 bit windows code.
+ */
+
+#ifndef __WINE_WINDEF16_H
+#define __WINE_WINDEF16_H
+
+#include "windef.h"
+
+/* Standard data types */
+
+typedef short INT16;
+typedef unsigned short UINT16;
+typedef unsigned short WIN_BOOL16;
+
+typedef UINT16 HANDLE16;
+typedef HANDLE16 *LPHANDLE16;
+
+typedef UINT16 WPARAM16;
+typedef INT16 *LPINT16;
+typedef UINT16 *LPUINT16;
+
+#define DECLARE_HANDLE16(a) \
+ typedef HANDLE16 a##16; \
+ typedef a##16 *P##a##16; \
+ typedef a##16 *NP##a##16; \
+ typedef a##16 *LP##a##16
+
+DECLARE_HANDLE16(HACMDRIVERID);
+DECLARE_HANDLE16(HACMDRIVER);
+DECLARE_HANDLE16(HACMOBJ);
+DECLARE_HANDLE16(HACMSTREAM);
+DECLARE_HANDLE16(HMETAFILEPICT);
+
+DECLARE_HANDLE16(HACCEL);
+DECLARE_HANDLE16(HBITMAP);
+DECLARE_HANDLE16(HBRUSH);
+DECLARE_HANDLE16(HCOLORSPACE);
+DECLARE_HANDLE16(HCURSOR);
+DECLARE_HANDLE16(HDC);
+DECLARE_HANDLE16(HDROP);
+DECLARE_HANDLE16(HDRVR);
+DECLARE_HANDLE16(HDWP);
+DECLARE_HANDLE16(HENHMETAFILE);
+DECLARE_HANDLE16(HFILE);
+DECLARE_HANDLE16(HFONT);
+DECLARE_HANDLE16(HICON);
+DECLARE_HANDLE16(HINSTANCE);
+DECLARE_HANDLE16(HKEY);
+DECLARE_HANDLE16(HMENU);
+DECLARE_HANDLE16(HMETAFILE);
+DECLARE_HANDLE16(HMIDI);
+DECLARE_HANDLE16(HMIDIIN);
+DECLARE_HANDLE16(HMIDIOUT);
+DECLARE_HANDLE16(HMIDISTRM);
+DECLARE_HANDLE16(HMIXER);
+DECLARE_HANDLE16(HMIXEROBJ);
+DECLARE_HANDLE16(HMMIO);
+DECLARE_HANDLE16(HPALETTE);
+DECLARE_HANDLE16(HPEN);
+DECLARE_HANDLE16(HQUEUE);
+DECLARE_HANDLE16(HRGN);
+DECLARE_HANDLE16(HRSRC);
+DECLARE_HANDLE16(HTASK);
+DECLARE_HANDLE16(HWAVE);
+DECLARE_HANDLE16(HWAVEIN);
+DECLARE_HANDLE16(HWAVEOUT);
+DECLARE_HANDLE16(HWINSTA);
+DECLARE_HANDLE16(HDESK);
+DECLARE_HANDLE16(HWND);
+DECLARE_HANDLE16(HKL);
+DECLARE_HANDLE16(HIC);
+DECLARE_HANDLE16(HRASCONN);
+#undef DECLARE_HANDLE16
+
+typedef HINSTANCE16 HMODULE16;
+typedef HANDLE16 HGDIOBJ16;
+typedef HANDLE16 HGLOBAL16;
+typedef HANDLE16 HLOCAL16;
+
+/* The SIZE structure */
+typedef struct
+{
+ INT16 cx;
+ INT16 cy;
+} SIZE16, *PSIZE16, *LPSIZE16;
+
+/* The POINT structure */
+
+typedef struct
+{
+ INT16 x;
+ INT16 y;
+} POINT16, *PPOINT16, *LPPOINT16;
+
+/* The RECT structure */
+
+typedef struct
+{
+ INT16 left;
+ INT16 top;
+ INT16 right;
+ INT16 bottom;
+} RECT16, *LPRECT16;
+
+/* Callback function pointers types */
+
+typedef LRESULT CALLBACK (*DRIVERPROC16)(DWORD,HDRVR16,UINT16,LPARAM,LPARAM);
+typedef WIN_BOOL16 CALLBACK (*DLGPROC16)(HWND16,UINT16,WPARAM16,LPARAM);
+typedef INT16 CALLBACK (*EDITWORDBREAKPROC16)(LPSTR,INT16,INT16,INT16);
+typedef LRESULT CALLBACK (*FARPROC16)();
+typedef INT16 CALLBACK (*PROC16)();
+typedef WIN_BOOL16 CALLBACK (*GRAYSTRINGPROC16)(HDC16,LPARAM,INT16);
+typedef LRESULT CALLBACK (*HOOKPROC16)(INT16,WPARAM16,LPARAM);
+typedef WIN_BOOL16 CALLBACK (*PROPENUMPROC16)(HWND16,SEGPTR,HANDLE16);
+typedef VOID CALLBACK (*TIMERPROC16)(HWND16,UINT16,UINT16,DWORD);
+typedef LRESULT CALLBACK (*WNDENUMPROC16)(HWND16,LPARAM);
+typedef LRESULT CALLBACK (*WNDPROC16)(HWND16,UINT16,WPARAM16,LPARAM);
+
+#endif /* __WINE_WINDEF16_H */
+
+/* Define some empty macros for compatibility with Windows code. */
+
+#ifndef __WINE__
+#define NEAR
+#define FAR
+#define near
+#define far
+#define _near
+#define _far
+#define IN
+#define OUT
+#define OPTIONAL
+#endif /* __WINE__ */
+
+/* Macro for structure packing. */
+
+#ifdef __GNUC__
+#ifndef _EGCS_
+#define WINE_PACKED __attribute__((packed))
+#define WINE_UNUSED __attribute__((unused))
+#define WINE_NORETURN __attribute__((noreturn))
+#endif
+#else
+#define WINE_PACKED /* nothing */
+#define WINE_UNUSED /* nothing */
+#define WINE_NORETURN /* nothing */
+#endif
+
+/* Macros to split words and longs. */
+
+#define LOBYTE(w) ((BYTE)(WORD)(w))
+#define HIBYTE(w) ((BYTE)((WORD)(w) >> 8))
+
+#define LOWORD(l) ((WORD)(DWORD)(l))
+#define HIWORD(l) ((WORD)((DWORD)(l) >> 16))
+
+#define SLOWORD(l) ((INT16)(LONG)(l))
+#define SHIWORD(l) ((INT16)((LONG)(l) >> 16))
+
+#define MAKEWORD(low,high) ((WORD)(((BYTE)(low)) | ((WORD)((BYTE)(high))) << 8))
+#define MAKELONG(low,high) ((LONG)(((WORD)(low)) | (((DWORD)((WORD)(high))) << 16)))
+#define MAKELPARAM(low,high) ((LPARAM)MAKELONG(low,high))
+#define MAKEWPARAM(low,high) ((WPARAM)MAKELONG(low,high))
+#define MAKELRESULT(low,high) ((LRESULT)MAKELONG(low,high))
+#define MAKEINTATOM(atom) ((LPCSTR)MAKELONG((atom),0))
+
+#define SELECTOROF(ptr) (HIWORD(ptr))
+#define OFFSETOF(ptr) (LOWORD(ptr))
+
+#ifdef __WINE__
+/* macros to set parts of a DWORD (not in the Windows API) */
+#define SET_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD(val))
+#define SET_LOBYTE(dw,val) ((dw) = ((dw) & 0xffffff00) | LOBYTE(val))
+#define SET_HIBYTE(dw,val) ((dw) = ((dw) & 0xffff00ff) | (LOWORD(val) & 0xff00))
+#define ADD_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD((DWORD)(dw)+(val)))
+#endif
+
+/* Macros to access unaligned or wrong-endian WORDs and DWORDs. */
+/* Note: These macros are semantically broken, at least for wrc. wrc
+ spits out data in the platform's current binary format, *not* in
+ little-endian format. These macros are used throughout the resource
+ code to load and store data to the resources. Since it is unlikely
+ that we'll ever be dealing with little-endian resource data, the
+ byte-swapping nature of these macros has been disabled. Rather than
+ remove the use of these macros from the resource loading code, the
+ macros have simply been disabled. In the future, someone may want
+ to reactivate these macros for other purposes. In that case, the
+ resource code will have to be modified to use different macros. */
+
+#if 1
+#define PUT_WORD(ptr,w) (*(WORD *)(ptr) = (w))
+#define GET_WORD(ptr) (*(WORD *)(ptr))
+#define PUT_DWORD(ptr,dw) (*(DWORD *)(ptr) = (dw))
+#define GET_DWORD(ptr) (*(DWORD *)(ptr))
+#else
+#define PUT_WORD(ptr,w) (*(BYTE *)(ptr) = LOBYTE(w), \
+ *((BYTE *)(ptr) + 1) = HIBYTE(w))
+#define GET_WORD(ptr) ((WORD)(*(BYTE *)(ptr) | \
+ (WORD)(*((BYTE *)(ptr)+1) << 8)))
+#define PUT_DWORD(ptr,dw) (PUT_WORD((ptr),LOWORD(dw)), \
+ PUT_WORD((WORD *)(ptr)+1,HIWORD(dw)))
+#define GET_DWORD(ptr) ((DWORD)(GET_WORD(ptr) | \
+ ((DWORD)GET_WORD((WORD *)(ptr)+1) << 16)))
+#endif /* 1 */
+
+/* min and max macros */
+#define __max(a,b) (((a) > (b)) ? (a) : (b))
+#define __min(a,b) (((a) < (b)) ? (a) : (b))
+#ifndef max
+#define max(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define _MAX_PATH 260
+#define MAX_PATH 260
+#define _MAX_DRIVE 3
+#define _MAX_DIR 256
+#define _MAX_FNAME 255
+#define _MAX_EXT 256
+
+#define HFILE_ERROR16 ((HFILE16)-1)
+#define HFILE_ERROR ((HFILE)-1)
+
+/* The SIZE structure */
+typedef struct tagSIZE
+{
+ INT cx;
+ INT cy;
+} SIZE, *PSIZE, *LPSIZE;
+
+
+typedef SIZE SIZEL, *PSIZEL, *LPSIZEL;
+
+#define CONV_SIZE16TO32(s16,s32) \
+ ((s32)->cx = (INT)(s16)->cx, (s32)->cy = (INT)(s16)->cy)
+#define CONV_SIZE32TO16(s32,s16) \
+ ((s16)->cx = (INT16)(s32)->cx, (s16)->cy = (INT16)(s32)->cy)
+
+/* The POINT structure */
+typedef struct tagPOINT
+{
+ LONG x;
+ LONG y;
+} POINT, *PPOINT, *LPPOINT;
+
+typedef struct _POINTL
+{
+ LONG x;
+ LONG y;
+} POINTL;
+
+#define CONV_POINT16TO32(p16,p32) \
+ ((p32)->x = (INT)(p16)->x, (p32)->y = (INT)(p16)->y)
+#define CONV_POINT32TO16(p32,p16) \
+ ((p16)->x = (INT16)(p32)->x, (p16)->y = (INT16)(p32)->y)
+
+#define MAKEPOINT16(l) (*((POINT16 *)&(l)))
+
+/* The POINTS structure */
+
+typedef struct tagPOINTS
+{
+ SHORT x;
+ SHORT y;
+} POINTS, *PPOINTS, *LPPOINTS;
+
+
+#define MAKEPOINTS(l) (*((POINTS *)&(l)))
+
+
+/* The RECT structure */
+typedef struct tagRECT
+{
+ short left;
+ short top;
+ short right;
+ short bottom;
+} RECT, *PRECT, *LPRECT;
+typedef const RECT *LPCRECT;
+
+
+typedef struct tagRECTL
+{
+ LONG left;
+ LONG top;
+ LONG right;
+ LONG bottom;
+} RECTL, *PRECTL, *LPRECTL;
+
+typedef const RECTL *LPCRECTL;
+
+#define CONV_RECT16TO32(r16,r32) \
+ ((r32)->left = (INT)(r16)->left, (r32)->top = (INT)(r16)->top, \
+ (r32)->right = (INT)(r16)->right, (r32)->bottom = (INT)(r16)->bottom)
+#define CONV_RECT32TO16(r32,r16) \
+ ((r16)->left = (INT16)(r32)->left, (r16)->top = (INT16)(r32)->top, \
+ (r16)->right = (INT16)(r32)->right, (r16)->bottom = (INT16)(r32)->bottom)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WINE_WINDEF_H */
diff --git a/src/libw32dll/wine/windows.h b/src/libw32dll/wine/windows.h
new file mode 100644
index 000000000..cd62a0327
--- /dev/null
+++ b/src/libw32dll/wine/windows.h
@@ -0,0 +1,38 @@
+#ifndef __WINE_WINDOWS_H
+#define __WINE_WINDOWS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "shell.h"
+#include "winreg.h"
+#include "winnetwk.h"
+#include "winver.h"
+#include "lzexpand.h"
+#include "shellapi.h"
+#include "ole2.h"
+#include "winnls.h"
+#include "objbase.h"
+#include "winspool.h"
+
+#if 0
+ Where does this belong? Nobody uses this stuff anyway.
+typedef struct {
+ BYTE i; /* much more .... */
+} KANJISTRUCT;
+typedef KANJISTRUCT *LPKANJISTRUCT;
+typedef KANJISTRUCT *NPKANJISTRUCT;
+typedef KANJISTRUCT *PKANJISTRUCT;
+
+
+#endif /* 0 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __WINE_WINDOWS_H */
diff --git a/src/libw32dll/wine/winerror.h b/src/libw32dll/wine/winerror.h
new file mode 100644
index 000000000..0c78792b9
--- /dev/null
+++ b/src/libw32dll/wine/winerror.h
@@ -0,0 +1,1658 @@
+#ifndef __WINE_WINERROR_H
+#define __WINE_WINERROR_H
+
+
+extern int WIN32_LastError;
+
+#define FACILITY_NULL 0
+#define FACILITY_RPC 1
+#define FACILITY_DISPATCH 2
+#define FACILITY_STORAGE 3
+#define FACILITY_ITF 4
+#define FACILITY_WIN32 7
+#define FACILITY_WINDOWS 8
+#define FACILITY_SSPI 9
+#define FACILITY_CONTROL 10
+#define FACILITY_CERT 11
+#define FACILITY_INTERNET 12
+
+#define SEVERITY_ERROR 1
+
+
+#define MAKE_HRESULT(sev,fac,code) \
+ ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) )
+#define MAKE_SCODE(sev,fac,code) \
+ ((SCODE) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) )
+#define SUCCEEDED(stat) ((HRESULT)(stat)>=0)
+#define FAILED(stat) ((HRESULT)(stat)<0)
+
+#define HRESULT_CODE(hr) ((hr) & 0xFFFF)
+#define SCODE_CODE(sc) ((sc) & 0xFFFF)
+
+#define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1FFF)
+#define SCODE_FACILITY(sc) (((sc) >> 16) & 0x1FFF)
+
+/* ERROR_UNKNOWN is a placeholder for error conditions which haven't
+ * been tested yet so we're not exactly sure what will be returned.
+ * All instances of ERROR_UNKNOWN should be tested under Win95/NT
+ * and replaced.
+ */
+#define ERROR_UNKNOWN 99999
+
+#define SEVERITY_SUCCESS 0
+#define SEVERITY_ERROR 1
+
+#define NO_ERROR 0
+#define ERROR_SUCCESS 0
+#define ERROR_INVALID_FUNCTION 1
+#define ERROR_FILE_NOT_FOUND 2
+#define ERROR_PATH_NOT_FOUND 3
+#define ERROR_TOO_MANY_OPEN_FILES 4
+#define ERROR_ACCESS_DENIED 5
+#define ERROR_INVALID_HANDLE 6
+#define ERROR_ARENA_TRASHED 7
+#define ERROR_NOT_ENOUGH_MEMORY 8
+#define ERROR_INVALID_BLOCK 9
+#define ERROR_BAD_ENVIRONMENT 10
+#define ERROR_BAD_FORMAT 11
+#define ERROR_INVALID_ACCESS 12
+#define ERROR_INVALID_DATA 13
+#define ERROR_OUTOFMEMORY 14
+#define ERROR_INVALID_DRIVE 15
+#define ERROR_CURRENT_DIRECTORY 16
+#define ERROR_NOT_SAME_DEVICE 17
+#define ERROR_NO_MORE_FILES 18
+#define ERROR_WRITE_PROTECT 19
+#define ERROR_BAD_UNIT 20
+#define ERROR_NOT_READY 21
+#define ERROR_BAD_COMMAND 22
+#define ERROR_CRC 23
+#define ERROR_BAD_LENGTH 24
+#define ERROR_SEEK 25
+#define ERROR_NOT_DOS_DISK 26
+#define ERROR_SECTOR_NOT_FOUND 27
+#define ERROR_OUT_OF_PAPER 28
+#define ERROR_WRITE_FAULT 29
+#define ERROR_READ_FAULT 30
+#define ERROR_GEN_FAILURE 31
+#define ERROR_SHARING_VIOLATION 32
+#define ERROR_LOCK_VIOLATION 33
+#define ERROR_WRONG_DISK 34
+#define ERROR_SHARING_BUFFER_EXCEEDED 36
+#define ERROR_HANDLE_EOF 38
+#define ERROR_HANDLE_DISK_FULL 39
+#define ERROR_NOT_SUPPORTED 50
+#define ERROR_REM_NOT_LIST 51
+#define ERROR_DUP_NAME 52
+#define ERROR_BAD_NETPATH 53
+#define ERROR_NETWORK_BUSY 54
+#define ERROR_DEV_NOT_EXIST 55
+#define ERROR_TOO_MANY_CMDS 56
+#define ERROR_ADAP_HDW_ERR 57
+#define ERROR_BAD_NET_RESP 58
+#define ERROR_UNEXP_NET_ERR 59
+#define ERROR_BAD_REM_ADAP 60
+#define ERROR_PRINTQ_FULL 61
+#define ERROR_NO_SPOOL_SPACE 62
+#define ERROR_PRINT_CANCELLED 63
+#define ERROR_NETNAME_DELETED 64
+#define ERROR_NETWORK_ACCESS_DENIED 65
+#define ERROR_BAD_DEV_TYPE 66
+#define ERROR_BAD_NET_NAME 67
+#define ERROR_TOO_MANY_NAMES 68
+#define ERROR_TOO_MANY_SESS 69
+#define ERROR_SHARING_PAUSED 70
+#define ERROR_REQ_NOT_ACCEP 71
+#define ERROR_REDIR_PAUSED 72
+#define ERROR_FILE_EXISTS 80
+#define ERROR_CANNOT_MAKE 82
+#define ERROR_FAIL_I24 83
+#define ERROR_OUT_OF_STRUCTURES 84
+#define ERROR_ALREADY_ASSIGNED 85
+#define ERROR_INVALID_PASSWORD 86
+#define ERROR_INVALID_PARAMETER 87
+#define ERROR_NET_WRITE_FAULT 88
+#define ERROR_NO_PROC_SLOTS 89
+#define ERROR_TOO_MANY_SEMAPHORES 100
+#define ERROR_EXCL_SEM_ALREADY_OWNED 101
+#define ERROR_SEM_IS_SET 102
+#define ERROR_TOO_MANY_SEM_REQUESTS 103
+#define ERROR_INVALID_AT_INTERRUPT_TIME 104
+#define ERROR_SEM_OWNER_DIED 105
+#define ERROR_SEM_USER_LIMIT 106
+#define ERROR_DISK_CHANGE 107
+#define ERROR_DRIVE_LOCKED 108
+#define ERROR_BROKEN_PIPE 109
+#define ERROR_OPEN_FAILED 110
+#define ERROR_BUFFER_OVERFLOW 111
+#define ERROR_DISK_FULL 112
+#define ERROR_NO_MORE_SEARCH_HANDLES 113
+#define ERROR_INVALID_TARGET_HANDLE 114
+#define ERROR_INVALID_CATEGORY 117
+#define ERROR_INVALID_VERIFY_SWITCH 118
+#define ERROR_BAD_DRIVER_LEVEL 119
+#define ERROR_CALL_NOT_IMPLEMENTED 120
+#define ERROR_SEM_TIMEOUT 121
+#define ERROR_INSUFFICIENT_BUFFER 122
+#define ERROR_INVALID_NAME 123
+#define ERROR_INVALID_LEVEL 124
+#define ERROR_NO_VOLUME_LABEL 125
+#define ERROR_MOD_NOT_FOUND 126
+#define ERROR_PROC_NOT_FOUND 127
+#define ERROR_WAIT_NO_CHILDREN 128
+#define ERROR_CHILD_NOT_COMPLETE 129
+#define ERROR_DIRECT_ACCESS_HANDLE 130
+#define ERROR_NEGATIVE_SEEK 131
+#define ERROR_SEEK_ON_DEVICE 132
+#define ERROR_IS_JOIN_TARGET 133
+#define ERROR_IS_JOINED 134
+#define ERROR_IS_SUBSTED 135
+#define ERROR_NOT_JOINED 136
+#define ERROR_NOT_SUBSTED 137
+#define ERROR_JOIN_TO_JOIN 138
+#define ERROR_SUBST_TO_SUBST 139
+#define ERROR_JOIN_TO_SUBST 140
+#define ERROR_SUBST_TO_JOIN 141
+#define ERROR_BUSY_DRIVE 142
+#define ERROR_SAME_DRIVE 143
+#define ERROR_DIR_NOT_ROOT 144
+#define ERROR_DIR_NOT_EMPTY 145
+#define ERROR_IS_SUBST_PATH 146
+#define ERROR_IS_JOIN_PATH 147
+#define ERROR_PATH_BUSY 148
+#define ERROR_IS_SUBST_TARGET 149
+#define ERROR_SYSTEM_TRACE 150
+#define ERROR_INVALID_EVENT_COUNT 151
+#define ERROR_TOO_MANY_MUXWAITERS 152
+#define ERROR_INVALID_LIST_FORMAT 153
+#define ERROR_LABEL_TOO_LONG 154
+#define ERROR_TOO_MANY_TCBS 155
+#define ERROR_SIGNAL_REFUSED 156
+#define ERROR_DISCARDED 157
+#define ERROR_NOT_LOCKED 158
+#define ERROR_BAD_THREADID_ADDR 159
+#define ERROR_BAD_ARGUMENTS 160
+#define ERROR_BAD_PATHNAME 161
+#define ERROR_SIGNAL_PENDING 162
+#define ERROR_MAX_THRDS_REACHED 164
+#define ERROR_LOCK_FAILED 167
+#define ERROR_BUSY 170
+#define ERROR_CANCEL_VIOLATION 173
+#define ERROR_ATOMIC_LOCKS_NOT_SUPPORTED 174
+#define ERROR_INVALID_SEGMENT_NUMBER 180
+#define ERROR_INVALID_ORDINAL 182
+#define ERROR_ALREADY_EXISTS 183
+#define ERROR_INVALID_FLAG_NUMBER 186
+#define ERROR_SEM_NOT_FOUND 187
+#define ERROR_INVALID_STARTING_CODESEG 188
+#define ERROR_INVALID_STACKSEG 189
+#define ERROR_INVALID_MODULETYPE 190
+#define ERROR_INVALID_EXE_SIGNATURE 191
+#define ERROR_EXE_MARKED_INVALID 192
+#define ERROR_BAD_EXE_FORMAT 193
+#define ERROR_ITERATED_DATA_EXCEEDS_64k 194
+#define ERROR_INVALID_MINALLOCSIZE 195
+#define ERROR_DYNLINK_FROM_INVALID_RING 196
+#define ERROR_IOPL_NOT_ENABLED 197
+#define ERROR_INVALID_SEGDPL 198
+#define ERROR_AUTODATASEG_EXCEEDS_64k 199
+#define ERROR_RING2SEG_MUST_BE_MOVABLE 200
+#define ERROR_RELOC_CHAIN_XEEDS_SEGLIM 201
+#define ERROR_INFLOOP_IN_RELOC_CHAIN 202
+#define ERROR_ENVVAR_NOT_FOUND 203
+#define ERROR_NO_SIGNAL_SENT 205
+#define ERROR_FILENAME_EXCED_RANGE 206
+#define ERROR_RING2_STACK_IN_USE 207
+#define ERROR_META_EXPANSION_TOO_LONG 208
+#define ERROR_INVALID_SIGNAL_NUMBER 209
+#define ERROR_THREAD_1_INACTIVE 210
+#define ERROR_LOCKED 212
+#define ERROR_TOO_MANY_MODULES 214
+#define ERROR_NESTING_NOT_ALLOWED 215
+#define ERROR_EXE_MACHINE_TYPE_MISMATCH 216
+#define ERROR_BAD_PIPE 230
+#define ERROR_PIPE_BUSY 231
+#define ERROR_NO_DATA 232
+#define ERROR_PIPE_NOT_CONNECTED 233
+#define ERROR_MORE_DATA 234
+#define ERROR_VC_DISCONNECTED 240
+#define ERROR_INVALID_EA_NAME 254
+#define ERROR_EA_LIST_INCONSISTENT 255
+#define ERROR_NO_MORE_ITEMS 259
+#define ERROR_CANNOT_COPY 266
+#define ERROR_DIRECTORY 267
+#define ERROR_EAS_DIDNT_FIT 275
+#define ERROR_EA_FILE_CORRUPT 276
+#define ERROR_EA_TABLE_FULL 277
+#define ERROR_INVALID_EA_HANDLE 278
+#define ERROR_EAS_NOT_SUPPORTED 282
+#define ERROR_NOT_OWNER 288
+#define ERROR_TOO_MANY_POSTS 298
+#define ERROR_PARTIAL_COPY 299
+#define ERROR_OPLOCK_NOT_GRANTED 300
+#define ERROR_INVALID_OPLOCK_PROTOCOL 301
+#define ERROR_MR_MID_NOT_FOUND 317
+#define ERROR_INVALID_ADDRESS 487
+#define ERROR_ARITHMETIC_OVERFLOW 534
+#define ERROR_PIPE_CONNECTED 535
+#define ERROR_PIPE_LISTENING 536
+#define ERROR_EA_ACCESS_DENIED 994
+#define ERROR_OPERATION_ABORTED 995
+#define ERROR_IO_INCOMPLETE 996
+#define ERROR_IO_PENDING 997
+#define ERROR_NOACCESS 998
+#define ERROR_SWAPERROR 999
+#define ERROR_STACK_OVERFLOW 1001
+#define ERROR_INVALID_MESSAGE 1002
+#define ERROR_CAN_NOT_COMPLETE 1003
+#define ERROR_INVALID_FLAGS 1004
+#define ERROR_UNRECOGNIZED_VOLUME 1005
+#define ERROR_FILE_INVALID 1006
+#define ERROR_FULLSCREEN_MODE 1007
+#define ERROR_NO_TOKEN 1008
+#define ERROR_BADDB 1009
+#define ERROR_BADKEY 1010
+#define ERROR_CANTOPEN 1011
+#define ERROR_CANTREAD 1012
+#define ERROR_CANTWRITE 1013
+#define ERROR_REGISTRY_RECOVERED 1014
+#define ERROR_REGISTRY_CORRUPT 1015
+#define ERROR_REGISTRY_IO_FAILED 1016
+#define ERROR_NOT_REGISTRY_FILE 1017
+#define ERROR_KEY_DELETED 1018
+#define ERROR_NO_LOG_SPACE 1019
+#define ERROR_KEY_HAS_CHILDREN 1020
+#define ERROR_CHILD_MUST_BE_VOLATILE 1021
+#define ERROR_NOTIFY_ENUM_DIR 1022
+#define ERROR_DEPENDENT_SERVICES_RUNNING 1051
+#define ERROR_INVALID_SERVICE_CONTROL 1052
+#define ERROR_SERVICE_REQUEST_TIMEOUT 1053
+#define ERROR_SERVICE_NO_THREAD 1054
+#define ERROR_SERVICE_DATABASE_LOCKED 1055
+#define ERROR_SERVICE_ALREADY_RUNNING 1056
+#define ERROR_INVALID_SERVICE_ACCOUNT 1057
+#define ERROR_SERVICE_DISABLED 1058
+#define ERROR_CIRCULAR_DEPENDENCY 1059
+#define ERROR_SERVICE_DOES_NOT_EXIST 1060
+#define ERROR_SERVICE_CANNOT_ACCEPT_CTRL 1061
+#define ERROR_SERVICE_NOT_ACTIVE 1062
+#define ERROR_FAILED_SERVICE_CONTROLLER_CONNECT 1063
+#define ERROR_EXCEPTION_IN_SERVICE 1064
+#define ERROR_DATABASE_DOES_NOT_EXIST 1065
+#define ERROR_SERVICE_SPECIFIC_ERROR 1066
+#define ERROR_PROCESS_ABORTED 1067
+#define ERROR_SERVICE_DEPENDENCY_FAIL 1068
+#define ERROR_SERVICE_LOGON_FAILED 1069
+#define ERROR_SERVICE_START_HANG 1070
+#define ERROR_INVALID_SERVICE_LOCK 1071
+#define ERROR_SERVICE_MARKED_FOR_DELETE 1072
+#define ERROR_SERVICE_EXISTS 1073
+#define ERROR_ALREADY_RUNNING_LKG 1074
+#define ERROR_SERVICE_DEPENDENCY_DELETED 1075
+#define ERROR_BOOT_ALREADY_ACCEPTED 1076
+#define ERROR_SERVICE_NEVER_STARTED 1077
+#define ERROR_DUPLICATE_SERVICE_NAME 1078
+#define ERROR_DIFFERENT_SERVICE_ACCOUNT 1079
+#define ERROR_CANNOT_DETECT_DRIVER_FAILURE 1080
+#define ERROR_CANNOT_DETECT_PROCESS_ABORT 1081
+#define ERROR_NO_RECOVERY_PROGRAM 1082
+#define ERROR_SERVICE_NOT_IN_EXE 1083
+#define ERROR_END_OF_MEDIA 1100
+#define ERROR_FILEMARK_DETECTED 1101
+#define ERROR_BEGINNING_OF_MEDIA 1102
+#define ERROR_SETMARK_DETECTED 1103
+#define ERROR_NO_DATA_DETECTED 1104
+#define ERROR_PARTITION_FAILURE 1105
+#define ERROR_INVALID_BLOCK_LENGTH 1106
+#define ERROR_DEVICE_NOT_PARTITIONED 1107
+#define ERROR_UNABLE_TO_LOCK_MEDIA 1108
+#define ERROR_UNABLE_TO_UNLOAD_MEDIA 1109
+#define ERROR_MEDIA_CHANGED 1110
+#define ERROR_BUS_RESET 1111
+#define ERROR_NO_MEDIA_IN_DRIVE 1112
+#define ERROR_NO_UNICODE_TRANSLATION 1113
+#define ERROR_DLL_INIT_FAILED 1114
+#define ERROR_SHUTDOWN_IN_PROGRESS 1115
+#define ERROR_NO_SHUTDOWN_IN_PROGRESS 1116
+#define ERROR_IO_DEVICE 1117
+#define ERROR_SERIAL_NO_DEVICE 1118
+#define ERROR_IRQ_BUSY 1119
+#define ERROR_MORE_WRITES 1120
+#define ERROR_COUNTER_TIMEOUT 1121
+#define ERROR_FLOPPY_ID_MARK_NOT_FOUND 1122
+#define ERROR_FLOPPY_WRONG_CYLINDER 1123
+#define ERROR_FLOPPY_UNKNOWN_ERROR 1124
+#define ERROR_FLOPPY_BAD_REGISTERS 1125
+#define ERROR_DISK_RECALIBRATE_FAILED 1126
+#define ERROR_DISK_OPERATION_FAILED 1127
+#define ERROR_DISK_RESET_FAILED 1128
+#define ERROR_EOM_OVERFLOW 1129
+#define ERROR_NOT_ENOUGH_SERVER_MEMORY 1130
+#define ERROR_POSSIBLE_DEADLOCK 1131
+#define ERROR_MAPPED_ALIGNMENT 1132
+#define ERROR_SET_POWER_STATE_VETOED 1140
+#define ERROR_SET_POWER_STATE_FAILED 1141
+#define ERROR_TOO_MANY_LINKS 1142
+#define ERROR_OLD_WIN_VERSION 1150
+#define ERROR_APP_WRONG_OS 1151
+#define ERROR_SINGLE_INSTANCE_APP 1152
+#define ERROR_RMODE_APP 1153
+#define ERROR_INVALID_DLL 1154
+#define ERROR_NO_ASSOCIATION 1155
+#define ERROR_DDE_FAIL 1156
+#define ERROR_DLL_NOT_FOUND 1157
+#define ERROR_NO_MORE_USER_HANDLES 1158
+#define ERROR_MESSAGE_SYNC_ONLY 1159
+#define ERROR_SOURCE_ELEMENT_EMPTY 1160
+#define ERROR_DESTINATION_ELEMENT_FULL 1161
+#define ERROR_ILLEGAL_ELEMENT_ADDRESS 1162
+#define ERROR_MAGAZINE_NOT_PRESENT 1163
+#define ERROR_DEVICE_REINITIALIZATION_NEEDED 1164
+#define ERROR_DEVICE_REQUIRES_CLEANING 1165
+#define ERROR_DEVICE_DOOR_OPEN 1166
+#define ERROR_DEVICE_NOT_CONNECTED 1167
+#define ERROR_NOT_FOUND 1168
+#define ERROR_NO_MATCH 1169
+#define ERROR_SET_NOT_FOUND 1170
+#define ERROR_POINT_NOT_FOUND 1171
+#define ERROR_NO_TRACKING_SERVICE 1172
+#define ERROR_NO_VOLUME_ID 1173
+#define ERROR_UNABLE_TO_REMOVE_REPLACED 1175
+#define ERROR_UNABLE_TO_MOVE_REPLACEMENT 1176
+#define ERROR_UNABLE_TO_MOVE_REPLACEMENT_2 1177
+#define ERROR_JOURNAL_DELETE_IN_PROGRESS 1178
+#define ERROR_JOURNAL_NOT_ACTIVE 1179
+#define ERROR_POTENTIAL_FILE_FOUND 1180
+#define ERROR_JOURNAL_ENTRY_DELETED 1181
+#define ERROR_BAD_DEVICE 1200
+#define ERROR_CONNECTION_UNAVAIL 1201
+#define ERROR_DEVICE_ALREADY_REMEMBERED 1202
+#define ERROR_NO_NET_OR_BAD_PATH 1203
+#define ERROR_BAD_PROVIDER 1204
+#define ERROR_CANNOT_OPEN_PROFILE 1205
+#define ERROR_BAD_PROFILE 1206
+#define ERROR_NOT_CONTAINER 1207
+#define ERROR_EXTENDED_ERROR 1208
+#define ERROR_INVALID_GROUPNAME 1209
+#define ERROR_INVALID_COMPUTERNAME 1210
+#define ERROR_INVALID_EVENTNAME 1211
+#define ERROR_INVALID_DOMAINNAME 1212
+#define ERROR_INVALID_SERVICENAME 1213
+#define ERROR_INVALID_NETNAME 1214
+#define ERROR_INVALID_SHARENAME 1215
+#define ERROR_INVALID_PASSWORDNAME 1216
+#define ERROR_INVALID_MESSAGENAME 1217
+#define ERROR_INVALID_MESSAGEDEST 1218
+#define ERROR_SESSION_CREDENTIAL_CONFLICT 1219
+#define ERROR_REMOTE_SESSION_LIMIT_EXCEEDED 1220
+#define ERROR_DUP_DOMAINNAME 1221
+#define ERROR_NO_NETWORK 1222
+#define ERROR_CANCELLED 1223
+#define ERROR_USER_MAPPED_FILE 1224
+#define ERROR_CONNECTION_REFUSED 1225
+#define ERROR_GRACEFUL_DISCONNECT 1226
+#define ERROR_ADDRESS_ALREADY_ASSOCIATED 1227
+#define ERROR_ADDRESS_NOT_ASSOCIATED 1228
+#define ERROR_CONNECTION_INVALID 1229
+#define ERROR_CONNECTION_ACTIVE 1230
+#define ERROR_NETWORK_UNREACHABLE 1231
+#define ERROR_HOST_UNREACHABLE 1232
+#define ERROR_PROTOCOL_UNREACHABLE 1233
+#define ERROR_PORT_UNREACHABLE 1234
+#define ERROR_REQUEST_ABORTED 1235
+#define ERROR_CONNECTION_ABORTED 1236
+#define ERROR_RETRY 1237
+#define ERROR_CONNECTION_COUNT_LIMIT 1238
+#define ERROR_LOGIN_TIME_RESTRICTION 1239
+#define ERROR_LOGIN_WKSTA_RESTRICTION 1240
+#define ERROR_INCORRECT_ADDRESS 1241
+#define ERROR_ALREADY_REGISTERED 1242
+#define ERROR_SERVICE_NOT_FOUND 1243
+#define ERROR_NOT_AUTHENTICATED 1244
+#define ERROR_NOT_LOGGED_ON 1245
+#define ERROR_CONTINUE 1246
+#define ERROR_ALREADY_INITIALIZED 1247
+#define ERROR_NO_MORE_DEVICES 1248
+#define ERROR_NO_SUCH_SITE 1249
+#define ERROR_DOMAIN_CONTROLLER_EXISTS 1250
+#define ERROR_ONLY_IF_CONNECTED 1251
+#define ERROR_OVERRIDE_NOCHANGES 1252
+#define ERROR_BAD_USER_PROFILE 1253
+#define ERROR_NOT_SUPPORTED_ON_SBS 1254
+#define ERROR_NOT_ALL_ASSIGNED 1300
+#define ERROR_SOME_NOT_MAPPED 1301
+#define ERROR_NO_QUOTAS_FOR_ACCOUNT 1302
+#define ERROR_LOCAL_USER_SESSION_KEY 1303
+#define ERROR_NULL_LM_PASSWORD 1304
+#define ERROR_UNKNOWN_REVISION 1305
+#define ERROR_REVISION_MISMATCH 1306
+#define ERROR_INVALID_OWNER 1307
+#define ERROR_INVALID_PRIMARY_GROUP 1308
+#define ERROR_NO_IMPERSONATION_TOKEN 1309
+#define ERROR_CANT_DISABLE_MANDATORY 1310
+#define ERROR_NO_LOGON_SERVERS 1311
+#define ERROR_NO_SUCH_LOGON_SESSION 1312
+#define ERROR_NO_SUCH_PRIVILEGE 1313
+#define ERROR_PRIVILEGE_NOT_HELD 1314
+#define ERROR_INVALID_ACCOUNT_NAME 1315
+#define ERROR_USER_EXISTS 1316
+#define ERROR_NO_SUCH_USER 1317
+#define ERROR_GROUP_EXISTS 1318
+#define ERROR_NO_SUCH_GROUP 1319
+#define ERROR_MEMBER_IN_GROUP 1320
+#define ERROR_MEMBER_NOT_IN_GROUP 1321
+#define ERROR_LAST_ADMIN 1322
+#define ERROR_WRONG_PASSWORD 1323
+#define ERROR_ILL_FORMED_PASSWORD 1324
+#define ERROR_PASSWORD_RESTRICTION 1325
+#define ERROR_LOGON_FAILURE 1326
+#define ERROR_ACCOUNT_RESTRICTION 1327
+#define ERROR_INVALID_LOGON_HOURS 1328
+#define ERROR_INVALID_WORKSTATION 1329
+#define ERROR_PASSWORD_EXPIRED 1330
+#define ERROR_ACCOUNT_DISABLED 1331
+#define ERROR_NONE_MAPPED 1332
+#define ERROR_TOO_MANY_LUIDS_REQUESTED 1333
+#define ERROR_LUIDS_EXHAUSTED 1334
+#define ERROR_INVALID_SUB_AUTHORITY 1335
+#define ERROR_INVALID_ACL 1336
+#define ERROR_INVALID_SID 1337
+#define ERROR_INVALID_SECURITY_DESCR 1338
+#define ERROR_BAD_INHERITANCE_ACL 1340
+#define ERROR_SERVER_DISABLED 1341
+#define ERROR_SERVER_NOT_DISABLED 1342
+#define ERROR_INVALID_ID_AUTHORITY 1343
+#define ERROR_ALLOTTED_SPACE_EXCEEDED 1344
+#define ERROR_INVALID_GROUP_ATTRIBUTES 1345
+#define ERROR_BAD_IMPERSONATION_LEVEL 1346
+#define ERROR_CANT_OPEN_ANONYMOUS 1347
+#define ERROR_BAD_VALIDATION_CLASS 1348
+#define ERROR_BAD_TOKEN_TYPE 1349
+#define ERROR_NO_SECURITY_ON_OBJECT 1350
+#define ERROR_CANT_ACCESS_DOMAIN_INFO 1351
+#define ERROR_INVALID_SERVER_STATE 1352
+#define ERROR_INVALID_DOMAIN_STATE 1353
+#define ERROR_INVALID_DOMAIN_ROLE 1354
+#define ERROR_NO_SUCH_DOMAIN 1355
+#define ERROR_DOMAIN_EXISTS 1356
+#define ERROR_DOMAIN_LIMIT_EXCEEDED 1357
+#define ERROR_INTERNAL_DB_CORRUPTION 1358
+#define ERROR_INTERNAL_ERROR 1359
+#define ERROR_GENERIC_NOT_MAPPED 1360
+#define ERROR_BAD_DESCRIPTOR_FORMAT 1361
+#define ERROR_NOT_LOGON_PROCESS 1362
+#define ERROR_LOGON_SESSION_EXISTS 1363
+#define ERROR_NO_SUCH_PACKAGE 1364
+#define ERROR_BAD_LOGON_SESSION_STATE 1365
+#define ERROR_LOGON_SESSION_COLLISION 1366
+#define ERROR_INVALID_LOGON_TYPE 1367
+#define ERROR_CANNOT_IMPERSONATE 1368
+#define ERROR_RXACT_INVALID_STATE 1369
+#define ERROR_RXACT_COMMIT_FAILURE 1370
+#define ERROR_SPECIAL_ACCOUNT 1371
+#define ERROR_SPECIAL_GROUP 1372
+#define ERROR_SPECIAL_USER 1373
+#define ERROR_MEMBERS_PRIMARY_GROUP 1374
+#define ERROR_TOKEN_ALREADY_IN_USE 1375
+#define ERROR_NO_SUCH_ALIAS 1376
+#define ERROR_MEMBER_NOT_IN_ALIAS 1377
+#define ERROR_MEMBER_IN_ALIAS 1378
+#define ERROR_ALIAS_EXISTS 1379
+#define ERROR_LOGON_NOT_GRANTED 1380
+#define ERROR_TOO_MANY_SECRETS 1381
+#define ERROR_SECRET_TOO_LONG 1382
+#define ERROR_INTERNAL_DB_ERROR 1383
+#define ERROR_TOO_MANY_CONTEXT_IDS 1384
+#define ERROR_LOGON_TYPE_NOT_GRANTED 1385
+#define ERROR_NT_CROSS_ENCRYPTION_REQUIRED 1386
+#define ERROR_NO_SUCH_MEMBER 1387
+#define ERROR_INVALID_MEMBER 1388
+#define ERROR_TOO_MANY_SIDS 1389
+#define ERROR_LM_CROSS_ENCRYPTION_REQUIRED 1390
+#define ERROR_NO_INHERITANCE 1391
+#define ERROR_FILE_CORRUPT 1392
+#define ERROR_DISK_CORRUPT 1393
+#define ERROR_NO_USER_SESSION_KEY 1394
+#define ERROR_LICENSE_QUOTA_EXCEEDED 1395
+#define ERROR_WRONG_TARGET_NAME 1396
+#define ERROR_MUTUAL_AUTH_FAILED 1397
+#define ERROR_TIME_SKEW 1398
+#define ERROR_INVALID_WINDOW_HANDLE 1400
+#define ERROR_INVALID_MENU_HANDLE 1401
+#define ERROR_INVALID_CURSOR_HANDLE 1402
+#define ERROR_INVALID_ACCEL_HANDLE 1403
+#define ERROR_INVALID_HOOK_HANDLE 1404
+#define ERROR_INVALID_DWP_HANDLE 1405
+#define ERROR_TLW_WITH_WSCHILD 1406
+#define ERROR_CANNOT_FIND_WND_CLASS 1407
+#define ERROR_WINDOW_OF_OTHER_THREAD 1408
+#define ERROR_HOTKEY_ALREADY_REGISTERED 1409
+#define ERROR_CLASS_ALREADY_EXISTS 1410
+#define ERROR_CLASS_DOES_NOT_EXIST 1411
+#define ERROR_CLASS_HAS_WINDOWS 1412
+#define ERROR_INVALID_INDEX 1413
+#define ERROR_INVALID_ICON_HANDLE 1414
+#define ERROR_PRIVATE_DIALOG_INDEX 1415
+#define ERROR_LISTBOX_ID_NOT_FOUND 1416
+#define ERROR_NO_WILDCARD_CHARACTERS 1417
+#define ERROR_CLIPBOARD_NOT_OPEN 1418
+#define ERROR_HOTKEY_NOT_REGISTERED 1419
+#define ERROR_WINDOW_NOT_DIALOG 1420
+#define ERROR_CONTROL_ID_NOT_FOUND 1421
+#define ERROR_INVALID_COMBOBOX_MESSAGE 1422
+#define ERROR_WINDOW_NOT_COMBOBOX 1423
+#define ERROR_INVALID_EDIT_HEIGHT 1424
+#define ERROR_DC_NOT_FOUND 1425
+#define ERROR_INVALID_HOOK_FILTER 1426
+#define ERROR_INVALID_FILTER_PROC 1427
+#define ERROR_HOOK_NEEDS_HMOD 1428
+#define ERROR_GLOBAL_ONLY_HOOK 1429
+#define ERROR_JOURNAL_HOOK_SET 1430
+#define ERROR_HOOK_NOT_INSTALLED 1431
+#define ERROR_INVALID_LB_MESSAGE 1432
+#define ERROR_SETCOUNT_ON_BAD_LB 1433
+#define ERROR_LB_WITHOUT_TABSTOPS 1434
+#define ERROR_DESTROY_OBJECT_OF_OTHER_THREAD 1435
+#define ERROR_CHILD_WINDOW_MENU 1436
+#define ERROR_NO_SYSTEM_MENU 1437
+#define ERROR_INVALID_MSGBOX_STYLE 1438
+#define ERROR_INVALID_SPI_VALUE 1439
+#define ERROR_SCREEN_ALREADY_LOCKED 1440
+#define ERROR_HWNDS_HAVE_DIFF_PARENT 1441
+#define ERROR_NOT_CHILD_WINDOW 1442
+#define ERROR_INVALID_GW_COMMAND 1443
+#define ERROR_INVALID_THREAD_ID 1444
+#define ERROR_NON_MDICHILD_WINDOW 1445
+#define ERROR_POPUP_ALREADY_ACTIVE 1446
+#define ERROR_NO_SCROLLBARS 1447
+#define ERROR_INVALID_SCROLLBAR_RANGE 1448
+#define ERROR_INVALID_SHOWWIN_COMMAND 1449
+#define ERROR_NO_SYSTEM_RESOURCES 1450
+#define ERROR_NONPAGED_SYSTEM_RESOURCES 1451
+#define ERROR_PAGED_SYSTEM_RESOURCES 1452
+#define ERROR_WORKING_SET_QUOTA 1453
+#define ERROR_PAGEFILE_QUOTA 1454
+#define ERROR_COMMITMENT_LIMIT 1455
+#define ERROR_MENU_ITEM_NOT_FOUND 1456
+#define ERROR_INVALID_KEYBOARD_HANDLE 1457
+#define ERROR_HOOK_TYPE_NOT_ALLOWED 1458
+#define ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION 1459
+#define ERROR_TIMEOUT 1460
+#define ERROR_INVALID_MONITOR_HANDLE 1461
+#define ERROR_EVENTLOG_FILE_CORRUPT 1500
+#define ERROR_EVENTLOG_CANT_START 1501
+#define ERROR_LOG_FILE_FULL 1502
+#define ERROR_EVENTLOG_FILE_CHANGED 1503
+#define ERROR_INSTALL_SERVICE_FAILURE 1601
+#define ERROR_INSTALL_USEREXIT 1602
+#define ERROR_INSTALL_FAILURE 1603
+#define ERROR_INSTALL_SUSPEND 1604
+#define ERROR_UNKNOWN_PRODUCT 1605
+#define ERROR_UNKNOWN_FEATURE 1606
+#define ERROR_UNKNOWN_COMPONENT 1607
+#define ERROR_UNKNOWN_PROPERTY 1608
+#define ERROR_INVALID_HANDLE_STATE 1609
+#define ERROR_BAD_CONFIGURATION 1610
+#define ERROR_INDEX_ABSENT 1611
+#define ERROR_INSTALL_SOURCE_ABSENT 1612
+#define ERROR_INSTALL_PACKAGE_VERSION 1613
+#define ERROR_PRODUCT_UNINSTALLED 1614
+#define ERROR_BAD_QUERY_SYNTAX 1615
+#define ERROR_INVALID_FIELD 1616
+#define ERROR_DEVICE_REMOVED 1617
+#define ERROR_INSTALL_ALREADY_RUNNING 1618
+#define ERROR_INSTALL_PACKAGE_OPEN_FAILED 1619
+#define ERROR_INSTALL_PACKAGE_INVALID 1620
+#define ERROR_INSTALL_UI_FAILURE 1621
+#define ERROR_INSTALL_LOG_FAILURE 1622
+#define ERROR_INSTALL_LANGUAGE_UNSUPPORTED 1623
+#define ERROR_INSTALL_TRANSFORM_FAILURE 1624
+#define ERROR_INSTALL_PACKAGE_REJECTED 1625
+#define ERROR_FUNCTION_NOT_CALLED 1626
+#define ERROR_FUNCTION_FAILED 1627
+#define ERROR_INVALID_TABLE 1628
+#define ERROR_DATATYPE_MISMATCH 1629
+#define ERROR_UNSUPPORTED_TYPE 1630
+#define ERROR_CREATE_FAILED 1631
+#define ERROR_INSTALL_TEMP_UNWRITABLE 1632
+#define ERROR_INSTALL_PLATFORM_UNSUPPORTED 1633
+#define ERROR_INSTALL_NOTUSED 1634
+#define ERROR_PATCH_PACKAGE_OPEN_FAILED 1635
+#define ERROR_PATCH_PACKAGE_INVALID 1636
+#define ERROR_PATCH_PACKAGE_UNSUPPORTED 1637
+#define ERROR_PRODUCT_VERSION 1638
+#define ERROR_INVALID_COMMAND_LINE 1639
+#define ERROR_INSTALL_REMOTE_DISALLOWED 1640
+#define ERROR_SUCCESS_REBOOT_INITIATED 1641
+#define RPC_S_INVALID_STRING_BINDING 1700
+#define RPC_S_WRONG_KIND_OF_BINDING 1701
+#define RPC_S_INVALID_BINDING 1702
+#define RPC_S_PROTSEQ_NOT_SUPPORTED 1703
+#define RPC_S_INVALID_RPC_PROTSEQ 1704
+#define RPC_S_INVALID_STRING_UUID 1705
+#define RPC_S_INVALID_ENDPOINT_FORMAT 1706
+#define RPC_S_INVALID_NET_ADDR 1707
+#define RPC_S_NO_ENDPOINT_FOUND 1708
+#define RPC_S_INVALID_TIMEOUT 1709
+#define RPC_S_OBJECT_NOT_FOUND 1710
+#define RPC_S_ALREADY_REGISTERED 1711
+#define RPC_S_TYPE_ALREADY_REGISTERED 1712
+#define RPC_S_ALREADY_LISTENING 1713
+#define RPC_S_NO_PROTSEQS_REGISTERED 1714
+#define RPC_S_NOT_LISTENING 1715
+#define RPC_S_UNKNOWN_MGR_TYPE 1716
+#define RPC_S_UNKNOWN_IF 1717
+#define RPC_S_NO_BINDINGS 1718
+#define RPC_S_NO_PROTSEQS 1719
+#define RPC_S_CANT_CREATE_ENDPOINT 1720
+#define RPC_S_OUT_OF_RESOURCES 1721
+#define RPC_S_SERVER_UNAVAILABLE 1722
+#define RPC_S_SERVER_TOO_BUSY 1723
+#define RPC_S_INVALID_NETWORK_OPTIONS 1724
+#define RPC_S_NO_CALL_ACTIVE 1725
+#define RPC_S_CALL_FAILED 1726
+#define RPC_S_CALL_FAILED_DNE 1727
+#define RPC_S_PROTOCOL_ERROR 1728
+#define RPC_S_UNSUPPORTED_TRANS_SYN 1730
+#define RPC_S_UNSUPPORTED_TYPE 1732
+#define RPC_S_INVALID_TAG 1733
+#define RPC_S_INVALID_BOUND 1734
+#define RPC_S_NO_ENTRY_NAME 1735
+#define RPC_S_INVALID_NAME_SYNTAX 1736
+#define RPC_S_UNSUPPORTED_NAME_SYNTAX 1737
+#define RPC_S_UUID_NO_ADDRESS 1739
+#define RPC_S_DUPLICATE_ENDPOINT 1740
+#define RPC_S_UNKNOWN_AUTHN_TYPE 1741
+#define RPC_S_MAX_CALLS_TOO_SMALL 1742
+#define RPC_S_STRING_TOO_LONG 1743
+#define RPC_S_PROTSEQ_NOT_FOUND 1744
+#define RPC_S_PROCNUM_OUT_OF_RANGE 1745
+#define RPC_S_BINDING_HAS_NO_AUTH 1746
+#define RPC_S_UNKNOWN_AUTHN_SERVICE 1747
+#define RPC_S_UNKNOWN_AUTHN_LEVEL 1748
+#define RPC_S_INVALID_AUTH_IDENTITY 1749
+#define RPC_S_UNKNOWN_AUTHZ_SERVICE 1750
+#define EPT_S_INVALID_ENTRY 1751
+#define EPT_S_CANT_PERFORM_OP 1752
+#define EPT_S_NOT_REGISTERED 1753
+#define RPC_S_NOTHING_TO_EXPORT 1754
+#define RPC_S_INCOMPLETE_NAME 1755
+#define RPC_S_INVALID_VERS_OPTION 1756
+#define RPC_S_NO_MORE_MEMBERS 1757
+#define RPC_S_NOT_ALL_OBJS_UNEXPORTED 1758
+#define RPC_S_INTERFACE_NOT_FOUND 1759
+#define RPC_S_ENTRY_ALREADY_EXISTS 1760
+#define RPC_S_ENTRY_NOT_FOUND 1761
+#define RPC_S_NAME_SERVICE_UNAVAILABLE 1762
+#define RPC_S_INVALID_NAF_ID 1763
+#define RPC_S_CANNOT_SUPPORT 1764
+#define RPC_S_NO_CONTEXT_AVAILABLE 1765
+#define RPC_S_INTERNAL_ERROR 1766
+#define RPC_S_ZERO_DIVIDE 1767
+#define RPC_S_ADDRESS_ERROR 1768
+#define RPC_S_FP_DIV_ZERO 1769
+#define RPC_S_FP_UNDERFLOW 1770
+#define RPC_S_FP_OVERFLOW 1771
+#define RPC_X_NO_MORE_ENTRIES 1772
+#define RPC_X_SS_CHAR_TRANS_OPEN_FAIL 1773
+#define RPC_X_SS_CHAR_TRANS_SHORT_FILE 1774
+#define RPC_X_SS_IN_NULL_CONTEXT 1775
+#define RPC_X_SS_CONTEXT_DAMAGED 1777
+#define RPC_X_SS_HANDLES_MISMATCH 1778
+#define RPC_X_SS_CANNOT_GET_CALL_HANDLE 1779
+#define RPC_X_NULL_REF_POINTER 1780
+#define RPC_X_ENUM_VALUE_OUT_OF_RANGE 1781
+#define RPC_X_BYTE_COUNT_TOO_SMALL 1782
+#define RPC_X_BAD_STUB_DATA 1783
+#define ERROR_INVALID_USER_BUFFER 1784
+#define ERROR_UNRECOGNIZED_MEDIA 1785
+#define ERROR_NO_TRUST_LSA_SECRET 1786
+#define ERROR_NO_TRUST_SAM_ACCOUNT 1787
+#define ERROR_TRUSTED_DOMAIN_FAILURE 1788
+#define ERROR_TRUSTED_RELATIONSHIP_FAILURE 1789
+#define ERROR_TRUST_FAILURE 1790
+#define RPC_S_CALL_IN_PROGRESS 1791
+#define ERROR_NETLOGON_NOT_STARTED 1792
+#define ERROR_ACCOUNT_EXPIRED 1793
+#define ERROR_REDIRECTOR_HAS_OPEN_HANDLES 1794
+#define ERROR_PRINTER_DRIVER_ALREADY_INSTALLED 1795
+#define ERROR_UNKNOWN_PORT 1796
+#define ERROR_UNKNOWN_PRINTER_DRIVER 1797
+#define ERROR_UNKNOWN_PRINTPROCESSOR 1798
+#define ERROR_INVALID_SEPARATOR_FILE 1799
+#define ERROR_INVALID_PRIORITY 1800
+#define ERROR_INVALID_PRINTER_NAME 1801
+#define ERROR_PRINTER_ALREADY_EXISTS 1802
+#define ERROR_INVALID_PRINTER_COMMAND 1803
+#define ERROR_INVALID_DATATYPE 1804
+#define ERROR_INVALID_ENVIRONMENT 1805
+#define RPC_S_NO_MORE_BINDINGS 1806
+#define ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 1807
+#define ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT 1808
+#define ERROR_NOLOGON_SERVER_TRUST_ACCOUNT 1809
+#define ERROR_DOMAIN_TRUST_INCONSISTENT 1810
+#define ERROR_SERVER_HAS_OPEN_HANDLES 1811
+#define ERROR_RESOURCE_DATA_NOT_FOUND 1812
+#define ERROR_RESOURCE_TYPE_NOT_FOUND 1813
+#define ERROR_RESOURCE_NAME_NOT_FOUND 1814
+#define ERROR_RESOURCE_LANG_NOT_FOUND 1815
+#define ERROR_NOT_ENOUGH_QUOTA 1816
+#define RPC_S_NO_INTERFACES 1817
+#define RPC_S_CALL_CANCELLED 1818
+#define RPC_S_BINDING_INCOMPLETE 1819
+#define RPC_S_COMM_FAILURE 1820
+#define RPC_S_UNSUPPORTED_AUTHN_LEVEL 1821
+#define RPC_S_NO_PRINC_NAME 1822
+#define RPC_S_NOT_RPC_ERROR 1823
+#define RPC_S_UUID_LOCAL_ONLY 1824
+#define RPC_S_SEC_PKG_ERROR 1825
+#define RPC_S_NOT_CANCELLED 1826
+#define RPC_X_INVALID_ES_ACTION 1827
+#define RPC_X_WRONG_ES_VERSION 1828
+#define RPC_X_WRONG_STUB_VERSION 1829
+#define RPC_X_INVALID_PIPE_OBJECT 1830
+#define RPC_X_WRONG_PIPE_ORDER 1831
+#define RPC_X_WRONG_PIPE_VERSION 1832
+#define RPC_S_GROUP_MEMBER_NOT_FOUND 1898
+#define EPT_S_CANT_CREATE 1899
+#define RPC_S_INVALID_OBJECT 1900
+#define ERROR_INVALID_TIME 1901
+#define ERROR_INVALID_FORM_NAME 1902
+#define ERROR_INVALID_FORM_SIZE 1903
+#define ERROR_ALREADY_WAITING 1904
+#define ERROR_PRINTER_DELETED 1905
+#define ERROR_INVALID_PRINTER_STATE 1906
+#define ERROR_PASSWORD_MUST_CHANGE 1907
+#define ERROR_DOMAIN_CONTROLLER_NOT_FOUND 1908
+#define ERROR_ACCOUNT_LOCKED_OUT 1909
+#define OR_INVALID_OXID 1910
+#define OR_INVALID_OID 1911
+#define OR_INVALID_SET 1912
+#define RPC_S_SEND_INCOMPLETE 1913
+#define RPC_S_INVALID_ASYNC_HANDLE 1914
+#define RPC_S_INVALID_ASYNC_CALL 1915
+#define RPC_X_PIPE_CLOSED 1916
+#define RPC_X_PIPE_DISCIPLINE_ERROR 1917
+#define RPC_X_PIPE_EMPTY 1918
+#define ERROR_NO_SITENAME 1919
+#define ERROR_CANT_ACCESS_FILE 1920
+#define ERROR_CANT_RESOLVE_FILENAME 1921
+#define RPC_S_ENTRY_TYPE_MISMATCH 1922
+#define RPC_S_NOT_ALL_OBJS_EXPORTED 1923
+#define RPC_S_INTERFACE_NOT_EXPORTED 1924
+#define RPC_S_PROFILE_NOT_ADDED 1925
+#define RPC_S_PRF_ELT_NOT_ADDED 1926
+#define RPC_S_PRF_ELT_NOT_REMOVED 1927
+#define RPC_S_GRP_ELT_NOT_ADDED 1928
+#define RPC_S_GRP_ELT_NOT_REMOVED 1929
+#define ERROR_INVALID_PIXEL_FORMAT 2000
+#define ERROR_BAD_DRIVER 2001
+#define ERROR_INVALID_WINDOW_STYLE 2002
+#define ERROR_METAFILE_NOT_SUPPORTED 2003
+#define ERROR_TRANSFORM_NOT_SUPPORTED 2004
+#define ERROR_CLIPPING_NOT_SUPPORTED 2005
+#define ERROR_INVALID_CMM 2010
+#define ERROR_INVALID_PROFILE 2011
+#define ERROR_TAG_NOT_FOUND 2012
+#define ERROR_TAG_NOT_PRESENT 2013
+#define ERROR_DUPLICATE_TAG 2014
+#define ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE 2015
+#define ERROR_PROFILE_NOT_FOUND 2016
+#define ERROR_INVALID_COLORSPACE 2017
+#define ERROR_ICM_NOT_ENABLED 2018
+#define ERROR_DELETING_ICM_XFORM 2019
+#define ERROR_INVALID_TRANSFORM 2020
+#define ERROR_COLORSPACE_MISMATCH 2021
+#define ERROR_INVALID_COLORINDEX 2022
+#define ERROR_CONNECTED_OTHER_PASSWORD 2108
+#define ERROR_BAD_USERNAME 2202
+#define ERROR_NOT_CONNECTED 2250
+#define ERROR_OPEN_FILES 2401
+#define ERROR_ACTIVE_CONNECTIONS 2402
+#define ERROR_DEVICE_IN_USE 2404
+#define ERROR_UNKNOWN_PRINT_MONITOR 3000
+#define ERROR_PRINTER_DRIVER_IN_USE 3001
+#define ERROR_SPOOL_FILE_NOT_FOUND 3002
+#define ERROR_SPL_NO_STARTDOC 3003
+#define ERROR_SPL_NO_ADDJOB 3004
+#define ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED 3005
+#define ERROR_PRINT_MONITOR_ALREADY_INSTALLED 3006
+#define ERROR_INVALID_PRINT_MONITOR 3007
+#define ERROR_PRINT_MONITOR_IN_USE 3008
+#define ERROR_PRINTER_HAS_JOBS_QUEUED 3009
+#define ERROR_SUCCESS_REBOOT_REQUIRED 3010
+#define ERROR_SUCCESS_RESTART_REQUIRED 3011
+#define ERROR_PRINTER_NOT_FOUND 3012
+#define ERROR_WINS_INTERNAL 4000
+#define ERROR_CAN_NOT_DEL_LOCAL_WINS 4001
+#define ERROR_STATIC_INIT 4002
+#define ERROR_INC_BACKUP 4003
+#define ERROR_FULL_BACKUP 4004
+#define ERROR_REC_NON_EXISTENT 4005
+#define ERROR_RPL_NOT_ALLOWED 4006
+#define ERROR_DHCP_ADDRESS_CONFLICT 4100
+#define ERROR_WMI_GUID_NOT_FOUND 4200
+#define ERROR_WMI_INSTANCE_NOT_FOUND 4201
+#define ERROR_WMI_ITEMID_NOT_FOUND 4202
+#define ERROR_WMI_TRY_AGAIN 4203
+#define ERROR_WMI_DP_NOT_FOUND 4204
+#define ERROR_WMI_UNRESOLVED_INSTANCE_REF 4205
+#define ERROR_WMI_ALREADY_ENABLED 4206
+#define ERROR_WMI_GUID_DISCONNECTED 4207
+#define ERROR_WMI_SERVER_UNAVAILABLE 4208
+#define ERROR_WMI_DP_FAILED 4209
+#define ERROR_WMI_INVALID_MOF 4210
+#define ERROR_WMI_INVALID_REGINFO 4211
+#define ERROR_WMI_ALREADY_DISABLED 4212
+#define ERROR_WMI_READ_ONLY 4213
+#define ERROR_WMI_SET_FAILURE 4214
+#define ERROR_INVALID_MEDIA 4300
+#define ERROR_INVALID_LIBRARY 4301
+#define ERROR_INVALID_MEDIA_POOL 4302
+#define ERROR_DRIVE_MEDIA_MISMATCH 4303
+#define ERROR_MEDIA_OFFLINE 4304
+#define ERROR_LIBRARY_OFFLINE 4305
+#define ERROR_EMPTY 4306
+#define ERROR_NOT_EMPTY 4307
+#define ERROR_MEDIA_UNAVAILABLE 4308
+#define ERROR_RESOURCE_DISABLED 4309
+#define ERROR_INVALID_CLEANER 4310
+#define ERROR_UNABLE_TO_CLEAN 4311
+#define ERROR_OBJECT_NOT_FOUND 4312
+#define ERROR_DATABASE_FAILURE 4313
+#define ERROR_DATABASE_FULL 4314
+#define ERROR_MEDIA_INCOMPATIBLE 4315
+#define ERROR_RESOURCE_NOT_PRESENT 4316
+#define ERROR_INVALID_OPERATION 4317
+#define ERROR_MEDIA_NOT_AVAILABLE 4318
+#define ERROR_DEVICE_NOT_AVAILABLE 4319
+#define ERROR_REQUEST_REFUSED 4320
+#define ERROR_INVALID_DRIVE_OBJECT 4321
+#define ERROR_LIBRARY_FULL 4322
+#define ERROR_MEDIUM_NOT_ACCESSIBLE 4323
+#define ERROR_UNABLE_TO_LOAD_MEDIUM 4324
+#define ERROR_UNABLE_TO_INVENTORY_DRIVE 4325
+#define ERROR_UNABLE_TO_INVENTORY_SLOT 4326
+#define ERROR_UNABLE_TO_INVENTORY_TRANSPORT 4327
+#define ERROR_TRANSPORT_FULL 4328
+#define ERROR_CONTROLLING_IEPORT 4329
+#define ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA 4330
+#define ERROR_CLEANER_SLOT_SET 4331
+#define ERROR_CLEANER_SLOT_NOT_SET 4332
+#define ERROR_CLEANER_CARTRIDGE_SPENT 4333
+#define ERROR_UNEXPECTED_OMID 4334
+#define ERROR_CANT_DELETE_LAST_ITEM 4335
+#define ERROR_MESSAGE_EXCEEDS_MAX_SIZE 4336
+#define ERROR_VOLUME_CONTAINS_SYS_FILES 4337
+#define ERROR_INDIGENOUS_TYPE 4338
+#define ERROR_NO_SUPPORTING_DRIVES 4339
+#define ERROR_FILE_OFFLINE 4350
+#define ERROR_REMOTE_STORAGE_NOT_ACTIVE 4351
+#define ERROR_REMOTE_STORAGE_MEDIA_ERROR 4352
+#define ERROR_NOT_A_REPARSE_POINT 4390
+#define ERROR_REPARSE_ATTRIBUTE_CONFLICT 4391
+#define ERROR_INVALID_REPARSE_DATA 4392
+#define ERROR_REPARSE_TAG_INVALID 4393
+#define ERROR_REPARSE_TAG_MISMATCH 4394
+#define ERROR_VOLUME_NOT_SIS_ENABLED 4500
+#define ERROR_DEPENDENT_RESOURCE_EXISTS 5001
+#define ERROR_DEPENDENCY_NOT_FOUND 5002
+#define ERROR_DEPENDENCY_ALREADY_EXISTS 5003
+#define ERROR_RESOURCE_NOT_ONLINE 5004
+#define ERROR_HOST_NODE_NOT_AVAILABLE 5005
+#define ERROR_RESOURCE_NOT_AVAILABLE 5006
+#define ERROR_RESOURCE_NOT_FOUND 5007
+#define ERROR_SHUTDOWN_CLUSTER 5008
+#define ERROR_CANT_EVICT_ACTIVE_NODE 5009
+#define ERROR_OBJECT_ALREADY_EXISTS 5010
+#define ERROR_OBJECT_IN_LIST 5011
+#define ERROR_GROUP_NOT_AVAILABLE 5012
+#define ERROR_GROUP_NOT_FOUND 5013
+#define ERROR_GROUP_NOT_ONLINE 5014
+#define ERROR_HOST_NODE_NOT_RESOURCE_OWNER 5015
+#define ERROR_HOST_NODE_NOT_GROUP_OWNER 5016
+#define ERROR_RESMON_CREATE_FAILED 5017
+#define ERROR_RESMON_ONLINE_FAILED 5018
+#define ERROR_RESOURCE_ONLINE 5019
+#define ERROR_QUORUM_RESOURCE 5020
+#define ERROR_NOT_QUORUM_CAPABLE 5021
+#define ERROR_CLUSTER_SHUTTING_DOWN 5022
+#define ERROR_INVALID_STATE 5023
+#define ERROR_RESOURCE_PROPERTIES_STORED 5024
+#define ERROR_NOT_QUORUM_CLASS 5025
+#define ERROR_CORE_RESOURCE 5026
+#define ERROR_QUORUM_RESOURCE_ONLINE_FAILED 5027
+#define ERROR_QUORUMLOG_OPEN_FAILED 5028
+#define ERROR_CLUSTERLOG_CORRUPT 5029
+#define ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE 5030
+#define ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE 5031
+#define ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND 5032
+#define ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE 5033
+#define ERROR_QUORUM_OWNER_ALIVE 5034
+#define ERROR_NETWORK_NOT_AVAILABLE 5035
+#define ERROR_NODE_NOT_AVAILABLE 5036
+#define ERROR_ALL_NODES_NOT_AVAILABLE 5037
+#define ERROR_RESOURCE_FAILED 5038
+#define ERROR_CLUSTER_INVALID_NODE 5039
+#define ERROR_CLUSTER_NODE_EXISTS 5040
+#define ERROR_CLUSTER_JOIN_IN_PROGRESS 5041
+#define ERROR_CLUSTER_NODE_NOT_FOUND 5042
+#define ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND 5043
+#define ERROR_CLUSTER_NETWORK_EXISTS 5044
+#define ERROR_CLUSTER_NETWORK_NOT_FOUND 5045
+#define ERROR_CLUSTER_NETINTERFACE_EXISTS 5046
+#define ERROR_CLUSTER_NETINTERFACE_NOT_FOUND 5047
+#define ERROR_CLUSTER_INVALID_REQUEST 5048
+#define ERROR_CLUSTER_INVALID_NETWORK_PROVIDER 5049
+#define ERROR_CLUSTER_NODE_DOWN 5050
+#define ERROR_CLUSTER_NODE_UNREACHABLE 5051
+#define ERROR_CLUSTER_NODE_NOT_MEMBER 5052
+#define ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS 5053
+#define ERROR_CLUSTER_INVALID_NETWORK 5054
+#define ERROR_CLUSTER_NODE_UP 5056
+#define ERROR_CLUSTER_IPADDR_IN_USE 5057
+#define ERROR_CLUSTER_NODE_NOT_PAUSED 5058
+#define ERROR_CLUSTER_NO_SECURITY_CONTEXT 5059
+#define ERROR_CLUSTER_NETWORK_NOT_INTERNAL 5060
+#define ERROR_CLUSTER_NODE_ALREADY_UP 5061
+#define ERROR_CLUSTER_NODE_ALREADY_DOWN 5062
+#define ERROR_CLUSTER_NETWORK_ALREADY_ONLINE 5063
+#define ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE 5064
+#define ERROR_CLUSTER_NODE_ALREADY_MEMBER 5065
+#define ERROR_CLUSTER_LAST_INTERNAL_NETWORK 5066
+#define ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS 5067
+#define ERROR_INVALID_OPERATION_ON_QUORUM 5068
+#define ERROR_DEPENDENCY_NOT_ALLOWED 5069
+#define ERROR_CLUSTER_NODE_PAUSED 5070
+#define ERROR_NODE_CANT_HOST_RESOURCE 5071
+#define ERROR_CLUSTER_NODE_NOT_READY 5072
+#define ERROR_CLUSTER_NODE_SHUTTING_DOWN 5073
+#define ERROR_CLUSTER_JOIN_ABORTED 5074
+#define ERROR_CLUSTER_INCOMPATIBLE_VERSIONS 5075
+#define ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED 5076
+#define ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED 5077
+#define ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND 5078
+#define ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED 5079
+#define ERROR_CLUSTER_RESNAME_NOT_FOUND 5080
+#define ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED 5081
+#define ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST 5082
+#define ERROR_CLUSTER_DATABASE_SEQMISMATCH 5083
+#define ERROR_RESMON_INVALID_STATE 5084
+#define ERROR_CLUSTER_GUM_NOT_LOCKER 5085
+#define ERROR_QUORUM_DISK_NOT_FOUND 5086
+#define ERROR_DATABASE_BACKUP_CORRUPT 5087
+#define ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT 5088
+#define ERROR_RESOURCE_PROPERTY_UNCHANGEABLE 5089
+#define ERROR_ENCRYPTION_FAILED 6000
+#define ERROR_DECRYPTION_FAILED 6001
+#define ERROR_FILE_ENCRYPTED 6002
+#define ERROR_NO_RECOVERY_POLICY 6003
+#define ERROR_NO_EFS 6004
+#define ERROR_WRONG_EFS 6005
+#define ERROR_NO_USER_KEYS 6006
+#define ERROR_FILE_NOT_ENCRYPTED 6007
+#define ERROR_NOT_EXPORT_FORMAT 6008
+#define ERROR_FILE_READ_ONLY 6009
+#define ERROR_DIR_EFS_DISALLOWED 6010
+#define ERROR_EFS_SERVER_NOT_TRUSTED 6011
+#define ERROR_NO_BROWSER_SERVERS_FOUND 6118
+#define SCHED_E_SERVICE_NOT_LOCALSYSTEM 6200
+#define ERROR_CTX_WINSTATION_NAME_INVALID 7001
+#define ERROR_CTX_INVALID_PD 7002
+#define ERROR_CTX_PD_NOT_FOUND 7003
+#define ERROR_CTX_WD_NOT_FOUND 7004
+#define ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY 7005
+#define ERROR_CTX_SERVICE_NAME_COLLISION 7006
+#define ERROR_CTX_CLOSE_PENDING 7007
+#define ERROR_CTX_NO_OUTBUF 7008
+#define ERROR_CTX_MODEM_INF_NOT_FOUND 7009
+#define ERROR_CTX_INVALID_MODEMNAME 7010
+#define ERROR_CTX_MODEM_RESPONSE_ERROR 7011
+#define ERROR_CTX_MODEM_RESPONSE_TIMEOUT 7012
+#define ERROR_CTX_MODEM_RESPONSE_NO_CARRIER 7013
+#define ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE 7014
+#define ERROR_CTX_MODEM_RESPONSE_BUSY 7015
+#define ERROR_CTX_MODEM_RESPONSE_VOICE 7016
+#define ERROR_CTX_TD_ERROR 7017
+#define ERROR_CTX_WINSTATION_NOT_FOUND 7022
+#define ERROR_CTX_WINSTATION_ALREADY_EXISTS 7023
+#define ERROR_CTX_WINSTATION_BUSY 7024
+#define ERROR_CTX_BAD_VIDEO_MODE 7025
+#define ERROR_CTX_GRAPHICS_INVALID 7035
+#define ERROR_CTX_LOGON_DISABLED 7037
+#define ERROR_CTX_NOT_CONSOLE 7038
+#define ERROR_CTX_CLIENT_QUERY_TIMEOUT 7040
+#define ERROR_CTX_CONSOLE_DISCONNECT 7041
+#define ERROR_CTX_CONSOLE_CONNECT 7042
+#define ERROR_CTX_SHADOW_DENIED 7044
+#define ERROR_CTX_WINSTATION_ACCESS_DENIED 7045
+#define ERROR_CTX_INVALID_WD 7049
+#define ERROR_CTX_SHADOW_INVALID 7050
+#define ERROR_CTX_SHADOW_DISABLED 7051
+#define ERROR_CTX_CLIENT_LICENSE_IN_USE 7052
+#define ERROR_CTX_CLIENT_LICENSE_NOT_SET 7053
+#define ERROR_CTX_LICENSE_NOT_AVAILABLE 7054
+#define ERROR_CTX_LICENSE_CLIENT_INVALID 7055
+#define ERROR_CTX_LICENSE_EXPIRED 7056
+#define FRS_ERR_INVALID_API_SEQUENCE 8001
+#define FRS_ERR_STARTING_SERVICE 8002
+#define FRS_ERR_STOPPING_SERVICE 8003
+#define FRS_ERR_INTERNAL_API 8004
+#define FRS_ERR_INTERNAL 8005
+#define FRS_ERR_SERVICE_COMM 8006
+#define FRS_ERR_INSUFFICIENT_PRIV 8007
+#define FRS_ERR_AUTHENTICATION 8008
+#define FRS_ERR_PARENT_INSUFFICIENT_PRIV 8009
+#define FRS_ERR_PARENT_AUTHENTICATION 8010
+#define FRS_ERR_CHILD_TO_PARENT_COMM 8011
+#define FRS_ERR_PARENT_TO_CHILD_COMM 8012
+#define FRS_ERR_SYSVOL_POPULATE 8013
+#define FRS_ERR_SYSVOL_POPULATE_TIMEOUT 8014
+#define FRS_ERR_SYSVOL_IS_BUSY 8015
+#define FRS_ERR_SYSVOL_DEMOTE 8016
+#define FRS_ERR_INVALID_SERVICE_PARAMETER 8017
+#define ERROR_DS_NOT_INSTALLED 8200
+#define ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY 8201
+#define ERROR_DS_NO_ATTRIBUTE_OR_VALUE 8202
+#define ERROR_DS_INVALID_ATTRIBUTE_SYNTAX 8203
+#define ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED 8204
+#define ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS 8205
+#define ERROR_DS_BUSY 8206
+#define ERROR_DS_UNAVAILABLE 8207
+#define ERROR_DS_NO_RIDS_ALLOCATED 8208
+#define ERROR_DS_NO_MORE_RIDS 8209
+#define ERROR_DS_INCORRECT_ROLE_OWNER 8210
+#define ERROR_DS_RIDMGR_INIT_ERROR 8211
+#define ERROR_DS_OBJ_CLASS_VIOLATION 8212
+#define ERROR_DS_CANT_ON_NON_LEAF 8213
+#define ERROR_DS_CANT_ON_RDN 8214
+#define ERROR_DS_CANT_MOD_OBJ_CLASS 8215
+#define ERROR_DS_CROSS_DOM_MOVE_ERROR 8216
+#define ERROR_DS_GC_NOT_AVAILABLE 8217
+#define ERROR_SHARED_POLICY 8218
+#define ERROR_POLICY_OBJECT_NOT_FOUND 8219
+#define ERROR_POLICY_ONLY_IN_DS 8220
+#define ERROR_PROMOTION_ACTIVE 8221
+#define ERROR_NO_PROMOTION_ACTIVE 8222
+#define ERROR_DS_OPERATIONS_ERROR 8224
+#define ERROR_DS_PROTOCOL_ERROR 8225
+#define ERROR_DS_TIMELIMIT_EXCEEDED 8226
+#define ERROR_DS_SIZELIMIT_EXCEEDED 8227
+#define ERROR_DS_ADMIN_LIMIT_EXCEEDED 8228
+#define ERROR_DS_COMPARE_FALSE 8229
+#define ERROR_DS_COMPARE_TRUE 8230
+#define ERROR_DS_AUTH_METHOD_NOT_SUPPORTED 8231
+#define ERROR_DS_STRONG_AUTH_REQUIRED 8232
+#define ERROR_DS_INAPPROPRIATE_AUTH 8233
+#define ERROR_DS_AUTH_UNKNOWN 8234
+#define ERROR_DS_REFERRAL 8235
+#define ERROR_DS_UNAVAILABLE_CRIT_EXTENSION 8236
+#define ERROR_DS_CONFIDENTIALITY_REQUIRED 8237
+#define ERROR_DS_INAPPROPRIATE_MATCHING 8238
+#define ERROR_DS_CONSTRAINT_VIOLATION 8239
+#define ERROR_DS_NO_SUCH_OBJECT 8240
+#define ERROR_DS_ALIAS_PROBLEM 8241
+#define ERROR_DS_INVALID_DN_SYNTAX 8242
+#define ERROR_DS_IS_LEAF 8243
+#define ERROR_DS_ALIAS_DEREF_PROBLEM 8244
+#define ERROR_DS_UNWILLING_TO_PERFORM 8245
+#define ERROR_DS_LOOP_DETECT 8246
+#define ERROR_DS_NAMING_VIOLATION 8247
+#define ERROR_DS_OBJECT_RESULTS_TOO_LARGE 8248
+#define ERROR_DS_AFFECTS_MULTIPLE_DSAS 8249
+#define ERROR_DS_SERVER_DOWN 8250
+#define ERROR_DS_LOCAL_ERROR 8251
+#define ERROR_DS_ENCODING_ERROR 8252
+#define ERROR_DS_DECODING_ERROR 8253
+#define ERROR_DS_FILTER_UNKNOWN 8254
+#define ERROR_DS_PARAM_ERROR 8255
+#define ERROR_DS_NOT_SUPPORTED 8256
+#define ERROR_DS_NO_RESULTS_RETURNED 8257
+#define ERROR_DS_CONTROL_NOT_FOUND 8258
+#define ERROR_DS_CLIENT_LOOP 8259
+#define ERROR_DS_REFERRAL_LIMIT_EXCEEDED 8260
+#define ERROR_DS_ROOT_MUST_BE_NC 8301
+#define ERROR_DS_ADD_REPLICA_INHIBITED 8302
+#define ERROR_DS_ATT_NOT_DEF_IN_SCHEMA 8303
+#define ERROR_DS_MAX_OBJ_SIZE_EXCEEDED 8304
+#define ERROR_DS_OBJ_STRING_NAME_EXISTS 8305
+#define ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA 8306
+#define ERROR_DS_RDN_DOESNT_MATCH_SCHEMA 8307
+#define ERROR_DS_NO_REQUESTED_ATTS_FOUND 8308
+#define ERROR_DS_USER_BUFFER_TO_SMALL 8309
+#define ERROR_DS_ATT_IS_NOT_ON_OBJ 8310
+#define ERROR_DS_ILLEGAL_MOD_OPERATION 8311
+#define ERROR_DS_OBJ_TOO_LARGE 8312
+#define ERROR_DS_BAD_INSTANCE_TYPE 8313
+#define ERROR_DS_MASTERDSA_REQUIRED 8314
+#define ERROR_DS_OBJECT_CLASS_REQUIRED 8315
+#define ERROR_DS_MISSING_REQUIRED_ATT 8316
+#define ERROR_DS_ATT_NOT_DEF_FOR_CLASS 8317
+#define ERROR_DS_ATT_ALREADY_EXISTS 8318
+#define ERROR_DS_CANT_ADD_ATT_VALUES 8320
+#define ERROR_DS_SINGLE_VALUE_CONSTRAINT 8321
+#define ERROR_DS_RANGE_CONSTRAINT 8322
+#define ERROR_DS_ATT_VAL_ALREADY_EXISTS 8323
+#define ERROR_DS_CANT_REM_MISSING_ATT 8324
+#define ERROR_DS_CANT_REM_MISSING_ATT_VAL 8325
+#define ERROR_DS_ROOT_CANT_BE_SUBREF 8326
+#define ERROR_DS_NO_CHAINING 8327
+#define ERROR_DS_NO_CHAINED_EVAL 8328
+#define ERROR_DS_NO_PARENT_OBJECT 8329
+#define ERROR_DS_PARENT_IS_AN_ALIAS 8330
+#define ERROR_DS_CANT_MIX_MASTER_AND_REPS 8331
+#define ERROR_DS_CHILDREN_EXIST 8332
+#define ERROR_DS_OBJ_NOT_FOUND 8333
+#define ERROR_DS_ALIASED_OBJ_MISSING 8334
+#define ERROR_DS_BAD_NAME_SYNTAX 8335
+#define ERROR_DS_ALIAS_POINTS_TO_ALIAS 8336
+#define ERROR_DS_CANT_DEREF_ALIAS 8337
+#define ERROR_DS_OUT_OF_SCOPE 8338
+#define ERROR_DS_CANT_DELETE_DSA_OBJ 8340
+#define ERROR_DS_GENERIC_ERROR 8341
+#define ERROR_DS_DSA_MUST_BE_INT_MASTER 8342
+#define ERROR_DS_CLASS_NOT_DSA 8343
+#define ERROR_DS_INSUFF_ACCESS_RIGHTS 8344
+#define ERROR_DS_ILLEGAL_SUPERIOR 8345
+#define ERROR_DS_ATTRIBUTE_OWNED_BY_SAM 8346
+#define ERROR_DS_NAME_TOO_MANY_PARTS 8347
+#define ERROR_DS_NAME_TOO_LONG 8348
+#define ERROR_DS_NAME_VALUE_TOO_LONG 8349
+#define ERROR_DS_NAME_UNPARSEABLE 8350
+#define ERROR_DS_NAME_TYPE_UNKNOWN 8351
+#define ERROR_DS_NOT_AN_OBJECT 8352
+#define ERROR_DS_SEC_DESC_TOO_SHORT 8353
+#define ERROR_DS_SEC_DESC_INVALID 8354
+#define ERROR_DS_NO_DELETED_NAME 8355
+#define ERROR_DS_SUBREF_MUST_HAVE_PARENT 8356
+#define ERROR_DS_NCNAME_MUST_BE_NC 8357
+#define ERROR_DS_CANT_ADD_SYSTEM_ONLY 8358
+#define ERROR_DS_CLASS_MUST_BE_CONCRETE 8359
+#define ERROR_DS_INVALID_DMD 8360
+#define ERROR_DS_OBJ_GUID_EXISTS 8361
+#define ERROR_DS_NOT_ON_BACKLINK 8362
+#define ERROR_DS_NO_CROSSREF_FOR_NC 8363
+#define ERROR_DS_SHUTTING_DOWN 8364
+#define ERROR_DS_UNKNOWN_OPERATION 8365
+#define ERROR_DS_INVALID_ROLE_OWNER 8366
+#define ERROR_DS_COULDNT_CONTACT_FSMO 8367
+#define ERROR_DS_CROSS_NC_DN_RENAME 8368
+#define ERROR_DS_CANT_MOD_SYSTEM_ONLY 8369
+#define ERROR_DS_REPLICATOR_ONLY 8370
+#define ERROR_DS_OBJ_CLASS_NOT_DEFINED 8371
+#define ERROR_DS_OBJ_CLASS_NOT_SUBCLASS 8372
+#define ERROR_DS_NAME_REFERENCE_INVALID 8373
+#define ERROR_DS_CROSS_REF_EXISTS 8374
+#define ERROR_DS_CANT_DEL_MASTER_CROSSREF 8375
+#define ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD 8376
+#define ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX 8377
+#define ERROR_DS_DUP_RDN 8378
+#define ERROR_DS_DUP_OID 8379
+#define ERROR_DS_DUP_MAPI_ID 8380
+#define ERROR_DS_DUP_SCHEMA_ID_GUID 8381
+#define ERROR_DS_DUP_LDAP_DISPLAY_NAME 8382
+#define ERROR_DS_SEMANTIC_ATT_TEST 8383
+#define ERROR_DS_SYNTAX_MISMATCH 8384
+#define ERROR_DS_EXISTS_IN_MUST_HAVE 8385
+#define ERROR_DS_EXISTS_IN_MAY_HAVE 8386
+#define ERROR_DS_NONEXISTENT_MAY_HAVE 8387
+#define ERROR_DS_NONEXISTENT_MUST_HAVE 8388
+#define ERROR_DS_AUX_CLS_TEST_FAIL 8389
+#define ERROR_DS_NONEXISTENT_POSS_SUP 8390
+#define ERROR_DS_SUB_CLS_TEST_FAIL 8391
+#define ERROR_DS_BAD_RDN_ATT_ID_SYNTAX 8392
+#define ERROR_DS_EXISTS_IN_AUX_CLS 8393
+#define ERROR_DS_EXISTS_IN_SUB_CLS 8394
+#define ERROR_DS_EXISTS_IN_POSS_SUP 8395
+#define ERROR_DS_RECALCSCHEMA_FAILED 8396
+#define ERROR_DS_TREE_DELETE_NOT_FINISHED 8397
+#define ERROR_DS_CANT_DELETE 8398
+#define ERROR_DS_ATT_SCHEMA_REQ_ID 8399
+#define ERROR_DS_BAD_ATT_SCHEMA_SYNTAX 8400
+#define ERROR_DS_CANT_CACHE_ATT 8401
+#define ERROR_DS_CANT_CACHE_CLASS 8402
+#define ERROR_DS_CANT_REMOVE_ATT_CACHE 8403
+#define ERROR_DS_CANT_REMOVE_CLASS_CACHE 8404
+#define ERROR_DS_CANT_RETRIEVE_DN 8405
+#define ERROR_DS_MISSING_SUPREF 8406
+#define ERROR_DS_CANT_RETRIEVE_INSTANCE 8407
+#define ERROR_DS_CODE_INCONSISTENCY 8408
+#define ERROR_DS_DATABASE_ERROR 8409
+#define ERROR_DS_GOVERNSID_MISSING 8410
+#define ERROR_DS_MISSING_EXPECTED_ATT 8411
+#define ERROR_DS_NCNAME_MISSING_CR_REF 8412
+#define ERROR_DS_SECURITY_CHECKING_ERROR 8413
+#define ERROR_DS_SCHEMA_NOT_LOADED 8414
+#define ERROR_DS_SCHEMA_ALLOC_FAILED 8415
+#define ERROR_DS_ATT_SCHEMA_REQ_SYNTAX 8416
+#define ERROR_DS_GCVERIFY_ERROR 8417
+#define ERROR_DS_DRA_SCHEMA_MISMATCH 8418
+#define ERROR_DS_CANT_FIND_DSA_OBJ 8419
+#define ERROR_DS_CANT_FIND_EXPECTED_NC 8420
+#define ERROR_DS_CANT_FIND_NC_IN_CACHE 8421
+#define ERROR_DS_CANT_RETRIEVE_CHILD 8422
+#define ERROR_DS_SECURITY_ILLEGAL_MODIFY 8423
+#define ERROR_DS_CANT_REPLACE_HIDDEN_REC 8424
+#define ERROR_DS_BAD_HIERARCHY_FILE 8425
+#define ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED 8426
+#define ERROR_DS_CONFIG_PARAM_MISSING 8427
+#define ERROR_DS_COUNTING_AB_INDICES_FAILED 8428
+#define ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED 8429
+#define ERROR_DS_INTERNAL_FAILURE 8430
+#define ERROR_DS_UNKNOWN_ERROR 8431
+#define ERROR_DS_ROOT_REQUIRES_CLASS_TOP 8432
+#define ERROR_DS_REFUSING_FSMO_ROLES 8433
+#define ERROR_DS_MISSING_FSMO_SETTINGS 8434
+#define ERROR_DS_UNABLE_TO_SURRENDER_ROLES 8435
+#define ERROR_DS_DRA_GENERIC 8436
+#define ERROR_DS_DRA_INVALID_PARAMETER 8437
+#define ERROR_DS_DRA_BUSY 8438
+#define ERROR_DS_DRA_BAD_DN 8439
+#define ERROR_DS_DRA_BAD_NC 8440
+#define ERROR_DS_DRA_DN_EXISTS 8441
+#define ERROR_DS_DRA_INTERNAL_ERROR 8442
+#define ERROR_DS_DRA_INCONSISTENT_DIT 8443
+#define ERROR_DS_DRA_CONNECTION_FAILED 8444
+#define ERROR_DS_DRA_BAD_INSTANCE_TYPE 8445
+#define ERROR_DS_DRA_OUT_OF_MEM 8446
+#define ERROR_DS_DRA_MAIL_PROBLEM 8447
+#define ERROR_DS_DRA_REF_ALREADY_EXISTS 8448
+#define ERROR_DS_DRA_REF_NOT_FOUND 8449
+#define ERROR_DS_DRA_OBJ_IS_REP_SOURCE 8450
+#define ERROR_DS_DRA_DB_ERROR 8451
+#define ERROR_DS_DRA_NO_REPLICA 8452
+#define ERROR_DS_DRA_ACCESS_DENIED 8453
+#define ERROR_DS_DRA_NOT_SUPPORTED 8454
+#define ERROR_DS_DRA_RPC_CANCELLED 8455
+#define ERROR_DS_DRA_SOURCE_DISABLED 8456
+#define ERROR_DS_DRA_SINK_DISABLED 8457
+#define ERROR_DS_DRA_NAME_COLLISION 8458
+#define ERROR_DS_DRA_SOURCE_REINSTALLED 8459
+#define ERROR_DS_DRA_MISSING_PARENT 8460
+#define ERROR_DS_DRA_PREEMPTED 8461
+#define ERROR_DS_DRA_ABANDON_SYNC 8462
+#define ERROR_DS_DRA_SHUTDOWN 8463
+#define ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET 8464
+#define ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA 8465
+#define ERROR_DS_DRA_EXTN_CONNECTION_FAILED 8466
+#define ERROR_DS_INSTALL_SCHEMA_MISMATCH 8467
+#define ERROR_DS_DUP_LINK_ID 8468
+#define ERROR_DS_NAME_ERROR_RESOLVING 8469
+#define ERROR_DS_NAME_ERROR_NOT_FOUND 8470
+#define ERROR_DS_NAME_ERROR_NOT_UNIQUE 8471
+#define ERROR_DS_NAME_ERROR_NO_MAPPING 8472
+#define ERROR_DS_NAME_ERROR_DOMAIN_ONLY 8473
+#define ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING 8474
+#define ERROR_DS_CONSTRUCTED_ATT_MOD 8475
+#define ERROR_DS_WRONG_OM_OBJ_CLASS 8476
+#define ERROR_DS_DRA_REPL_PENDING 8477
+#define ERROR_DS_DS_REQUIRED 8478
+#define ERROR_DS_INVALID_LDAP_DISPLAY_NAME 8479
+#define ERROR_DS_NON_BASE_SEARCH 8480
+#define ERROR_DS_CANT_RETRIEVE_ATTS 8481
+#define ERROR_DS_BACKLINK_WITHOUT_LINK 8482
+#define ERROR_DS_EPOCH_MISMATCH 8483
+#define ERROR_DS_SRC_NAME_MISMATCH 8484
+#define ERROR_DS_SRC_AND_DST_NC_IDENTICAL 8485
+#define ERROR_DS_DST_NC_MISMATCH 8486
+#define ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC 8487
+#define ERROR_DS_SRC_GUID_MISMATCH 8488
+#define ERROR_DS_CANT_MOVE_DELETED_OBJECT 8489
+#define ERROR_DS_PDC_OPERATION_IN_PROGRESS 8490
+#define ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD 8491
+#define ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION 8492
+#define ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS 8493
+#define ERROR_DS_NC_MUST_HAVE_NC_PARENT 8494
+#define ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE 8495
+#define ERROR_DS_DST_DOMAIN_NOT_NATIVE 8496
+#define ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER 8497
+#define ERROR_DS_CANT_MOVE_ACCOUNT_GROUP 8498
+#define ERROR_DS_CANT_MOVE_RESOURCE_GROUP 8499
+#define ERROR_DS_INVALID_SEARCH_FLAG 8500
+#define ERROR_DS_NO_TREE_DELETE_ABOVE_NC 8501
+#define ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE 8502
+#define ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE 8503
+#define ERROR_DS_SAM_INIT_FAILURE 8504
+#define ERROR_DS_SENSITIVE_GROUP_VIOLATION 8505
+#define ERROR_DS_CANT_MOD_PRIMARYGROUPID 8506
+#define ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD 8507
+#define ERROR_DS_NONSAFE_SCHEMA_CHANGE 8508
+#define ERROR_DS_SCHEMA_UPDATE_DISALLOWED 8509
+#define ERROR_DS_CANT_CREATE_UNDER_SCHEMA 8510
+#define ERROR_DS_INSTALL_NO_SRC_SCH_VERSION 8511
+#define ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE 8512
+#define ERROR_DS_INVALID_GROUP_TYPE 8513
+#define ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN 8514
+#define ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN 8515
+#define ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER 8516
+#define ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER 8517
+#define ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER 8518
+#define ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER 8519
+#define ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER 8520
+#define ERROR_DS_HAVE_PRIMARY_MEMBERS 8521
+#define ERROR_DS_STRING_SD_CONVERSION_FAILED 8522
+#define ERROR_DS_NAMING_MASTER_GC 8523
+#define ERROR_DS_LOOKUP_FAILURE 8524
+#define ERROR_DS_COULDNT_UPDATE_SPNS 8525
+#define ERROR_DS_CANT_RETRIEVE_SD 8526
+#define ERROR_DS_KEY_NOT_UNIQUE 8527
+#define ERROR_DS_WRONG_LINKED_ATT_SYNTAX 8528
+#define ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD 8529
+#define ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY 8530
+#define ERROR_DS_CANT_START 8531
+#define ERROR_DS_INIT_FAILURE 8532
+#define ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION 8533
+#define ERROR_DS_SOURCE_DOMAIN_IN_FOREST 8534
+#define ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST 8535
+#define ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED 8536
+#define ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN 8537
+#define ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER 8538
+#define ERROR_DS_SRC_SID_EXISTS_IN_FOREST 8539
+#define ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH 8540
+#define ERROR_SAM_INIT_FAILURE 8541
+#define ERROR_DS_DRA_SCHEMA_INFO_SHIP 8542
+#define ERROR_DS_DRA_SCHEMA_CONFLICT 8543
+#define ERROR_DS_DRA_EARLIER_SCHEMA_CONLICT 8544
+#define ERROR_DS_DRA_OBJ_NC_MISMATCH 8545
+#define ERROR_DS_NC_STILL_HAS_DSAS 8546
+#define ERROR_DS_GC_REQUIRED 8547
+#define ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY 8548
+#define ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS 8549
+#define ERROR_DS_CANT_ADD_TO_GC 8550
+#define ERROR_DS_NO_CHECKPOINT_WITH_PDC 8551
+#define ERROR_DS_SOURCE_AUDITING_NOT_ENABLED 8552
+#define ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC 8553
+#define ERROR_DS_INVALID_NAME_FOR_SPN 8554
+#define ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS 8555
+#define ERROR_DS_UNICODEPWD_NOT_IN_QUOTES 8556
+#define ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED 8557
+#define ERROR_DS_MUST_BE_RUN_ON_DST_DC 8558
+#define ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER 8559
+#define ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ 8560
+#define DNS_ERROR_RCODE_FORMAT_ERROR 9001
+#define DNS_ERROR_RCODE_SERVER_FAILURE 9002
+#define DNS_ERROR_RCODE_NAME_ERROR 9003
+#define DNS_ERROR_RCODE_NOT_IMPLEMENTED 9004
+#define DNS_ERROR_RCODE_REFUSED 9005
+#define DNS_ERROR_RCODE_YXDOMAIN 9006
+#define DNS_ERROR_RCODE_YXRRSET 9007
+#define DNS_ERROR_RCODE_NXRRSET 9008
+#define DNS_ERROR_RCODE_NOTAUTH 9009
+#define DNS_ERROR_RCODE_NOTZONE 9010
+#define DNS_ERROR_RCODE_BADSIG 9016
+#define DNS_ERROR_RCODE_BADKEY 9017
+#define DNS_ERROR_RCODE_BADTIME 9018
+#define DNS_INFO_NO_RECORDS 9501
+#define DNS_ERROR_BAD_PACKET 9502
+#define DNS_ERROR_NO_PACKET 9503
+#define DNS_ERROR_RCODE 9504
+#define DNS_ERROR_UNSECURE_PACKET 9505
+#define DNS_ERROR_INVALID_TYPE 9551
+#define DNS_ERROR_INVALID_IP_ADDRESS 9552
+#define DNS_ERROR_INVALID_PROPERTY 9553
+#define DNS_ERROR_TRY_AGAIN_LATER 9554
+#define DNS_ERROR_NOT_UNIQUE 9555
+#define DNS_ERROR_NON_RFC_NAME 9556
+#define DNS_STATUS_FQDN 9557
+#define DNS_STATUS_DOTTED_NAME 9558
+#define DNS_STATUS_SINGLE_PART_NAME 9559
+#define DNS_ERROR_INVALID_NAME_CHAR 9560
+#define DNS_ERROR_NUMERIC_NAME 9561
+#define DNS_ERROR_ZONE_DOES_NOT_EXIST 9601
+#define DNS_ERROR_NO_ZONE_INFO 9602
+#define DNS_ERROR_INVALID_ZONE_OPERATION 9603
+#define DNS_ERROR_ZONE_CONFIGURATION_ERROR 9604
+#define DNS_ERROR_ZONE_HAS_NO_SOA_RECORD 9605
+#define DNS_ERROR_ZONE_HAS_NO_NS_RECORDS 9606
+#define DNS_ERROR_ZONE_LOCKED 9607
+#define DNS_ERROR_ZONE_CREATION_FAILED 9608
+#define DNS_ERROR_ZONE_ALREADY_EXISTS 9609
+#define DNS_ERROR_AUTOZONE_ALREADY_EXISTS 9610
+#define DNS_ERROR_INVALID_ZONE_TYPE 9611
+#define DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP 9612
+#define DNS_ERROR_ZONE_NOT_SECONDARY 9613
+#define DNS_ERROR_NEED_SECONDARY_ADDRESSES 9614
+#define DNS_ERROR_WINS_INIT_FAILED 9615
+#define DNS_ERROR_NEED_WINS_SERVERS 9616
+#define DNS_ERROR_NBSTAT_INIT_FAILED 9617
+#define DNS_ERROR_SOA_DELETE_INVALID 9618
+#define DNS_ERROR_PRIMARY_REQUIRES_DATAFILE 9651
+#define DNS_ERROR_INVALID_DATAFILE_NAME 9652
+#define DNS_ERROR_DATAFILE_OPEN_FAILURE 9653
+#define DNS_ERROR_FILE_WRITEBACK_FAILED 9654
+#define DNS_ERROR_DATAFILE_PARSING 9655
+#define DNS_ERROR_RECORD_DOES_NOT_EXIST 9701
+#define DNS_ERROR_RECORD_FORMAT 9702
+#define DNS_ERROR_NODE_CREATION_FAILED 9703
+#define DNS_ERROR_UNKNOWN_RECORD_TYPE 9704
+#define DNS_ERROR_RECORD_TIMED_OUT 9705
+#define DNS_ERROR_NAME_NOT_IN_ZONE 9706
+#define DNS_ERROR_CNAME_LOOP 9707
+#define DNS_ERROR_NODE_IS_CNAME 9708
+#define DNS_ERROR_CNAME_COLLISION 9709
+#define DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT 9710
+#define DNS_ERROR_RECORD_ALREADY_EXISTS 9711
+#define DNS_ERROR_SECONDARY_DATA 9712
+#define DNS_ERROR_NO_CREATE_CACHE_DATA 9713
+#define DNS_ERROR_NAME_DOES_NOT_EXIST 9714
+#define DNS_WARNING_PTR_CREATE_FAILED 9715
+#define DNS_WARNING_DOMAIN_UNDELETED 9716
+#define DNS_ERROR_DS_UNAVAILABLE 9717
+#define DNS_ERROR_DS_ZONE_ALREADY_EXISTS 9718
+#define DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE 9719
+#define DNS_INFO_AXFR_COMPLETE 9751
+#define DNS_ERROR_AXFR 9752
+#define DNS_INFO_ADDED_LOCAL_WINS 9753
+#define DNS_STATUS_CONTINUE_NEEDED 9801
+#define DNS_ERROR_NO_TCPIP 9851
+#define DNS_ERROR_NO_DNS_SERVERS 9852
+
+/* HRESULT values for OLE, SHELL and other Interface stuff */
+/* the codes 4000-40ff are reserved for OLE */
+#define NOERROR 0L
+#define S_OK ((HRESULT)0L)
+#define S_FALSE ((HRESULT)1L)
+
+#define DISP_E_UNKNOWNINTERFACE 0x80020001L
+#define DISP_E_MEMBERNOTFOUND 0x80020003L
+#define DISP_E_PARAMNOTFOUND 0x80020004L
+#define DISP_E_TYPEMISMATCH 0x80020005L
+#define DISP_E_UNKNOWNNAME 0x80020006L
+#define DISP_E_NONAMEDARGS 0x80020007L
+#define DISP_E_BADVARTYPE 0x80020008L
+#define DISP_E_EXCEPTION 0x80020009L
+#define DISP_E_OVERFLOW 0x8002000AL
+#define DISP_E_BADINDEX 0x8002000BL
+#define DISP_E_UNKNOWNLCID 0x8002000CL
+#define DISP_E_ARRAYISLOCKED 0x8002000DL
+#define DISP_E_BADPARAMCOUNT 0x8002000EL
+#define DISP_E_PARAMNOTOPTIONAL 0x8002000FL
+
+#define TYPE_E_ELEMENTNOTFOUND 0x8002802BL
+#define TYPE_E_CANTLOADLIBRARY 0x80029C4AL
+
+/* OLE Clipboard */
+#define CLIPBRD_E_FIRST 0x800401D0L
+#define CLIPBRD_E_LAST 0x800401DFL
+#define CLIPBRD_S_FIRST 0x000401D0L
+#define CLIPBRD_S_LAST 0x000401DFL
+#define CLIPBRD_E_CANT_OPEN 0x800401D0L
+#define CLIPBRD_E_CANT_EMPTY 0x800401D1L
+#define CLIPBRD_E_CANT_SET 0x800401D2L
+#define CLIPBRD_E_BAD_DATA 0x800401D3L
+#define CLIPBRD_E_CANT_CLOSE 0x800401D4L
+
+/* Drag and Drop */
+#define DRAGDROP_S_DROP 0x00040100L
+#define DRAGDROP_S_CANCEL 0x00040101L
+#define DRAGDROP_E_NOTREGISTERED 0x80040100L
+#define DRAGDROP_E_ALREADYREGISTERED 0x80040101L
+#define DRAGDROP_S_USEDEFAULTCURSORS 0x00040102L
+
+#define E_UNEXPECTED 0x8000FFFF
+
+#define E_NOTIMPL 0x80004001
+#define E_NOINTERFACE 0x80004002
+#define E_POINTER 0x80004003
+#define E_ABORT 0x80004004
+#define E_FAIL 0x80004005
+#define E_UNSPEC E_FAIL /* must to be defined (used by FileMoniker, IOleLink and DoDragDrop as a return value) */
+
+/*#define CO_E_INIT_TLS 0x80004006
+#define CO_E_INIT_SHARED_ALLOCATOR 0x80004007
+#define CO_E_INIT_MEMORY_ALLOCATOR 0x80004008
+#define CO_E_INIT_CLASS_CACHE 0x80004009
+#define CO_E_INIT_RPC_CHANNEL 0x8000400A
+#define CO_E_INIT_TLS_SET_CHANNEL_CONTROL 0x8000400B
+#define CO_E_INIT_TLS_CHANNEL_CONTROL 0x8000400C
+#define CO_E_INIT_UNACCEPTED_USER_ALLOCATOR 0x8000400D
+#define CO_E_INIT_SCM_MUTEX_EXISTS 0x8000400E
+#define CO_E_INIT_SCM_FILE_MAPPING_EXISTS 0x8000400F
+#define CO_E_INIT_SCM_MAP_VIEW_OF_FILE 0x80004010
+#define CO_E_INIT_SCM_EXEC_FAILURE 0x80004011
+#define CO_E_INIT_ONLY_SINGLE_THREADED 0x80004012 */
+
+#define CO_S_NOTALLINTERFACES 0x00080012
+#define CO_E_NOTINITIALIZED 0x800401F0
+#define CO_E_ERRORINDLL 0x800401F9
+#define CO_E_OBJISREG 0x800401FB
+
+#define OLE_E_FIRST 0x80040000L
+#define OLE_E_LAST 0x800400FFL
+#define OLE_S_FIRST 0x00040000L
+#define OLE_S_LAST 0x000400FFL
+
+#define OLE_E_ENUM_NOMORE 0x80040002
+#define OLE_E_ADVISENOTSUPPORTED 0x80040003
+#define OLE_E_NOCONNECTION 0x80040004
+#define OLE_E_NOTRUNNING 0x80040005
+#define OLE_E_NOCACHE 0x80040006
+#define OLE_E_BLANK 0x80040007
+#define OLE_E_NOT_INPLACEACTIVE 0x80040010
+#define OLE_E_STATIC 0x8004000B
+#define OLE_E_PROMPTSAVECANCELLED 0x8004000C
+#define OLE_S_USEREG 0x00040000
+#define OLE_S_STATIC 0x00040001
+
+#define DV_E_FORMATETC 0x80040064
+#define DV_E_DVASPECT 0x8004006B
+#define DV_E_LINDEX 0x80040068
+#define DV_E_TYMED 0x80040069
+
+#define CLASS_E_NOAGGREGATION 0x80040110
+#define CLASS_E_CLASSNOTAVAILABLE 0x80040111
+
+#define DATA_S_SAMEFORMATETC 0x80040130
+
+#define E_ACCESSDENIED 0x80070005
+#define E_HANDLE 0x80070006
+#define E_OUTOFMEMORY 0x8007000E
+#define E_INVALIDARG 0x80070057
+
+/*#define OLE_E_FIRST 0x80040000L */
+/*#define OLE_E_LAST 0x800400FFL */
+/*#define OLE_S_FIRST 0x00040000L */
+/*#define OLE_S_LAST 0x000400FFL */
+
+#define MK_S_REDUCED_TO_SELF 0x000401E2
+#define MK_S_ME 0x000401E4
+#define MK_S_HIM 0x000401E5
+#define MK_S_US 0x000401E6
+#define MK_S_MONIKERALREADYREGISTERED 0x000401E7
+
+#define MK_E_EXCEEDEDDEADLINE 0x800401E1
+#define MK_E_NEEDGENERIC 0x800401E2
+#define MK_E_UNAVAILABLE 0x800401E3
+#define MK_E_SYNTAX 0x800401E4
+#define MK_E_NOOBJECT 0x800401E5
+#define MK_E_INVALIDEXTENSION 0x800401E6
+#define MK_E_INTERMEDIATEINTERFACENOTSUPPORTED 0x800401E7
+#define MK_E_NOTBINDABLE 0x800401E8
+#define MK_E_NOTBOUND 0x800401E9
+#define MK_E_CANTOPENFILE 0x800401EA
+#define MK_E_MIUSTBOTHERUSER 0x800401EB
+#define MK_E_NOINVERSE 0x800401EC
+#define MK_E_NOSTORAGE 0x800401ED
+#define MK_E_NOPREFIX 0x800401EE
+
+#define STG_E_INVALIDFUNCTION 0x80030001
+#define STG_E_FILENOTFOUND 0x80030002
+#define STG_E_PATHNOTFOUND 0x80030003
+#define STG_E_TOOMANYOPENFILES 0x80030004
+#define STG_E_ACCESSDENIED 0x80030005
+#define STG_E_INVALIDHANDLE 0x80030006
+#define STG_E_INSUFFICIENTMEMORY 0x80030008
+#define STG_E_INVALIDPOINTER 0x80030009
+#define STG_E_NOMOREFILES 0x80030012
+#define STG_E_DISKISWRITEPROTECTED 0x80030013
+#define STG_E_SEEKERROR 0x80030019
+#define STG_E_WRITEFAULT 0x8003001D
+#define STG_E_READFAULT 0x8003001E
+#define STG_E_SHAREVIOLATION 0x80030020
+#define STG_E_LOCKVIOLATION 0x80030021
+#define STG_E_FILEALREADYEXISTS 0x80030050
+#define STG_E_INVALIDPARAMETER 0x80030057
+#define STG_E_MEDIUMFULL 0x80030070
+#define STG_E_ABNORMALAPIEXIT 0x800300FA
+#define STG_E_INVALIDHEADER 0x800300FB
+#define STG_E_INVALIDNAME 0x800300FC
+#define STG_E_UNKNOWN 0x800300FD
+#define STG_E_UNIMPLEMENTEDFUNCTION 0x800300FE
+#define STG_E_INVALIDFLAG 0x800300FF
+#define STG_E_INUSE 0x80030100
+#define STG_E_NOTCURRENT 0x80030101
+#define STG_E_REVERTED 0x80030102
+#define STG_E_CANTSAVE 0x80030103
+#define STG_E_OLDFORMAT 0x80030104
+#define STG_E_OLDDLL 0x80030105
+#define STG_E_SHAREREQUIRED 0x80030106
+#define STG_E_NOTFILEBASEDSTORAGE 0x80030107
+#define STG_E_EXTANTMARSHALLINGS 0x80030108
+
+#define CONVERT10_E_OLESTREAM_GET 0x800401C0
+#define CONVERT10_E_OLESTREAM_PUT 0x800401C1
+#define CONVERT10_E_OLESTREAM_FMT 0x800401C2
+#define CONVERT10_E_OLESTREAM_BITMAP_TO_DIB 0x800401C3
+#define CONVERT10_E_STG_FMT 0x800401C4
+#define CONVERT10_E_STG_NO_STD_STREAM 0x800401C5
+#define CONVERT10_E_STG_DIB_TO_BITMAP 0x800401C6
+
+/* alten versionen
+#define E_NOTIMPL 0x80000001
+#define E_OUTOFMEMORY 0x80000002
+#define E_INVALIDARG 0x80000003
+#define E_NOINTERFACE 0x80000004
+#define E_POINTER 0x80000005
+#define E_HANDLE 0x80000006
+#define E_ABORT 0x80000007
+#define E_FAIL 0x80000008
+#define E_ACCESSDENIED 0x80000009 */
+
+/* Obtained from lcc-win32 include files */
+#define GDI_ERROR 0xffffffff
+
+
+/* registry errors */
+#define REGDB_E_READREGDB 0x80040150
+#define REGDB_E_CLASSNOTREG 0x80040154
+
+#define INPLACE_E_NOTUNDOABLE 0x800401A0
+#define INPLACE_E_NOTOOLSPACE 0x800401A1
+
+#define DATA_E_FORMATETC DV_E_FORMATETC
+
+#define CLASSFACTORY_E_FIRST 0x80040110L
+#define CLASSFACTORY_E_LAST 0x8004011FL
+#define CLASSFACTORY_S_FIRST 0x80040110L
+#define CLASSFACTORY_S_LAST 0x8004011FL
+
+#define CLASS_E_NOTLICENSED (CLASSFACTORY_E_FIRST+2)
+#define CLASS_E_NOAGGREGATION 0x80040110
+#define CLASS_E_CLASSNOTAVAILABLE 0x80040111
+
+
+#define OLEOBJ_E_NOVERBS 0x00040180L
+#define OLEOBJ_E_INVALIDVERB 0x00040181L
+#define OLEOBJ_S_INVALIDVERB 0x00040180L
+
+#endif /* __WINE_WINERROR_H */
diff --git a/src/libw32dll/wine/winestring.h b/src/libw32dll/wine/winestring.h
new file mode 100644
index 000000000..5b66dc803
--- /dev/null
+++ b/src/libw32dll/wine/winestring.h
@@ -0,0 +1,13 @@
+#ifndef __WINE_WINE_WINESTRING_H
+#define __WINE_WINE_WINESTRING_H
+
+#include "windef.h"
+
+LPWSTR WINAPI lstrcpyAtoW(LPWSTR,LPCSTR);
+LPSTR WINAPI lstrcpyWtoA(LPSTR,LPCWSTR);
+LPWSTR WINAPI lstrcpynAtoW(LPWSTR,LPCSTR,INT);
+LPSTR WINAPI lstrcpynWtoA(LPSTR,LPCWSTR,INT);
+
+#define lstrncmpiA strncasecmp
+
+#endif /* __WINE_WINE_WINESTRING_H */
diff --git a/src/libw32dll/wine/winnt.h b/src/libw32dll/wine/winnt.h
new file mode 100644
index 000000000..107172ef8
--- /dev/null
+++ b/src/libw32dll/wine/winnt.h
@@ -0,0 +1,2665 @@
+/*
+ * Win32 definitions for Windows NT
+ *
+ * Copyright 1996 Alexandre Julliard
+ */
+
+#ifndef __WINE_WINNT_H
+#define __WINE_WINNT_H
+
+#include "windef.h"
+
+#ifndef RC_INVOKED
+#include <string.h>
+#endif
+
+#include "pshpack1.h"
+/* Defines */
+
+/* Argument 1 passed to the DllEntryProc. */
+#define DLL_PROCESS_DETACH 0 /* detach process (unload library) */
+#define DLL_PROCESS_ATTACH 1 /* attach process (load library) */
+#define DLL_THREAD_ATTACH 2 /* attach new thread */
+#define DLL_THREAD_DETACH 3 /* detach thread */
+
+
+/* u.x.wProcessorArchitecture (NT) */
+#define PROCESSOR_ARCHITECTURE_INTEL 0
+#define PROCESSOR_ARCHITECTURE_MIPS 1
+#define PROCESSOR_ARCHITECTURE_ALPHA 2
+#define PROCESSOR_ARCHITECTURE_PPC 3
+#define PROCESSOR_ARCHITECTURE_SHX 4
+#define PROCESSOR_ARCHITECTURE_ARM 5
+#define PROCESSOR_ARCHITECTURE_UNKNOWN 0xFFFF
+
+/* dwProcessorType */
+#define PROCESSOR_INTEL_386 386
+#define PROCESSOR_INTEL_486 486
+#define PROCESSOR_INTEL_PENTIUM 586
+#define PROCESSOR_INTEL_860 860
+#define PROCESSOR_MIPS_R2000 2000
+#define PROCESSOR_MIPS_R3000 3000
+#define PROCESSOR_MIPS_R4000 4000
+#define PROCESSOR_ALPHA_21064 21064
+#define PROCESSOR_PPC_601 601
+#define PROCESSOR_PPC_603 603
+#define PROCESSOR_PPC_604 604
+#define PROCESSOR_PPC_620 620
+#define PROCESSOR_HITACHI_SH3 10003
+#define PROCESSOR_HITACHI_SH3E 10004
+#define PROCESSOR_HITACHI_SH4 10005
+#define PROCESSOR_MOTOROLA_821 821
+#define PROCESSOR_SHx_SH3 103
+#define PROCESSOR_SHx_SH4 104
+#define PROCESSOR_STRONGARM 2577
+#define PROCESSOR_ARM720 1824 /* 0x720 */
+#define PROCESSOR_ARM820 2080 /* 0x820 */
+#define PROCESSOR_ARM920 2336 /* 0x920 */
+#define PROCESSOR_ARM_7TDMI 70001
+
+#define ANYSIZE_ARRAY 1
+
+#define MINCHAR 0x80
+#define MAXCHAR 0x7f
+#define MINSHORT 0x8000
+#define MAXSHORT 0x7fff
+#define MINLONG 0x80000000
+#define MAXLONG 0x7fffffff
+#define MAXBYTE 0xff
+#define MAXWORD 0xffff
+#define MAXDWORD 0xffffffff
+
+#define FIELD_OFFSET(type, field) \
+ ((LONG)(INT)&(((type *)0)->field))
+
+#define CONTAINING_RECORD(address, type, field) \
+ ((type *)((PCHAR)(address) - (PCHAR)(&((type *)0)->field)))
+
+/* Types */
+
+/* TCHAR data types definitions for Winelib. */
+/* These types are _not_ defined for the emulator, because they */
+/* depend on the UNICODE macro that only exists in user's code. */
+
+#ifndef __WINE__
+# ifdef UNICODE
+typedef WCHAR TCHAR, *PTCHAR;
+typedef LPWSTR PTSTR, LPTSTR;
+typedef LPCWSTR PCTSTR, LPCTSTR;
+#define __TEXT(string) L##string /*probably wrong */
+# else /* UNICODE */
+typedef char TCHAR, *PTCHAR;
+typedef LPSTR PTSTR, LPTSTR;
+typedef LPCSTR PCTSTR, LPCTSTR;
+#define __TEXT(string) string
+# endif /* UNICODE */
+#endif /* __WINE__ */
+#define TEXT(quote) __TEXT(quote)
+
+typedef BYTE BOOLEAN;
+typedef BOOLEAN *PBOOLEAN;
+
+typedef struct _LIST_ENTRY {
+ struct _LIST_ENTRY *Flink;
+ struct _LIST_ENTRY *Blink;
+} LIST_ENTRY, *PLIST_ENTRY;
+
+typedef struct _SINGLE_LIST_ENTRY {
+ struct _SINGLE_LIST_ENTRY *Next;
+} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
+
+/* Heap flags */
+
+#define HEAP_NO_SERIALIZE 0x00000001
+#define HEAP_GROWABLE 0x00000002
+#define HEAP_GENERATE_EXCEPTIONS 0x00000004
+#define HEAP_ZERO_MEMORY 0x00000008
+#define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010
+#define HEAP_TAIL_CHECKING_ENABLED 0x00000020
+#define HEAP_FREE_CHECKING_ENABLED 0x00000040
+#define HEAP_DISABLE_COALESCE_ON_FREE 0x00000080
+#define HEAP_CREATE_ALIGN_16 0x00010000
+#define HEAP_CREATE_ENABLE_TRACING 0x00020000
+#define HEAP_WINE_SEGPTR 0x01000000 /* Not a Win32 flag */
+#define HEAP_WINE_CODESEG 0x02000000 /* Not a Win32 flag */
+#define HEAP_WINE_CODE16SEG 0x04000000 /* Not a Win32 flag */
+#define HEAP_WINE_SHARED 0x08000000 /* Not a Win32 flag */
+
+/* Processor feature flags. */
+#define PF_FLOATING_POINT_PRECISION_ERRATA 0
+#define PF_FLOATING_POINT_EMULATED 1
+#define PF_COMPARE_EXCHANGE_DOUBLE 2
+#define PF_MMX_INSTRUCTIONS_AVAILABLE 3
+#define PF_PPC_MOVEMEM_64BIT_OK 4
+#define PF_ALPHA_BYTE_INSTRUCTIONS 5
+
+
+/* The Win32 register context */
+
+/* CONTEXT is the CPU-dependent context; it should be used */
+/* wherever a platform-specific context is needed (e.g. exception */
+/* handling, Win32 register functions). */
+
+/* CONTEXT86 is the i386-specific context; it should be used */
+/* wherever only a 386 context makes sense (e.g. DOS interrupts, */
+/* Win16 register functions), so that this code can be compiled */
+/* on all platforms. */
+
+#define SIZE_OF_80387_REGISTERS 80
+
+typedef struct _FLOATING_SAVE_AREA
+{
+ DWORD ControlWord;
+ DWORD StatusWord;
+ DWORD TagWord;
+ DWORD ErrorOffset;
+ DWORD ErrorSelector;
+ DWORD DataOffset;
+ DWORD DataSelector;
+ BYTE RegisterArea[SIZE_OF_80387_REGISTERS];
+ DWORD Cr0NpxState;
+} FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA;
+
+typedef struct _CONTEXT86
+{
+ DWORD ContextFlags;
+
+ /* These are selected by CONTEXT_DEBUG_REGISTERS */
+ DWORD Dr0;
+ DWORD Dr1;
+ DWORD Dr2;
+ DWORD Dr3;
+ DWORD Dr6;
+ DWORD Dr7;
+
+ /* These are selected by CONTEXT_FLOATING_POINT */
+ FLOATING_SAVE_AREA FloatSave;
+
+ /* These are selected by CONTEXT_SEGMENTS */
+ DWORD SegGs;
+ DWORD SegFs;
+ DWORD SegEs;
+ DWORD SegDs;
+
+ /* These are selected by CONTEXT_INTEGER */
+ DWORD Edi;
+ DWORD Esi;
+ DWORD Ebx;
+ DWORD Edx;
+ DWORD Ecx;
+ DWORD Eax;
+
+ /* These are selected by CONTEXT_CONTROL */
+ DWORD Ebp;
+ DWORD Eip;
+ DWORD SegCs;
+ DWORD EFlags;
+ DWORD Esp;
+ DWORD SegSs;
+} CONTEXT86;
+
+#define CONTEXT_X86 0x00010000
+#define CONTEXT_i386 CONTEXT_X86
+#define CONTEXT_i486 CONTEXT_X86
+
+#define CONTEXT86_CONTROL (CONTEXT_i386 | 0x0001) /* SS:SP, CS:IP, FLAGS, BP */
+#define CONTEXT86_INTEGER (CONTEXT_i386 | 0x0002) /* AX, BX, CX, DX, SI, DI */
+#define CONTEXT86_SEGMENTS (CONTEXT_i386 | 0x0004) /* DS, ES, FS, GS */
+#define CONTEXT86_FLOATING_POINT (CONTEXT_i386 | 0x0008L) /* 387 state */
+#define CONTEXT86_DEBUG_REGISTERS (CONTEXT_i386 | 0x0010L) /* DB 0-3,6,7 */
+#define CONTEXT86_FULL (CONTEXT86_CONTROL | CONTEXT86_INTEGER | CONTEXT86_SEGMENTS)
+
+/* i386 context definitions */
+#ifdef __i386__
+
+#define CONTEXT_CONTROL CONTEXT86_CONTROL
+#define CONTEXT_INTEGER CONTEXT86_INTEGER
+#define CONTEXT_SEGMENTS CONTEXT86_SEGMENTS
+#define CONTEXT_FLOATING_POINT CONTEXT86_FLOATING_POINT
+#define CONTEXT_DEBUG_REGISTERS CONTEXT86_DEBUG_REGISTERS
+#define CONTEXT_FULL CONTEXT86_FULL
+
+typedef CONTEXT86 CONTEXT;
+
+#endif /* __i386__ */
+
+/* Alpha context definitions */
+#ifdef _ALPHA_
+
+#define CONTEXT_ALPHA 0x00020000
+
+#define CONTEXT_CONTROL (CONTEXT_ALPHA | 0x00000001L)
+#define CONTEXT_FLOATING_POINT (CONTEXT_ALPHA | 0x00000002L)
+#define CONTEXT_INTEGER (CONTEXT_ALPHA | 0x00000004L)
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER)
+
+typedef struct _CONTEXT
+{
+ /* selected by CONTEXT_FLOATING_POINT */
+ ULONGLONG FltF0;
+ ULONGLONG FltF1;
+ ULONGLONG FltF2;
+ ULONGLONG FltF3;
+ ULONGLONG FltF4;
+ ULONGLONG FltF5;
+ ULONGLONG FltF6;
+ ULONGLONG FltF7;
+ ULONGLONG FltF8;
+ ULONGLONG FltF9;
+ ULONGLONG FltF10;
+ ULONGLONG FltF11;
+ ULONGLONG FltF12;
+ ULONGLONG FltF13;
+ ULONGLONG FltF14;
+ ULONGLONG FltF15;
+ ULONGLONG FltF16;
+ ULONGLONG FltF17;
+ ULONGLONG FltF18;
+ ULONGLONG FltF19;
+ ULONGLONG FltF20;
+ ULONGLONG FltF21;
+ ULONGLONG FltF22;
+ ULONGLONG FltF23;
+ ULONGLONG FltF24;
+ ULONGLONG FltF25;
+ ULONGLONG FltF26;
+ ULONGLONG FltF27;
+ ULONGLONG FltF28;
+ ULONGLONG FltF29;
+ ULONGLONG FltF30;
+ ULONGLONG FltF31;
+
+ /* selected by CONTEXT_INTEGER */
+ ULONGLONG IntV0;
+ ULONGLONG IntT0;
+ ULONGLONG IntT1;
+ ULONGLONG IntT2;
+ ULONGLONG IntT3;
+ ULONGLONG IntT4;
+ ULONGLONG IntT5;
+ ULONGLONG IntT6;
+ ULONGLONG IntT7;
+ ULONGLONG IntS0;
+ ULONGLONG IntS1;
+ ULONGLONG IntS2;
+ ULONGLONG IntS3;
+ ULONGLONG IntS4;
+ ULONGLONG IntS5;
+ ULONGLONG IntFp;
+ ULONGLONG IntA0;
+ ULONGLONG IntA1;
+ ULONGLONG IntA2;
+ ULONGLONG IntA3;
+ ULONGLONG IntA4;
+ ULONGLONG IntA5;
+ ULONGLONG IntT8;
+ ULONGLONG IntT9;
+ ULONGLONG IntT10;
+ ULONGLONG IntT11;
+ ULONGLONG IntRa;
+ ULONGLONG IntT12;
+ ULONGLONG IntAt;
+ ULONGLONG IntGp;
+ ULONGLONG IntSp;
+ ULONGLONG IntZero;
+
+ /* selected by CONTEXT_FLOATING_POINT */
+ ULONGLONG Fpcr;
+ ULONGLONG SoftFpcr;
+
+ /* selected by CONTEXT_CONTROL */
+ ULONGLONG Fir;
+ DWORD Psr;
+ DWORD ContextFlags;
+ DWORD Fill[4];
+} CONTEXT;
+
+#define _QUAD_PSR_OFFSET HighSoftFpcr
+#define _QUAD_FLAGS_OFFSET HighFir
+
+#endif /* _ALPHA_ */
+
+/* Mips context definitions */
+#ifdef _MIPS_
+
+#define CONTEXT_R4000 0x00010000
+
+#define CONTEXT_CONTROL (CONTEXT_R4000 | 0x00000001)
+#define CONTEXT_FLOATING_POINT (CONTEXT_R4000 | 0x00000002)
+#define CONTEXT_INTEGER (CONTEXT_R4000 | 0x00000004)
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER)
+
+typedef struct _CONTEXT
+{
+ DWORD Argument[4];
+ /* These are selected by CONTEXT_FLOATING_POINT */
+ DWORD FltF0;
+ DWORD FltF1;
+ DWORD FltF2;
+ DWORD FltF3;
+ DWORD FltF4;
+ DWORD FltF5;
+ DWORD FltF6;
+ DWORD FltF7;
+ DWORD FltF8;
+ DWORD FltF9;
+ DWORD FltF10;
+ DWORD FltF11;
+ DWORD FltF12;
+ DWORD FltF13;
+ DWORD FltF14;
+ DWORD FltF15;
+ DWORD FltF16;
+ DWORD FltF17;
+ DWORD FltF18;
+ DWORD FltF19;
+ DWORD FltF20;
+ DWORD FltF21;
+ DWORD FltF22;
+ DWORD FltF23;
+ DWORD FltF24;
+ DWORD FltF25;
+ DWORD FltF26;
+ DWORD FltF27;
+ DWORD FltF28;
+ DWORD FltF29;
+ DWORD FltF30;
+ DWORD FltF31;
+
+ /* These are selected by CONTEXT_INTEGER */
+ DWORD IntZero;
+ DWORD IntAt;
+ DWORD IntV0;
+ DWORD IntV1;
+ DWORD IntA0;
+ DWORD IntA1;
+ DWORD IntA2;
+ DWORD IntA3;
+ DWORD IntT0;
+ DWORD IntT1;
+ DWORD IntT2;
+ DWORD IntT3;
+ DWORD IntT4;
+ DWORD IntT5;
+ DWORD IntT6;
+ DWORD IntT7;
+ DWORD IntS0;
+ DWORD IntS1;
+ DWORD IntS2;
+ DWORD IntS3;
+ DWORD IntS4;
+ DWORD IntS5;
+ DWORD IntS6;
+ DWORD IntS7;
+ DWORD IntT8;
+ DWORD IntT9;
+ DWORD IntK0;
+ DWORD IntK1;
+ DWORD IntGp;
+ DWORD IntSp;
+ DWORD IntS8;
+ DWORD IntRa;
+ DWORD IntLo;
+ DWORD IntHi;
+
+ /* These are selected by CONTEXT_FLOATING_POINT */
+ DWORD Fsr;
+
+ /* These are selected by CONTEXT_CONTROL */
+ DWORD Fir;
+ DWORD Psr;
+
+ DWORD ContextFlags;
+ DWORD Fill[2];
+} CONTEXT;
+
+#endif /* _MIPS_ */
+
+/* PowerPC context definitions */
+#ifdef __PPC__
+
+#define CONTEXT_CONTROL 0x0001
+#define CONTEXT_FLOATING_POINT 0x0002
+#define CONTEXT_INTEGER 0x0004
+#define CONTEXT_DEBUG_REGISTERS 0x0008
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER)
+
+typedef struct
+{
+ /* These are selected by CONTEXT_FLOATING_POINT */
+ double Fpr0;
+ double Fpr1;
+ double Fpr2;
+ double Fpr3;
+ double Fpr4;
+ double Fpr5;
+ double Fpr6;
+ double Fpr7;
+ double Fpr8;
+ double Fpr9;
+ double Fpr10;
+ double Fpr11;
+ double Fpr12;
+ double Fpr13;
+ double Fpr14;
+ double Fpr15;
+ double Fpr16;
+ double Fpr17;
+ double Fpr18;
+ double Fpr19;
+ double Fpr20;
+ double Fpr21;
+ double Fpr22;
+ double Fpr23;
+ double Fpr24;
+ double Fpr25;
+ double Fpr26;
+ double Fpr27;
+ double Fpr28;
+ double Fpr29;
+ double Fpr30;
+ double Fpr31;
+ double Fpscr;
+
+ /* These are selected by CONTEXT_INTEGER */
+ DWORD Gpr0;
+ DWORD Gpr1;
+ DWORD Gpr2;
+ DWORD Gpr3;
+ DWORD Gpr4;
+ DWORD Gpr5;
+ DWORD Gpr6;
+ DWORD Gpr7;
+ DWORD Gpr8;
+ DWORD Gpr9;
+ DWORD Gpr10;
+ DWORD Gpr11;
+ DWORD Gpr12;
+ DWORD Gpr13;
+ DWORD Gpr14;
+ DWORD Gpr15;
+ DWORD Gpr16;
+ DWORD Gpr17;
+ DWORD Gpr18;
+ DWORD Gpr19;
+ DWORD Gpr20;
+ DWORD Gpr21;
+ DWORD Gpr22;
+ DWORD Gpr23;
+ DWORD Gpr24;
+ DWORD Gpr25;
+ DWORD Gpr26;
+ DWORD Gpr27;
+ DWORD Gpr28;
+ DWORD Gpr29;
+ DWORD Gpr30;
+ DWORD Gpr31;
+
+ DWORD Cr;
+ DWORD Xer;
+
+ /* These are selected by CONTEXT_CONTROL */
+ DWORD Msr;
+ DWORD Iar;
+ DWORD Lr;
+ DWORD Ctr;
+
+ DWORD ContextFlags;
+ DWORD Fill[3];
+
+ /* These are selected by CONTEXT_DEBUG_REGISTERS */
+ DWORD Dr0;
+ DWORD Dr1;
+ DWORD Dr2;
+ DWORD Dr3;
+ DWORD Dr4;
+ DWORD Dr5;
+ DWORD Dr6;
+ DWORD Dr7;
+} CONTEXT;
+
+typedef struct _STACK_FRAME_HEADER
+{
+ DWORD BackChain;
+ DWORD GlueSaved1;
+ DWORD GlueSaved2;
+ DWORD Reserved1;
+ DWORD Spare1;
+ DWORD Spare2;
+
+ DWORD Parameter0;
+ DWORD Parameter1;
+ DWORD Parameter2;
+ DWORD Parameter3;
+ DWORD Parameter4;
+ DWORD Parameter5;
+ DWORD Parameter6;
+ DWORD Parameter7;
+} STACK_FRAME_HEADER,*PSTACK_FRAME_HEADER;
+
+#endif /* __PPC__ */
+
+#ifdef __sparc__
+
+/*
+ * FIXME:
+ *
+ * There is no official CONTEXT structure defined for the SPARC
+ * architecture, so I just made one up.
+ *
+ * This structure is valid only for 32-bit SPARC architectures,
+ * not for 64-bit SPARC.
+ *
+ * Note that this structure contains only the 'top-level' registers;
+ * the rest of the register window chain is not visible.
+ *
+ * The layout follows the Solaris 'prgregset_t' structure.
+ *
+ */
+
+#define CONTEXT_SPARC 0x10000000
+
+#define CONTEXT_CONTROL (CONTEXT_SPARC | 0x00000001)
+#define CONTEXT_FLOATING_POINT (CONTEXT_SPARC | 0x00000002)
+#define CONTEXT_INTEGER (CONTEXT_SPARC | 0x00000004)
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER)
+
+typedef struct _CONTEXT
+{
+ DWORD ContextFlags;
+
+ /* These are selected by CONTEXT_INTEGER */
+ DWORD g0;
+ DWORD g1;
+ DWORD g2;
+ DWORD g3;
+ DWORD g4;
+ DWORD g5;
+ DWORD g6;
+ DWORD g7;
+ DWORD o0;
+ DWORD o1;
+ DWORD o2;
+ DWORD o3;
+ DWORD o4;
+ DWORD o5;
+ DWORD o6;
+ DWORD o7;
+ DWORD l0;
+ DWORD l1;
+ DWORD l2;
+ DWORD l3;
+ DWORD l4;
+ DWORD l5;
+ DWORD l6;
+ DWORD l7;
+ DWORD i0;
+ DWORD i1;
+ DWORD i2;
+ DWORD i3;
+ DWORD i4;
+ DWORD i5;
+ DWORD i6;
+ DWORD i7;
+
+ /* These are selected by CONTEXT_CONTROL */
+ DWORD psr;
+ DWORD pc;
+ DWORD npc;
+ DWORD y;
+ DWORD wim;
+ DWORD tbr;
+
+ /* FIXME: floating point registers missing */
+
+} CONTEXT;
+
+#endif /* __sparc__ */
+
+#if !defined(CONTEXT_FULL) && !defined(RC_INVOKED)
+#error You need to define a CONTEXT for your CPU
+#endif
+
+typedef CONTEXT *PCONTEXT;
+typedef HANDLE *PHANDLE;
+
+#ifdef __WINE__
+
+/* Macros for easier access to i386 context registers */
+
+#define EAX_reg(context) ((context)->Eax)
+#define EBX_reg(context) ((context)->Ebx)
+#define ECX_reg(context) ((context)->Ecx)
+#define EDX_reg(context) ((context)->Edx)
+#define ESI_reg(context) ((context)->Esi)
+#define EDI_reg(context) ((context)->Edi)
+#define EBP_reg(context) ((context)->Ebp)
+
+#define CS_reg(context) ((context)->SegCs)
+#define DS_reg(context) ((context)->SegDs)
+#define ES_reg(context) ((context)->SegEs)
+#define FS_reg(context) ((context)->SegFs)
+#define GS_reg(context) ((context)->SegGs)
+#define SS_reg(context) ((context)->SegSs)
+
+#define EFL_reg(context) ((context)->EFlags)
+#define EIP_reg(context) ((context)->Eip)
+#define ESP_reg(context) ((context)->Esp)
+
+#define AX_reg(context) (*(WORD*)&EAX_reg(context))
+#define BX_reg(context) (*(WORD*)&EBX_reg(context))
+#define CX_reg(context) (*(WORD*)&ECX_reg(context))
+#define DX_reg(context) (*(WORD*)&EDX_reg(context))
+#define SI_reg(context) (*(WORD*)&ESI_reg(context))
+#define DI_reg(context) (*(WORD*)&EDI_reg(context))
+#define BP_reg(context) (*(WORD*)&EBP_reg(context))
+
+#define AL_reg(context) (*(BYTE*)&EAX_reg(context))
+#define AH_reg(context) (*((BYTE*)&EAX_reg(context)+1))
+#define BL_reg(context) (*(BYTE*)&EBX_reg(context))
+#define BH_reg(context) (*((BYTE*)&EBX_reg(context)+1))
+#define CL_reg(context) (*(BYTE*)&ECX_reg(context))
+#define CH_reg(context) (*((BYTE*)&ECX_reg(context)+1))
+#define DL_reg(context) (*(BYTE*)&EDX_reg(context))
+#define DH_reg(context) (*((BYTE*)&EDX_reg(context)+1))
+
+#define SET_CFLAG(context) (EFL_reg(context) |= 0x0001)
+#define RESET_CFLAG(context) (EFL_reg(context) &= ~0x0001)
+#define SET_ZFLAG(context) (EFL_reg(context) |= 0x0040)
+#define RESET_ZFLAG(context) (EFL_reg(context) &= ~0x0040)
+
+#define ISV86(context) (EFL_reg(context) & 0x00020000)
+#define V86BASE(context) ((context)->Dr7) /* ugly */
+
+
+/* Macros to retrieve the current context */
+
+#ifdef __i386__
+
+#ifdef NEED_UNDERSCORE_PREFIX
+# define __ASM_NAME(name) "_" name
+#else
+# define __ASM_NAME(name) name
+#endif
+
+#ifdef __GNUC__
+# define __ASM_GLOBAL_FUNC(name,code) \
+ __asm__( ".align 4\n\t" \
+ ".globl " __ASM_NAME(#name) "\n\t" \
+ ".type " __ASM_NAME(#name) ",@function\n" \
+ __ASM_NAME(#name) ":\n\t" \
+ code );
+#else /* __GNUC__ */
+# define __ASM_GLOBAL_FUNC(name,code) \
+ void __asm_dummy_##name(void) { \
+ asm( ".align 4\n\t" \
+ ".globl " __ASM_NAME(#name) "\n\t" \
+ ".type " __ASM_NAME(#name) ",@function\n" \
+ __ASM_NAME(#name) ":\n\t" \
+ code ); \
+ }
+#endif /* __GNUC__ */
+
+#define _DEFINE_REGS_ENTRYPOINT( name, fn, args ) \
+ __ASM_GLOBAL_FUNC( name, \
+ "call " __ASM_NAME("CALL32_Regs") "\n\t" \
+ ".long " __ASM_NAME(#fn) "\n\t" \
+ ".byte " #args ", " #args )
+#define DEFINE_REGS_ENTRYPOINT_0( name, fn ) \
+ _DEFINE_REGS_ENTRYPOINT( name, fn, 0 )
+#define DEFINE_REGS_ENTRYPOINT_1( name, fn, t1 ) \
+ _DEFINE_REGS_ENTRYPOINT( name, fn, 4 )
+#define DEFINE_REGS_ENTRYPOINT_2( name, fn, t1, t2 ) \
+ _DEFINE_REGS_ENTRYPOINT( name, fn, 8 )
+#define DEFINE_REGS_ENTRYPOINT_3( name, fn, t1, t2, t3 ) \
+ _DEFINE_REGS_ENTRYPOINT( name, fn, 12 )
+#define DEFINE_REGS_ENTRYPOINT_4( name, fn, t1, t2, t3, t4 ) \
+ _DEFINE_REGS_ENTRYPOINT( name, fn, 16 )
+
+#endif /* __i386__ */
+
+#ifdef __sparc__
+/* FIXME: use getcontext() to retrieve full context */
+#define _GET_CONTEXT \
+ CONTEXT context; \
+ do { memset(&context, 0, sizeof(CONTEXT)); \
+ context.ContextFlags = CONTEXT_CONTROL; \
+ context.pc = (DWORD)__builtin_return_address(0); \
+ } while (0)
+
+#define DEFINE_REGS_ENTRYPOINT_0( name, fn ) \
+ void WINAPI name ( void ) \
+ { _GET_CONTEXT; fn( &context ); }
+#define DEFINE_REGS_ENTRYPOINT_1( name, fn, t1 ) \
+ void WINAPI name ( t1 a1 ) \
+ { _GET_CONTEXT; fn( a1, &context ); }
+#define DEFINE_REGS_ENTRYPOINT_2( name, fn, t1, t2 ) \
+ void WINAPI name ( t1 a1, t2 a2 ) \
+ { _GET_CONTEXT; fn( a1, a2, &context ); }
+#define DEFINE_REGS_ENTRYPOINT_3( name, fn, t1, t2, t3 ) \
+ void WINAPI name ( t1 a1, t2 a2, t3 a3 ) \
+ { _GET_CONTEXT; fn( a1, a2, a3, &context ); }
+#define DEFINE_REGS_ENTRYPOINT_4( name, fn, t1, t2, t3, t4 ) \
+ void WINAPI name ( t1 a1, t2 a2, t3 a3, t4 a4 ) \
+ { _GET_CONTEXT; fn( a1, a2, a3, a4, &context ); }
+
+#endif /* __sparc__ */
+
+#ifndef DEFINE_REGS_ENTRYPOINT_0
+#error You need to define DEFINE_REGS_ENTRYPOINT macros for your CPU
+#endif
+
+#ifdef __i386__
+# define GET_IP(context) ((LPVOID)(context)->Eip)
+#endif
+#ifdef __sparc__
+# define GET_IP(context) ((LPVOID)(context)->pc)
+#endif
+
+#if !defined(GET_IP) && !defined(RC_INVOKED)
+# error You must define GET_IP for this CPU
+#endif
+
+#endif /* __WINE__ */
+
+/*
+ * Exception codes
+ */
+
+#define STATUS_SUCCESS 0x00000000
+#define STATUS_WAIT_0 0x00000000
+#define STATUS_ABANDONED_WAIT_0 0x00000080
+#define STATUS_USER_APC 0x000000C0
+#define STATUS_TIMEOUT 0x00000102
+#define STATUS_PENDING 0x00000103
+
+#define STATUS_GUARD_PAGE_VIOLATION 0x80000001
+#define STATUS_DATATYPE_MISALIGNMENT 0x80000002
+#define STATUS_BREAKPOINT 0x80000003
+#define STATUS_SINGLE_STEP 0x80000004
+#define STATUS_BUFFER_OVERFLOW 0x80000005
+#define STATUS_NO_MORE_FILES 0x80000006
+#define STATUS_WAKE_SYSTEM_DEBUGGER 0x80000007
+
+#define STATUS_HANDLES_CLOSED 0x8000000A
+#define STATUS_NO_INHERITANCE 0x8000000B
+#define STATUS_GUID_SUBSTITUTION_MADE 0x8000000C
+#define STATUS_PARTIAL_COPY 0x8000000D
+#define STATUS_DEVICE_PAPER_EMPTY 0x8000000E
+#define STATUS_DEVICE_POWERED_OFF 0x8000000F
+#define STATUS_DEVICE_OFF_LINE 0x80000010
+#define STATUS_DEVICE_BUSY 0x80000011
+#define STATUS_NO_MORE_EAS 0x80000012
+#define STATUS_INVALID_EA_NAME 0x80000013
+#define STATUS_EA_LIST_INCONSISTENT 0x80000014
+#define STATUS_INVALID_EA_FLAG 0x80000015
+#define STATUS_VERIFY_REQUIRED 0x80000016
+#define STATUS_EXTRANEOUS_INFORMATION 0x80000017
+#define STATUS_RXACT_COMMIT_NECESSARY 0x80000018
+#define STATUS_NO_MORE_ENTRIES 0x8000001A
+#define STATUS_FILEMARK_DETECTED 0x8000001B
+#define STATUS_MEDIA_CHANGED 0x8000001C
+#define STATUS_BUS_RESET 0x8000001D
+#define STATUS_END_OF_MEDIA 0x8000001E
+#define STATUS_BEGINNING_OF_MEDIA 0x8000001F
+#define STATUS_MEDIA_CHECK 0x80000020
+#define STATUS_SETMARK_DETECTED 0x80000021
+#define STATUS_NO_DATA_DETECTED 0x80000022
+#define STATUS_REDIRECTOR_HAS_OPEN_HANDLES 0x80000023
+#define STATUS_SERVER_HAS_OPEN_HANDLES 0x80000024
+#define STATUS_ALREADY_DISCONNECTED 0x80000025
+#define STATUS_LONGJUMP 0x80000026
+
+#define STATUS_UNSUCCESSFUL 0xC0000001
+#define STATUS_NOT_IMPLEMENTED 0xC0000002
+#define STATUS_INVALID_INFO_CLASS 0xC0000003
+#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
+#define STATUS_ACCESS_VIOLATION 0xC0000005
+#define STATUS_IN_PAGE_ERROR 0xC0000006
+#define STATUS_PAGEFILE_QUOTA 0xC0000007
+#define STATUS_INVALID_HANDLE 0xC0000008
+#define STATUS_BAD_INITIAL_STACK 0xC0000009
+#define STATUS_BAD_INITIAL_PC 0xC000000A
+#define STATUS_INVALID_CID 0xC000000B
+#define STATUS_TIMER_NOT_CANCELED 0xC000000C
+#define STATUS_INVALID_PARAMETER 0xC000000D
+#define STATUS_NO_SUCH_DEVICE 0xC000000E
+#define STATUS_NO_SUCH_FILE 0xC000000F
+#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010
+#define STATUS_END_OF_FILE 0xC0000011
+#define STATUS_WRONG_VOLUME 0xC0000012
+#define STATUS_NO_MEDIA_IN_DEVICE 0xC0000013
+#define STATUS_UNRECOGNIZED_MEDIA 0xC0000014
+#define STATUS_NONEXISTENT_SECTOR 0xC0000015
+#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016
+#define STATUS_NO_MEMORY 0xC0000017
+#define STATUS_CONFLICTING_ADDRESSES 0xC0000018
+#define STATUS_NOT_MAPPED_VIEW 0xC0000019
+#define STATUS_UNABLE_TO_FREE_VM 0xC000001A
+#define STATUS_UNABLE_TO_DELETE_SECTION 0xC000001B
+#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C
+#define STATUS_ILLEGAL_INSTRUCTION 0xC000001D
+#define STATUS_INVALID_LOCK_SEQUENCE 0xC000001E
+#define STATUS_INVALID_VIEW_SIZE 0xC000001F
+#define STATUS_INVALID_FILE_FOR_SECTION 0xC0000020
+#define STATUS_ALREADY_COMMITTED 0xC0000021
+#define STATUS_ACCESS_DENIED 0xC0000022
+#define STATUS_BUFFER_TOO_SMALL 0xC0000023
+#define STATUS_OBJECT_TYPE_MISMATCH 0xC0000024
+#define STATUS_NONCONTINUABLE_EXCEPTION 0xC0000025
+#define STATUS_INVALID_DISPOSITION 0xC0000026
+#define STATUS_UNWIND 0xC0000027
+#define STATUS_BAD_STACK 0xC0000028
+#define STATUS_INVALID_UNWIND_TARGET 0xC0000029
+#define STATUS_NOT_LOCKED 0xC000002A
+#define STATUS_PARITY_ERROR 0xC000002B
+#define STATUS_UNABLE_TO_DECOMMIT_VM 0xC000002C
+#define STATUS_NOT_COMMITTED 0xC000002D
+#define STATUS_INVALID_PORT_ATTRIBUTES 0xC000002E
+#define STATUS_PORT_MESSAGE_TOO_LONG 0xC000002F
+#define STATUS_INVALID_PARAMETER_MIX 0xC0000030
+#define STATUS_INVALID_QUOTA_LOWER 0xC0000031
+#define STATUS_DISK_CORRUPT_ERROR 0xC0000032
+#define STATUS_OBJECT_NAME_INVALID 0xC0000033
+#define STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034
+#define STATUS_OBJECT_NAME_COLLISION 0xC0000035
+#define STATUS_PORT_DISCONNECTED 0xC0000037
+#define STATUS_DEVICE_ALREADY_ATTACHED 0xC0000038
+#define STATUS_OBJECT_PATH_INVALID 0xC0000039
+#define STATUS_OBJECT_PATH_NOT_FOUND 0xC000003A
+#define STATUS_PATH_SYNTAX_BAD 0xC000003B
+#define STATUS_DATA_OVERRUN 0xC000003C
+#define STATUS_DATA_LATE_ERROR 0xC000003D
+#define STATUS_DATA_ERROR 0xC000003E
+#define STATUS_CRC_ERROR 0xC000003F
+#define STATUS_SECTION_TOO_BIG 0xC0000040
+#define STATUS_PORT_CONNECTION_REFUSED 0xC0000041
+#define STATUS_INVALID_PORT_HANDLE 0xC0000042
+#define STATUS_SHARING_VIOLATION 0xC0000043
+#define STATUS_QUOTA_EXCEEDED 0xC0000044
+#define STATUS_INVALID_PAGE_PROTECTION 0xC0000045
+#define STATUS_MUTANT_NOT_OWNED 0xC0000046
+#define STATUS_SEMAPHORE_LIMIT_EXCEEDED 0xC0000047
+#define STATUS_PORT_ALREADY_SET 0xC0000048
+#define STATUS_SUSPEND_COUNT_EXCEEDED 0xC000004A
+#define STATUS_LOCK_NOT_GRANTED 0xC0000054 /* FIXME: not sure */
+#define STATUS_FILE_LOCK_CONFLICT 0xC0000055 /* FIXME: not sure */
+#define STATUS_UNKNOWN_REVISION 0xC0000058
+#define STATUS_INVALID_SECURITY_DESCR 0xC0000079
+#define STATUS_DISK_FULL 0xC000007F
+#define STATUS_SECTION_NOT_EXTENDED 0xC0000087
+#define STATUS_ARRAY_BOUNDS_EXCEEDED 0xC000008C
+#define STATUS_FLOAT_DENORMAL_OPERAND 0xC000008D
+#define STATUS_FLOAT_DIVIDE_BY_ZERO 0xC000008E
+#define STATUS_FLOAT_INEXACT_RESULT 0xC000008F
+#define STATUS_FLOAT_INVALID_OPERATION 0xC0000090
+#define STATUS_FLOAT_OVERFLOW 0xC0000091
+#define STATUS_FLOAT_STACK_CHECK 0xC0000092
+#define STATUS_FLOAT_UNDERFLOW 0xC0000093
+#define STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000094
+#define STATUS_INTEGER_OVERFLOW 0xC0000095
+#define STATUS_PRIVILEGED_INSTRUCTION 0xC0000096
+#define STATUS_MEDIA_WRITE_PROTECTED 0XC00000A2
+#define STATUS_INVALID_PARAMETER_2 0xC00000F0
+#define STATUS_STACK_OVERFLOW 0xC00000FD
+#define STATUS_DIRECTORY_NOT_EMPTY 0xC0000101
+#define STATUS_TOO_MANY_OPENED_FILES 0xC000011F
+#define STATUS_CONTROL_C_EXIT 0xC000013A
+#define STATUS_PIPE_BROKEN 0xC000014B
+#define STATUS_NOT_REGISTRY_FILE 0xC000015C
+#define STATUS_PARTITION_FAILURE 0xC0000172
+#define STATUS_INVALID_BLOCK_LENGTH 0xC0000173
+#define STATUS_DEVICE_NOT_PARTITIONED 0xC0000174
+#define STATUS_UNABLE_TO_LOCK_MEDIA 0xC0000175
+#define STATUS_UNABLE_TO_UNLOAD_MEDIA 0xC0000176
+#define STATUS_EOM_OVERFLOW 0xC0000177
+#define STATUS_NO_MEDIA 0xC0000178
+#define STATUS_NO_SUCH_MEMBER 0xC000017A
+#define STATUS_INVALID_MEMBER 0xC000017B
+#define STATUS_KEY_DELETED 0xC000017C
+#define STATUS_NO_LOG_SPACE 0xC000017D
+#define STATUS_TOO_MANY_SIDS 0xC000017E
+#define STATUS_LM_CROSS_ENCRYPTION_REQUIRED 0xC000017F
+#define STATUS_KEY_HAS_CHILDREN 0xC0000180
+#define STATUS_CHILD_MUST_BE_VOLATILE 0xC0000181
+#define STATUS_DEVICE_CONFIGURATION_ERROR0xC0000182
+#define STATUS_DRIVER_INTERNAL_ERROR 0xC0000183
+#define STATUS_INVALID_DEVICE_STATE 0xC0000184
+#define STATUS_IO_DEVICE_ERROR 0xC0000185
+#define STATUS_DEVICE_PROTOCOL_ERROR 0xC0000186
+#define STATUS_BACKUP_CONTROLLER 0xC0000187
+#define STATUS_LOG_FILE_FULL 0xC0000188
+#define STATUS_TOO_LATE 0xC0000189
+#define STATUS_NO_TRUST_LSA_SECRET 0xC000018A
+#define STATUS_NO_TRUST_SAM_ACCOUNT 0xC000018B
+#define STATUS_TRUSTED_DOMAIN_FAILURE 0xC000018C
+#define STATUS_TRUSTED_RELATIONSHIP_FAILURE 0xC000018D
+#define STATUS_EVENTLOG_FILE_CORRUPT 0xC000018E
+#define STATUS_EVENTLOG_CANT_START 0xC000018F
+#define STATUS_TRUST_FAILURE 0xC0000190
+#define STATUS_MUTANT_LIMIT_EXCEEDED 0xC0000191
+#define STATUS_NETLOGON_NOT_STARTED 0xC0000192
+#define STATUS_ACCOUNT_EXPIRED 0xC0000193
+#define STATUS_POSSIBLE_DEADLOCK 0xC0000194
+#define STATUS_NETWORK_CREDENTIAL_CONFLICT 0xC0000195
+#define STATUS_REMOTE_SESSION_LIMIT 0xC0000196
+#define STATUS_EVENTLOG_FILE_CHANGED 0xC0000197
+#define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 0xC0000198
+#define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT 0xC0000199
+#define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT 0xC000019A
+#define STATUS_DOMAIN_TRUST_INCONSISTENT 0xC000019B
+#define STATUS_FS_DRIVER_REQUIRED 0xC000019C
+
+#define STATUS_RESOURCE_LANG_NOT_FOUND 0xC0000204
+
+#define MAXIMUM_WAIT_OBJECTS 64
+#define MAXIMUM_SUSPEND_COUNT 127
+
+
+/*
+ * Return values from the actual exception handlers
+ */
+
+#define ExceptionContinueExecution 0
+#define ExceptionContinueSearch 1
+#define ExceptionNestedException 2
+#define ExceptionCollidedUnwind 3
+
+/*
+ * Return values from filters in except() and from UnhandledExceptionFilter
+ */
+
+#define EXCEPTION_EXECUTE_HANDLER 1
+#define EXCEPTION_CONTINUE_SEARCH 0
+#define EXCEPTION_CONTINUE_EXECUTION -1
+
+/*
+ * From OS/2 2.0 exception handling
+ * Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD
+ */
+
+#define EH_NONCONTINUABLE 0x01
+#define EH_UNWINDING 0x02
+#define EH_EXIT_UNWIND 0x04
+#define EH_STACK_INVALID 0x08
+#define EH_NESTED_CALL 0x10
+
+#define EXCEPTION_CONTINUABLE 0
+#define EXCEPTION_NONCONTINUABLE EH_NONCONTINUABLE
+
+/*
+ * The exception record used by Win32 to give additional information
+ * about exception to exception handlers.
+ */
+
+#define EXCEPTION_MAXIMUM_PARAMETERS 15
+
+typedef struct __EXCEPTION_RECORD
+{
+ DWORD ExceptionCode;
+ DWORD ExceptionFlags;
+ struct __EXCEPTION_RECORD *ExceptionRecord;
+
+ LPVOID ExceptionAddress;
+ DWORD NumberParameters;
+ DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+} EXCEPTION_RECORD, *PEXCEPTION_RECORD;
+
+/*
+ * The exception pointers structure passed to exception filters
+ * in except() and the UnhandledExceptionFilter().
+ */
+
+typedef struct _EXCEPTION_POINTERS
+{
+ PEXCEPTION_RECORD ExceptionRecord;
+ PCONTEXT ContextRecord;
+} EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
+
+
+/*
+ * The exception frame, used for registering exception handlers
+ * Win32 cares only about this, but compilers generally emit
+ * larger exception frames for their own use.
+ */
+
+struct __EXCEPTION_FRAME;
+
+typedef DWORD (*PEXCEPTION_HANDLER)(PEXCEPTION_RECORD,struct __EXCEPTION_FRAME*,
+ PCONTEXT,struct __EXCEPTION_FRAME **);
+
+typedef struct __EXCEPTION_FRAME
+{
+ struct __EXCEPTION_FRAME *Prev;
+ PEXCEPTION_HANDLER Handler;
+} EXCEPTION_FRAME, *PEXCEPTION_FRAME;
+
+#include "poppack.h"
+
+/*
+ * function pointer to a exception filter
+ */
+
+typedef LONG CALLBACK (*PTOP_LEVEL_EXCEPTION_FILTER)(PEXCEPTION_POINTERS ExceptionInfo);
+typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER;
+
+DWORD WINAPI UnhandledExceptionFilter( PEXCEPTION_POINTERS epointers );
+LPTOP_LEVEL_EXCEPTION_FILTER
+WINAPI SetUnhandledExceptionFilter( LPTOP_LEVEL_EXCEPTION_FILTER filter );
+
+/* status values for ContinueDebugEvent */
+#define DBG_CONTINUE 0x00010002
+#define DBG_TERMINATE_THREAD 0x40010003
+#define DBG_TERMINATE_PROCESS 0x40010004
+#define DBG_CONTROL_C 0x40010005
+#define DBG_CONTROL_BREAK 0x40010008
+#define DBG_EXCEPTION_NOT_HANDLED 0x80010001
+
+typedef struct _NT_TIB
+{
+ struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
+ PVOID StackBase;
+ PVOID StackLimit;
+ PVOID SubSystemTib;
+ union {
+ PVOID FiberData;
+ DWORD Version;
+ } DUMMYUNIONNAME;
+ PVOID ArbitraryUserPointer;
+ struct _NT_TIB *Self;
+} NT_TIB, *PNT_TIB;
+
+struct _TEB;
+/*
+#if defined(__i386__) && defined(__GNUC__)
+extern inline struct _TEB * WINAPI NtCurrentTeb(void);
+extern inline struct _TEB * WINAPI NtCurrentTeb(void)
+{
+ struct _TEB *teb;
+ __asm__(".byte 0x64\n\tmovl (0x18),%0" : "=r" (teb));
+ return teb;
+}
+#else
+extern struct _TEB * WINAPI NtCurrentTeb(void);
+#endif
+*/
+
+/*
+ * File formats definitions
+ */
+
+typedef struct _IMAGE_DOS_HEADER {
+ WORD e_magic; /* 00: MZ Header signature */
+ WORD e_cblp; /* 02: Bytes on last page of file */
+ WORD e_cp; /* 04: Pages in file */
+ WORD e_crlc; /* 06: Relocations */
+ WORD e_cparhdr; /* 08: Size of header in paragraphs */
+ WORD e_minalloc; /* 0a: Minimum extra paragraphs needed */
+ WORD e_maxalloc; /* 0c: Maximum extra paragraphs needed */
+ WORD e_ss; /* 0e: Initial (relative) SS value */
+ WORD e_sp; /* 10: Initial SP value */
+ WORD e_csum; /* 12: Checksum */
+ WORD e_ip; /* 14: Initial IP value */
+ WORD e_cs; /* 16: Initial (relative) CS value */
+ WORD e_lfarlc; /* 18: File address of relocation table */
+ WORD e_ovno; /* 1a: Overlay number */
+ WORD e_res[4]; /* 1c: Reserved words */
+ WORD e_oemid; /* 24: OEM identifier (for e_oeminfo) */
+ WORD e_oeminfo; /* 26: OEM information; e_oemid specific */
+ WORD e_res2[10]; /* 28: Reserved words */
+ DWORD e_lfanew; /* 3c: Offset to extended header */
+} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
+
+#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */
+#define IMAGE_OS2_SIGNATURE 0x454E /* NE */
+#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */
+#define IMAGE_OS2_SIGNATURE_LX 0x584C /* LX */
+#define IMAGE_VXD_SIGNATURE 0x454C /* LE */
+#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
+
+/*
+ * This is the Windows executable (NE) header.
+ * the name IMAGE_OS2_HEADER is misleading, but in the SDK this way.
+ */
+typedef struct
+{
+ WORD ne_magic; /* 00 NE signature 'NE' */
+ BYTE ne_ver; /* 02 Linker version number */
+ BYTE ne_rev; /* 03 Linker revision number */
+ WORD ne_enttab; /* 04 Offset to entry table relative to NE */
+ WORD ne_cbenttab; /* 06 Length of entry table in bytes */
+ LONG ne_crc; /* 08 Checksum */
+ WORD ne_flags; /* 0c Flags about segments in this file */
+ WORD ne_autodata; /* 0e Automatic data segment number */
+ WORD ne_heap; /* 10 Initial size of local heap */
+ WORD ne_stack; /* 12 Initial size of stack */
+ DWORD ne_csip; /* 14 Initial CS:IP */
+ DWORD ne_sssp; /* 18 Initial SS:SP */
+ WORD ne_cseg; /* 1c # of entries in segment table */
+ WORD ne_cmod; /* 1e # of entries in module reference tab. */
+ WORD ne_cbnrestab; /* 20 Length of nonresident-name table */
+ WORD ne_segtab; /* 22 Offset to segment table */
+ WORD ne_rsrctab; /* 24 Offset to resource table */
+ WORD ne_restab; /* 26 Offset to resident-name table */
+ WORD ne_modtab; /* 28 Offset to module reference table */
+ WORD ne_imptab; /* 2a Offset to imported name table */
+ DWORD ne_nrestab; /* 2c Offset to nonresident-name table */
+ WORD ne_cmovent; /* 30 # of movable entry points */
+ WORD ne_align; /* 32 Logical sector alignment shift count */
+ WORD ne_cres; /* 34 # of resource segments */
+ BYTE ne_exetyp; /* 36 Flags indicating target OS */
+ BYTE ne_flagsothers; /* 37 Additional information flags */
+ WORD fastload_offset; /* 38 Offset to fast load area (should be ne_pretthunks)*/
+ WORD fastload_length; /* 3a Length of fast load area (should be ne_psegrefbytes) */
+ WORD ne_swaparea; /* 3c Reserved by Microsoft */
+ WORD ne_expver; /* 3e Expected Windows version number */
+} IMAGE_OS2_HEADER,*PIMAGE_OS2_HEADER;
+
+typedef struct _IMAGE_VXD_HEADER {
+ WORD e32_magic;
+ BYTE e32_border;
+ BYTE e32_worder;
+ DWORD e32_level;
+ WORD e32_cpu;
+ WORD e32_os;
+ DWORD e32_ver;
+ DWORD e32_mflags;
+ DWORD e32_mpages;
+ DWORD e32_startobj;
+ DWORD e32_eip;
+ DWORD e32_stackobj;
+ DWORD e32_esp;
+ DWORD e32_pagesize;
+ DWORD e32_lastpagesize;
+ DWORD e32_fixupsize;
+ DWORD e32_fixupsum;
+ DWORD e32_ldrsize;
+ DWORD e32_ldrsum;
+ DWORD e32_objtab;
+ DWORD e32_objcnt;
+ DWORD e32_objmap;
+ DWORD e32_itermap;
+ DWORD e32_rsrctab;
+ DWORD e32_rsrccnt;
+ DWORD e32_restab;
+ DWORD e32_enttab;
+ DWORD e32_dirtab;
+ DWORD e32_dircnt;
+ DWORD e32_fpagetab;
+ DWORD e32_frectab;
+ DWORD e32_impmod;
+ DWORD e32_impmodcnt;
+ DWORD e32_impproc;
+ DWORD e32_pagesum;
+ DWORD e32_datapage;
+ DWORD e32_preload;
+ DWORD e32_nrestab;
+ DWORD e32_cbnrestab;
+ DWORD e32_nressum;
+ DWORD e32_autodata;
+ DWORD e32_debuginfo;
+ DWORD e32_debuglen;
+ DWORD e32_instpreload;
+ DWORD e32_instdemand;
+ DWORD e32_heapsize;
+ BYTE e32_res3[12];
+ DWORD e32_winresoff;
+ DWORD e32_winreslen;
+ WORD e32_devid;
+ WORD e32_ddkver;
+} IMAGE_VXD_HEADER, *PIMAGE_VXD_HEADER;
+
+
+/* These defines describe the meanings of the bits in the Characteristics
+ field */
+
+#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 /* No relocation info */
+#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
+#define IMAGE_FILE_16BIT_MACHINE 0x0040
+#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
+#define IMAGE_FILE_32BIT_MACHINE 0x0100
+#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
+#define IMAGE_FILE_SYSTEM 0x1000
+#define IMAGE_FILE_DLL 0x2000
+#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
+
+/* These are the settings of the Machine field. */
+#define IMAGE_FILE_MACHINE_UNKNOWN 0
+#define IMAGE_FILE_MACHINE_I860 0x14d
+#define IMAGE_FILE_MACHINE_I386 0x14c
+#define IMAGE_FILE_MACHINE_R3000 0x162
+#define IMAGE_FILE_MACHINE_R4000 0x166
+#define IMAGE_FILE_MACHINE_R10000 0x168
+#define IMAGE_FILE_MACHINE_ALPHA 0x184
+#define IMAGE_FILE_MACHINE_POWERPC 0x1F0
+
+#define IMAGE_SIZEOF_FILE_HEADER 20
+
+/* Possible Magic values */
+#define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b
+#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
+
+/* These are indexes into the DataDirectory array */
+#define IMAGE_FILE_EXPORT_DIRECTORY 0
+#define IMAGE_FILE_IMPORT_DIRECTORY 1
+#define IMAGE_FILE_RESOURCE_DIRECTORY 2
+#define IMAGE_FILE_EXCEPTION_DIRECTORY 3
+#define IMAGE_FILE_SECURITY_DIRECTORY 4
+#define IMAGE_FILE_BASE_RELOCATION_TABLE 5
+#define IMAGE_FILE_DEBUG_DIRECTORY 6
+#define IMAGE_FILE_DESCRIPTION_STRING 7
+#define IMAGE_FILE_MACHINE_VALUE 8 /* Mips */
+#define IMAGE_FILE_THREAD_LOCAL_STORAGE 9
+#define IMAGE_FILE_CALLBACK_DIRECTORY 10
+
+/* Directory Entries, indices into the DataDirectory array */
+
+#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
+#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
+#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
+#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
+#define IMAGE_DIRECTORY_ENTRY_SECURITY 4
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
+#define IMAGE_DIRECTORY_ENTRY_DEBUG 6
+#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
+#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* (MIPS GP) */
+#define IMAGE_DIRECTORY_ENTRY_TLS 9
+#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
+#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11
+#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */
+#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
+#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14
+
+/* Subsystem Values */
+
+#define IMAGE_SUBSYSTEM_UNKNOWN 0
+#define IMAGE_SUBSYSTEM_NATIVE 1
+#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 /* Windows GUI subsystem */
+#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 /* Windows character subsystem*/
+#define IMAGE_SUBSYSTEM_OS2_CUI 5
+#define IMAGE_SUBSYSTEM_POSIX_CUI 7
+
+typedef struct _IMAGE_FILE_HEADER {
+ WORD Machine;
+ WORD NumberOfSections;
+ DWORD TimeDateStamp;
+ DWORD PointerToSymbolTable;
+ DWORD NumberOfSymbols;
+ WORD SizeOfOptionalHeader;
+ WORD Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+
+typedef struct _IMAGE_DATA_DIRECTORY {
+ DWORD VirtualAddress;
+ DWORD Size;
+} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
+
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+
+typedef struct _IMAGE_OPTIONAL_HEADER {
+
+ /* Standard fields */
+
+ WORD Magic;
+ BYTE MajorLinkerVersion;
+ BYTE MinorLinkerVersion;
+ DWORD SizeOfCode;
+ DWORD SizeOfInitializedData;
+ DWORD SizeOfUninitializedData;
+ DWORD AddressOfEntryPoint;
+ DWORD BaseOfCode;
+ DWORD BaseOfData;
+
+ /* NT additional fields */
+
+ DWORD ImageBase;
+ DWORD SectionAlignment;
+ DWORD FileAlignment;
+ WORD MajorOperatingSystemVersion;
+ WORD MinorOperatingSystemVersion;
+ WORD MajorImageVersion;
+ WORD MinorImageVersion;
+ WORD MajorSubsystemVersion;
+ WORD MinorSubsystemVersion;
+ DWORD Win32VersionValue;
+ DWORD SizeOfImage;
+ DWORD SizeOfHeaders;
+ DWORD CheckSum;
+ WORD Subsystem;
+ WORD DllCharacteristics;
+ DWORD SizeOfStackReserve;
+ DWORD SizeOfStackCommit;
+ DWORD SizeOfHeapReserve;
+ DWORD SizeOfHeapCommit;
+ DWORD LoaderFlags;
+ DWORD NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
+
+typedef struct _IMAGE_NT_HEADERS {
+ DWORD Signature;
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_OPTIONAL_HEADER OptionalHeader;
+} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
+
+#define IMAGE_SIZEOF_SHORT_NAME 8
+
+typedef struct _IMAGE_SECTION_HEADER {
+ BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ DWORD PhysicalAddress;
+ DWORD VirtualSize;
+ } Misc;
+ DWORD VirtualAddress;
+ DWORD SizeOfRawData;
+ DWORD PointerToRawData;
+ DWORD PointerToRelocations;
+ DWORD PointerToLinenumbers;
+ WORD NumberOfRelocations;
+ WORD NumberOfLinenumbers;
+ DWORD Characteristics;
+} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
+
+#define IMAGE_SIZEOF_SECTION_HEADER 40
+
+#define IMAGE_FIRST_SECTION(ntheader) \
+ ((PIMAGE_SECTION_HEADER)((LPBYTE)&((PIMAGE_NT_HEADERS)(ntheader))->OptionalHeader + \
+ ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader))
+
+/* These defines are for the Characteristics bitfield. */
+/* #define IMAGE_SCN_TYPE_REG 0x00000000 - Reserved */
+/* #define IMAGE_SCN_TYPE_DSECT 0x00000001 - Reserved */
+/* #define IMAGE_SCN_TYPE_NOLOAD 0x00000002 - Reserved */
+/* #define IMAGE_SCN_TYPE_GROUP 0x00000004 - Reserved */
+/* #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 - Reserved */
+/* #define IMAGE_SCN_TYPE_COPY 0x00000010 - Reserved */
+
+#define IMAGE_SCN_CNT_CODE 0x00000020
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
+
+#define IMAGE_SCN_LNK_OTHER 0x00000100
+#define IMAGE_SCN_LNK_INFO 0x00000200
+/* #define IMAGE_SCN_TYPE_OVER 0x00000400 - Reserved */
+#define IMAGE_SCN_LNK_REMOVE 0x00000800
+#define IMAGE_SCN_LNK_COMDAT 0x00001000
+
+/* 0x00002000 - Reserved */
+/* #define IMAGE_SCN_MEM_PROTECTED 0x00004000 - Obsolete */
+#define IMAGE_SCN_MEM_FARDATA 0x00008000
+
+/* #define IMAGE_SCN_MEM_SYSHEAP 0x00010000 - Obsolete */
+#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
+#define IMAGE_SCN_MEM_16BIT 0x00020000
+#define IMAGE_SCN_MEM_LOCKED 0x00040000
+#define IMAGE_SCN_MEM_PRELOAD 0x00080000
+
+#define IMAGE_SCN_ALIGN_1BYTES 0x00100000
+#define IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default */
+#define IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define IMAGE_SCN_ALIGN_64BYTES 0x00700000
+/* 0x00800000 - Unused */
+
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
+
+
+#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000
+#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000
+#define IMAGE_SCN_MEM_SHARED 0x10000000
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define IMAGE_SCN_MEM_READ 0x40000000
+#define IMAGE_SCN_MEM_WRITE 0x80000000
+
+#include "pshpack2.h"
+
+typedef struct _IMAGE_SYMBOL {
+ union {
+ BYTE ShortName[8];
+ struct {
+ DWORD Short;
+ DWORD Long;
+ } Name;
+ DWORD LongName[2];
+ } N;
+ DWORD Value;
+ SHORT SectionNumber;
+ WORD Type;
+ BYTE StorageClass;
+ BYTE NumberOfAuxSymbols;
+} IMAGE_SYMBOL;
+typedef IMAGE_SYMBOL *PIMAGE_SYMBOL;
+
+#define IMAGE_SIZEOF_SYMBOL 18
+
+typedef struct _IMAGE_LINENUMBER {
+ union {
+ DWORD SymbolTableIndex;
+ DWORD VirtualAddress;
+ } Type;
+ WORD Linenumber;
+} IMAGE_LINENUMBER;
+typedef IMAGE_LINENUMBER *PIMAGE_LINENUMBER;
+
+#define IMAGE_SIZEOF_LINENUMBER 6
+
+typedef union _IMAGE_AUX_SYMBOL {
+ struct {
+ DWORD TagIndex;
+ union {
+ struct {
+ WORD Linenumber;
+ WORD Size;
+ } LnSz;
+ DWORD TotalSize;
+ } Misc;
+ union {
+ struct {
+ DWORD PointerToLinenumber;
+ DWORD PointerToNextFunction;
+ } Function;
+ struct {
+ WORD Dimension[4];
+ } Array;
+ } FcnAry;
+ WORD TvIndex;
+ } Sym;
+ struct {
+ BYTE Name[IMAGE_SIZEOF_SYMBOL];
+ } File;
+ struct {
+ DWORD Length;
+ WORD NumberOfRelocations;
+ WORD NumberOfLinenumbers;
+ DWORD CheckSum;
+ SHORT Number;
+ BYTE Selection;
+ } Section;
+} IMAGE_AUX_SYMBOL;
+typedef IMAGE_AUX_SYMBOL *PIMAGE_AUX_SYMBOL;
+
+#define IMAGE_SIZEOF_AUX_SYMBOL 18
+
+#include "poppack.h"
+
+#define IMAGE_SYM_UNDEFINED (SHORT)0
+#define IMAGE_SYM_ABSOLUTE (SHORT)-1
+#define IMAGE_SYM_DEBUG (SHORT)-2
+
+#define IMAGE_SYM_TYPE_NULL 0x0000
+#define IMAGE_SYM_TYPE_VOID 0x0001
+#define IMAGE_SYM_TYPE_CHAR 0x0002
+#define IMAGE_SYM_TYPE_SHORT 0x0003
+#define IMAGE_SYM_TYPE_INT 0x0004
+#define IMAGE_SYM_TYPE_LONG 0x0005
+#define IMAGE_SYM_TYPE_FLOAT 0x0006
+#define IMAGE_SYM_TYPE_DOUBLE 0x0007
+#define IMAGE_SYM_TYPE_STRUCT 0x0008
+#define IMAGE_SYM_TYPE_UNION 0x0009
+#define IMAGE_SYM_TYPE_ENUM 0x000A
+#define IMAGE_SYM_TYPE_MOE 0x000B
+#define IMAGE_SYM_TYPE_BYTE 0x000C
+#define IMAGE_SYM_TYPE_WORD 0x000D
+#define IMAGE_SYM_TYPE_UINT 0x000E
+#define IMAGE_SYM_TYPE_DWORD 0x000F
+#define IMAGE_SYM_TYPE_PCODE 0x8000
+
+#define IMAGE_SYM_DTYPE_NULL 0
+#define IMAGE_SYM_DTYPE_POINTER 1
+#define IMAGE_SYM_DTYPE_FUNCTION 2
+#define IMAGE_SYM_DTYPE_ARRAY 3
+
+#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1
+#define IMAGE_SYM_CLASS_NULL 0x0000
+#define IMAGE_SYM_CLASS_AUTOMATIC 0x0001
+#define IMAGE_SYM_CLASS_EXTERNAL 0x0002
+#define IMAGE_SYM_CLASS_STATIC 0x0003
+#define IMAGE_SYM_CLASS_REGISTER 0x0004
+#define IMAGE_SYM_CLASS_EXTERNAL_DEF 0x0005
+#define IMAGE_SYM_CLASS_LABEL 0x0006
+#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 0x0007
+#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 0x0008
+#define IMAGE_SYM_CLASS_ARGUMENT 0x0009
+#define IMAGE_SYM_CLASS_STRUCT_TAG 0x000A
+#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 0x000B
+#define IMAGE_SYM_CLASS_UNION_TAG 0x000C
+#define IMAGE_SYM_CLASS_TYPE_DEFINITION 0x000D
+#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 0x000E
+#define IMAGE_SYM_CLASS_ENUM_TAG 0x000F
+#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 0x0010
+#define IMAGE_SYM_CLASS_REGISTER_PARAM 0x0011
+#define IMAGE_SYM_CLASS_BIT_FIELD 0x0012
+
+#define IMAGE_SYM_CLASS_FAR_EXTERNAL 0x0044
+#define IMAGE_SYM_CLASS_BLOCK 0x0064
+#define IMAGE_SYM_CLASS_FUNCTION 0x0065
+#define IMAGE_SYM_CLASS_END_OF_STRUCT 0x0066
+#define IMAGE_SYM_CLASS_FILE 0x0067
+#define IMAGE_SYM_CLASS_SECTION 0x0068
+#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 0x0069
+
+#define N_BTMASK 0x000F
+#define N_TMASK 0x0030
+#define N_TMASK1 0x00C0
+#define N_TMASK2 0x00F0
+#define N_BTSHFT 4
+#define N_TSHIFT 2
+
+#define BTYPE(x) ((x) & N_BTMASK)
+
+#ifndef ISPTR
+#define ISPTR(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_POINTER << N_BTSHFT))
+#endif
+
+#ifndef ISFCN
+#define ISFCN(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT))
+#endif
+
+#ifndef ISARY
+#define ISARY(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT))
+#endif
+
+#ifndef ISTAG
+#define ISTAG(x) ((x)==IMAGE_SYM_CLASS_STRUCT_TAG || (x)==IMAGE_SYM_CLASS_UNION_TAG || (x)==IMAGE_SYM_CLASS_ENUM_TAG)
+#endif
+
+#ifndef INCREF
+#define INCREF(x) ((((x)&~N_BTMASK)<<N_TSHIFT)|(IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT)|((x)&N_BTMASK))
+#endif
+#ifndef DECREF
+#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
+#endif
+
+#define IMAGE_COMDAT_SELECT_NODUPLICATES 1
+#define IMAGE_COMDAT_SELECT_ANY 2
+#define IMAGE_COMDAT_SELECT_SAME_SIZE 3
+#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4
+#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
+#define IMAGE_COMDAT_SELECT_LARGEST 6
+#define IMAGE_COMDAT_SELECT_NEWEST 7
+
+#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
+#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
+#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
+
+/* Export module directory */
+
+typedef struct _IMAGE_EXPORT_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD Name;
+ DWORD Base;
+ DWORD NumberOfFunctions;
+ DWORD NumberOfNames;
+ LPDWORD *AddressOfFunctions;
+ LPDWORD *AddressOfNames;
+ LPWORD *AddressOfNameOrdinals;
+} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY;
+
+/* Import name entry */
+typedef struct _IMAGE_IMPORT_BY_NAME {
+ WORD Hint;
+ BYTE Name[1];
+} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME;
+
+/* Import thunk */
+typedef struct _IMAGE_THUNK_DATA {
+ union {
+ LPBYTE ForwarderString;
+ FARPROC Function;
+ DWORD Ordinal;
+ PIMAGE_IMPORT_BY_NAME AddressOfData;
+ } u1;
+} IMAGE_THUNK_DATA,*PIMAGE_THUNK_DATA;
+
+/* Import module directory */
+
+typedef struct _IMAGE_IMPORT_DESCRIPTOR {
+ union {
+ DWORD Characteristics; /* 0 for terminating null import descriptor */
+ PIMAGE_THUNK_DATA OriginalFirstThunk; /* RVA to original unbound IAT */
+ } u;
+ DWORD TimeDateStamp; /* 0 if not bound,
+ * -1 if bound, and real date\time stamp
+ * in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
+ * (new BIND)
+ * otherwise date/time stamp of DLL bound to
+ * (Old BIND)
+ */
+ DWORD ForwarderChain; /* -1 if no forwarders */
+ DWORD Name;
+ /* RVA to IAT (if bound this IAT has actual addresses) */
+ PIMAGE_THUNK_DATA FirstThunk;
+} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR;
+
+#define IMAGE_ORDINAL_FLAG 0x80000000
+#define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0)
+#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
+
+typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR
+{
+ DWORD TimeDateStamp;
+ WORD OffsetModuleName;
+ WORD NumberOfModuleForwarderRefs;
+/* Array of zero or more IMAGE_BOUND_FORWARDER_REF follows */
+} IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR;
+
+typedef struct _IMAGE_BOUND_FORWARDER_REF
+{
+ DWORD TimeDateStamp;
+ WORD OffsetModuleName;
+ WORD Reserved;
+} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF;
+
+typedef struct _IMAGE_BASE_RELOCATION
+{
+ DWORD VirtualAddress;
+ DWORD SizeOfBlock;
+ WORD TypeOffset[1];
+} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION;
+
+typedef struct _IMAGE_RELOCATION
+{
+ union {
+ DWORD VirtualAddress;
+ DWORD RelocCount;
+ } u;
+ DWORD SymbolTableIndex;
+ WORD Type;
+} IMAGE_RELOCATION;
+typedef IMAGE_RELOCATION *PIMAGE_RELOCATION;
+
+#define IMAGE_SIZEOF_RELOCATION 10
+
+/* generic relocation types */
+#define IMAGE_REL_BASED_ABSOLUTE 0
+#define IMAGE_REL_BASED_HIGH 1
+#define IMAGE_REL_BASED_LOW 2
+#define IMAGE_REL_BASED_HIGHLOW 3
+#define IMAGE_REL_BASED_HIGHADJ 4
+#define IMAGE_REL_BASED_MIPS_JMPADDR 5
+#define IMAGE_REL_BASED_SECTION 6
+#define IMAGE_REL_BASED_REL 7
+#define IMAGE_REL_BASED_MIPS_JMPADDR16 9
+#define IMAGE_REL_BASED_IA64_IMM64 9 /* yes, 9 too */
+#define IMAGE_REL_BASED_DIR64 10
+#define IMAGE_REL_BASED_HIGH3ADJ 11
+
+/* I386 relocation types */
+#define IMAGE_REL_I386_ABSOLUTE 0
+#define IMAGE_REL_I386_DIR16 1
+#define IMAGE_REL_I386_REL16 2
+#define IMAGE_REL_I386_DIR32 6
+#define IMAGE_REL_I386_DIR32NB 7
+#define IMAGE_REL_I386_SEG12 9
+#define IMAGE_REL_I386_SECTION 10
+#define IMAGE_REL_I386_SECREL 11
+#define IMAGE_REL_I386_REL32 20
+
+/* MIPS relocation types */
+#define IMAGE_REL_MIPS_ABSOLUTE 0x0000
+#define IMAGE_REL_MIPS_REFHALF 0x0001
+#define IMAGE_REL_MIPS_REFWORD 0x0002
+#define IMAGE_REL_MIPS_JMPADDR 0x0003
+#define IMAGE_REL_MIPS_REFHI 0x0004
+#define IMAGE_REL_MIPS_REFLO 0x0005
+#define IMAGE_REL_MIPS_GPREL 0x0006
+#define IMAGE_REL_MIPS_LITERAL 0x0007
+#define IMAGE_REL_MIPS_SECTION 0x000A
+#define IMAGE_REL_MIPS_SECREL 0x000B
+#define IMAGE_REL_MIPS_SECRELLO 0x000C
+#define IMAGE_REL_MIPS_SECRELHI 0x000D
+#define IMAGE_REL_MIPS_JMPADDR16 0x0010
+#define IMAGE_REL_MIPS_REFWORDNB 0x0022
+#define IMAGE_REL_MIPS_PAIR 0x0025
+
+/* ALPHA relocation types */
+#define IMAGE_REL_ALPHA_ABSOLUTE 0x0000
+#define IMAGE_REL_ALPHA_REFLONG 0x0001
+#define IMAGE_REL_ALPHA_REFQUAD 0x0002
+#define IMAGE_REL_ALPHA_GPREL 0x0003
+#define IMAGE_REL_ALPHA_LITERAL 0x0004
+#define IMAGE_REL_ALPHA_LITUSE 0x0005
+#define IMAGE_REL_ALPHA_GPDISP 0x0006
+#define IMAGE_REL_ALPHA_BRADDR 0x0007
+#define IMAGE_REL_ALPHA_HINT 0x0008
+#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x0009
+#define IMAGE_REL_ALPHA_REFHI 0x000A
+#define IMAGE_REL_ALPHA_REFLO 0x000B
+#define IMAGE_REL_ALPHA_PAIR 0x000C
+#define IMAGE_REL_ALPHA_MATCH 0x000D
+#define IMAGE_REL_ALPHA_SECTION 0x000E
+#define IMAGE_REL_ALPHA_SECREL 0x000F
+#define IMAGE_REL_ALPHA_REFLONGNB 0x0010
+#define IMAGE_REL_ALPHA_SECRELLO 0x0011
+#define IMAGE_REL_ALPHA_SECRELHI 0x0012
+#define IMAGE_REL_ALPHA_REFQ3 0x0013
+#define IMAGE_REL_ALPHA_REFQ2 0x0014
+#define IMAGE_REL_ALPHA_REFQ1 0x0015
+#define IMAGE_REL_ALPHA_GPRELLO 0x0016
+#define IMAGE_REL_ALPHA_GPRELHI 0x0017
+
+/* PowerPC relocation types */
+#define IMAGE_REL_PPC_ABSOLUTE 0x0000
+#define IMAGE_REL_PPC_ADDR64 0x0001
+#define IMAGE_REL_PPC_ADDR 0x0002
+#define IMAGE_REL_PPC_ADDR24 0x0003
+#define IMAGE_REL_PPC_ADDR16 0x0004
+#define IMAGE_REL_PPC_ADDR14 0x0005
+#define IMAGE_REL_PPC_REL24 0x0006
+#define IMAGE_REL_PPC_REL14 0x0007
+#define IMAGE_REL_PPC_TOCREL16 0x0008
+#define IMAGE_REL_PPC_TOCREL14 0x0009
+#define IMAGE_REL_PPC_ADDR32NB 0x000A
+#define IMAGE_REL_PPC_SECREL 0x000B
+#define IMAGE_REL_PPC_SECTION 0x000C
+#define IMAGE_REL_PPC_IFGLUE 0x000D
+#define IMAGE_REL_PPC_IMGLUE 0x000E
+#define IMAGE_REL_PPC_SECREL16 0x000F
+#define IMAGE_REL_PPC_REFHI 0x0010
+#define IMAGE_REL_PPC_REFLO 0x0011
+#define IMAGE_REL_PPC_PAIR 0x0012
+#define IMAGE_REL_PPC_SECRELLO 0x0013
+#define IMAGE_REL_PPC_SECRELHI 0x0014
+#define IMAGE_REL_PPC_GPREL 0x0015
+#define IMAGE_REL_PPC_TYPEMASK 0x00FF
+/* modifier bits */
+#define IMAGE_REL_PPC_NEG 0x0100
+#define IMAGE_REL_PPC_BRTAKEN 0x0200
+#define IMAGE_REL_PPC_BRNTAKEN 0x0400
+#define IMAGE_REL_PPC_TOCDEFN 0x0800
+
+/* SH3 ? relocation type */
+#define IMAGE_REL_SH3_ABSOLUTE 0x0000
+#define IMAGE_REL_SH3_DIRECT16 0x0001
+#define IMAGE_REL_SH3_DIRECT 0x0002
+#define IMAGE_REL_SH3_DIRECT8 0x0003
+#define IMAGE_REL_SH3_DIRECT8_WORD 0x0004
+#define IMAGE_REL_SH3_DIRECT8_LONG 0x0005
+#define IMAGE_REL_SH3_DIRECT4 0x0006
+#define IMAGE_REL_SH3_DIRECT4_WORD 0x0007
+#define IMAGE_REL_SH3_DIRECT4_LONG 0x0008
+#define IMAGE_REL_SH3_PCREL8_WORD 0x0009
+#define IMAGE_REL_SH3_PCREL8_LONG 0x000A
+#define IMAGE_REL_SH3_PCREL12_WORD 0x000B
+#define IMAGE_REL_SH3_STARTOF_SECTION 0x000C
+#define IMAGE_REL_SH3_SIZEOF_SECTION 0x000D
+#define IMAGE_REL_SH3_SECTION 0x000E
+#define IMAGE_REL_SH3_SECREL 0x000F
+#define IMAGE_REL_SH3_DIRECT32_NB 0x0010
+
+/* ARM (Archimedes?) relocation types */
+#define IMAGE_REL_ARM_ABSOLUTE 0x0000
+#define IMAGE_REL_ARM_ADDR 0x0001
+#define IMAGE_REL_ARM_ADDR32NB 0x0002
+#define IMAGE_REL_ARM_BRANCH24 0x0003
+#define IMAGE_REL_ARM_BRANCH11 0x0004
+#define IMAGE_REL_ARM_SECTION 0x000E
+#define IMAGE_REL_ARM_SECREL 0x000F
+
+/* IA64 relocation types */
+#define IMAGE_REL_IA64_ABSOLUTE 0x0000
+#define IMAGE_REL_IA64_IMM14 0x0001
+#define IMAGE_REL_IA64_IMM22 0x0002
+#define IMAGE_REL_IA64_IMM64 0x0003
+#define IMAGE_REL_IA64_DIR 0x0004
+#define IMAGE_REL_IA64_DIR64 0x0005
+#define IMAGE_REL_IA64_PCREL21B 0x0006
+#define IMAGE_REL_IA64_PCREL21M 0x0007
+#define IMAGE_REL_IA64_PCREL21F 0x0008
+#define IMAGE_REL_IA64_GPREL22 0x0009
+#define IMAGE_REL_IA64_LTOFF22 0x000A
+#define IMAGE_REL_IA64_SECTION 0x000B
+#define IMAGE_REL_IA64_SECREL22 0x000C
+#define IMAGE_REL_IA64_SECREL64I 0x000D
+#define IMAGE_REL_IA64_SECREL 0x000E
+#define IMAGE_REL_IA64_LTOFF64 0x000F
+#define IMAGE_REL_IA64_DIR32NB 0x0010
+#define IMAGE_REL_IA64_RESERVED_11 0x0011
+#define IMAGE_REL_IA64_RESERVED_12 0x0012
+#define IMAGE_REL_IA64_RESERVED_13 0x0013
+#define IMAGE_REL_IA64_RESERVED_14 0x0014
+#define IMAGE_REL_IA64_RESERVED_15 0x0015
+#define IMAGE_REL_IA64_RESERVED_16 0x0016
+#define IMAGE_REL_IA64_ADDEND 0x001F
+
+/* archive format */
+
+#define IMAGE_ARCHIVE_START_SIZE 8
+#define IMAGE_ARCHIVE_START "!<arch>\n"
+#define IMAGE_ARCHIVE_END "`\n"
+#define IMAGE_ARCHIVE_PAD "\n"
+#define IMAGE_ARCHIVE_LINKER_MEMBER "/ "
+#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
+
+typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER
+{
+ BYTE Name[16];
+ BYTE Date[12];
+ BYTE UserID[6];
+ BYTE GroupID[6];
+ BYTE Mode[8];
+ BYTE Size[10];
+ BYTE EndHeader[2];
+} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER;
+
+#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
+
+/*
+ * Resource directory stuff
+ */
+typedef struct _IMAGE_RESOURCE_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ WORD NumberOfNamedEntries;
+ WORD NumberOfIdEntries;
+ /* IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; */
+} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY;
+
+#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
+#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
+
+typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
+ union {
+ struct {
+ unsigned NameOffset:31;
+ unsigned NameIsString:1;
+ } s;
+ DWORD Name;
+ WORD Id;
+ } u1;
+ union {
+ DWORD OffsetToData;
+ struct {
+ unsigned OffsetToDirectory:31;
+ unsigned DataIsDirectory:1;
+ } s;
+ } u2;
+} IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY;
+
+
+typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING {
+ WORD Length;
+ CHAR NameString[ 1 ];
+} IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING;
+
+typedef struct _IMAGE_RESOURCE_DIR_STRING_U {
+ WORD Length;
+ WCHAR NameString[ 1 ];
+} IMAGE_RESOURCE_DIR_STRING_U,*PIMAGE_RESOURCE_DIR_STRING_U;
+
+typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
+ DWORD OffsetToData;
+ DWORD Size;
+ DWORD CodePage;
+ DWORD ResourceHandle;
+} IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY;
+
+
+typedef VOID CALLBACK (*PIMAGE_TLS_CALLBACK)(
+ LPVOID DllHandle,DWORD Reason,LPVOID Reserved
+);
+
+typedef struct _IMAGE_TLS_DIRECTORY {
+ DWORD StartAddressOfRawData;
+ DWORD EndAddressOfRawData;
+ LPDWORD AddressOfIndex;
+ PIMAGE_TLS_CALLBACK *AddressOfCallBacks;
+ DWORD SizeOfZeroFill;
+ DWORD Characteristics;
+} IMAGE_TLS_DIRECTORY,*PIMAGE_TLS_DIRECTORY;
+
+typedef struct _IMAGE_DEBUG_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD Type;
+ DWORD SizeOfData;
+ DWORD AddressOfRawData;
+ DWORD PointerToRawData;
+} IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY;
+
+#define IMAGE_DEBUG_TYPE_UNKNOWN 0
+#define IMAGE_DEBUG_TYPE_COFF 1
+#define IMAGE_DEBUG_TYPE_CODEVIEW 2
+#define IMAGE_DEBUG_TYPE_FPO 3
+#define IMAGE_DEBUG_TYPE_MISC 4
+#define IMAGE_DEBUG_TYPE_EXCEPTION 5
+#define IMAGE_DEBUG_TYPE_FIXUP 6
+#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7
+#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8
+#define IMAGE_DEBUG_TYPE_BORLAND 9
+#define IMAGE_DEBUG_TYPE_RESERVED10 10
+
+typedef struct _IMAGE_COFF_SYMBOLS_HEADER {
+ DWORD NumberOfSymbols;
+ DWORD LvaToFirstSymbol;
+ DWORD NumberOfLinenumbers;
+ DWORD LvaToFirstLinenumber;
+ DWORD RvaToFirstByteOfCode;
+ DWORD RvaToLastByteOfCode;
+ DWORD RvaToFirstByteOfData;
+ DWORD RvaToLastByteOfData;
+} IMAGE_COFF_SYMBOLS_HEADER, *PIMAGE_COFF_SYMBOLS_HEADER;
+
+#define FRAME_FPO 0
+#define FRAME_TRAP 1
+#define FRAME_TSS 2
+#define FRAME_NONFPO 3
+
+typedef struct _FPO_DATA {
+ DWORD ulOffStart;
+ DWORD cbProcSize;
+ DWORD cdwLocals;
+ WORD cdwParams;
+ unsigned cbProlog : 8;
+ unsigned cbRegs : 3;
+ unsigned fHasSEH : 1;
+ unsigned fUseBP : 1;
+ unsigned reserved : 1;
+ unsigned cbFrame : 2;
+} FPO_DATA, *PFPO_DATA;
+
+typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD GlobalFlagsClear;
+ DWORD GlobalFlagsSet;
+ DWORD CriticalSectionDefaultTimeout;
+ DWORD DeCommitFreeBlockThreshold;
+ DWORD DeCommitTotalFreeThreshold;
+ PVOID LockPrefixTable;
+ DWORD MaximumAllocationSize;
+ DWORD VirtualMemoryThreshold;
+ DWORD ProcessHeapFlags;
+ DWORD ProcessAffinityMask;
+ WORD CSDVersion;
+ WORD Reserved1;
+ PVOID EditList;
+ DWORD Reserved[1];
+} IMAGE_LOAD_CONFIG_DIRECTORY, *PIMAGE_LOAD_CONFIG_DIRECTORY;
+
+typedef struct _IMAGE_FUNCTION_ENTRY {
+ DWORD StartingAddress;
+ DWORD EndingAddress;
+ DWORD EndOfPrologue;
+} IMAGE_FUNCTION_ENTRY, *PIMAGE_FUNCTION_ENTRY;
+
+/* This is the structure that appears at the very start of a .DBG file. */
+
+typedef struct _IMAGE_SEPARATE_DEBUG_HEADER {
+ WORD Signature;
+ WORD Flags;
+ WORD Machine;
+ WORD Characteristics;
+ DWORD TimeDateStamp;
+ DWORD CheckSum;
+ DWORD ImageBase;
+ DWORD SizeOfImage;
+ DWORD NumberOfSections;
+ DWORD ExportedNamesSize;
+ DWORD DebugDirectorySize;
+ DWORD SectionAlignment;
+ DWORD Reserved[ 2 ];
+} IMAGE_SEPARATE_DEBUG_HEADER,*PIMAGE_SEPARATE_DEBUG_HEADER;
+
+#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944
+
+
+typedef struct tagMESSAGE_RESOURCE_ENTRY {
+ WORD Length;
+ WORD Flags;
+ BYTE Text[1];
+} MESSAGE_RESOURCE_ENTRY,*PMESSAGE_RESOURCE_ENTRY;
+#define MESSAGE_RESOURCE_UNICODE 0x0001
+
+typedef struct tagMESSAGE_RESOURCE_BLOCK {
+ DWORD LowId;
+ DWORD HighId;
+ DWORD OffsetToEntries;
+} MESSAGE_RESOURCE_BLOCK,*PMESSAGE_RESOURCE_BLOCK;
+
+typedef struct tagMESSAGE_RESOURCE_DATA {
+ DWORD NumberOfBlocks;
+ MESSAGE_RESOURCE_BLOCK Blocks[ 1 ];
+} MESSAGE_RESOURCE_DATA,*PMESSAGE_RESOURCE_DATA;
+
+/*
+ * Here follows typedefs for security and tokens.
+ */
+
+/*
+ * First a constant for the following typdefs.
+ */
+
+#define ANYSIZE_ARRAY 1
+
+/* FIXME: Orphan. What does it point to? */
+typedef PVOID PACCESS_TOKEN;
+
+/*
+ * TOKEN_INFORMATION_CLASS
+ */
+
+typedef enum _TOKEN_INFORMATION_CLASS {
+ TokenUser = 1,
+ TokenGroups,
+ TokenPrivileges,
+ TokenOwner,
+ TokenPrimaryGroup,
+ TokenDefaultDacl,
+ TokenSource,
+ TokenType,
+ TokenImpersonationLevel,
+ TokenStatistics
+} TOKEN_INFORMATION_CLASS;
+
+#ifndef _SECURITY_DEFINED
+#define _SECURITY_DEFINED
+
+#include "pshpack1.h"
+
+typedef DWORD ACCESS_MASK, *PACCESS_MASK;
+
+typedef struct _GENERIC_MAPPING {
+ ACCESS_MASK GenericRead;
+ ACCESS_MASK GenericWrite;
+ ACCESS_MASK GenericExecute;
+ ACCESS_MASK GenericAll;
+} GENERIC_MAPPING, *PGENERIC_MAPPING;
+
+#ifndef SID_IDENTIFIER_AUTHORITY_DEFINED
+#define SID_IDENTIFIER_AUTHORITY_DEFINED
+typedef struct {
+ BYTE Value[6];
+} SID_IDENTIFIER_AUTHORITY,*PSID_IDENTIFIER_AUTHORITY,*LPSID_IDENTIFIER_AUTHORITY;
+#endif /* !defined(SID_IDENTIFIER_AUTHORITY_DEFINED) */
+
+#ifndef SID_DEFINED
+#define SID_DEFINED
+typedef struct _SID {
+ BYTE Revision;
+ BYTE SubAuthorityCount;
+ SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
+ DWORD SubAuthority[1];
+} SID,*PSID;
+#endif /* !defined(SID_DEFINED) */
+
+#define SID_REVISION (1) /* Current revision */
+#define SID_MAX_SUB_AUTHORITIES (15) /* current max subauths */
+#define SID_RECOMMENDED_SUB_AUTHORITIES (1) /* recommended subauths */
+
+
+/*
+ * ACL
+ */
+
+#define ACL_REVISION1 1
+#define ACL_REVISION2 2
+#define ACL_REVISION3 3
+#define ACL_REVISION4 4
+
+#define MIN_ACL_REVISION ACL_REVISION2
+#define MAX_ACL_REVISION ACL_REVISION4
+
+typedef struct _ACL {
+ BYTE AclRevision;
+ BYTE Sbz1;
+ WORD AclSize;
+ WORD AceCount;
+ WORD Sbz2;
+} ACL, *PACL;
+
+/* SECURITY_DESCRIPTOR */
+#define SECURITY_DESCRIPTOR_REVISION 1
+#define SECURITY_DESCRIPTOR_REVISION1 1
+
+
+#define SE_OWNER_DEFAULTED 0x0001
+#define SE_GROUP_DEFAULTED 0x0002
+#define SE_DACL_PRESENT 0x0004
+#define SE_DACL_DEFAULTED 0x0008
+#define SE_SACL_PRESENT 0x0010
+#define SE_SACL_DEFAULTED 0x0020
+#define SE_SELF_RELATIVE 0x8000
+
+typedef DWORD SECURITY_INFORMATION, *PSECURITY_INFORMATION;
+typedef WORD SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL;
+
+/* The security descriptor structure */
+typedef struct {
+ BYTE Revision;
+ BYTE Sbz1;
+ SECURITY_DESCRIPTOR_CONTROL Control;
+ DWORD Owner;
+ DWORD Group;
+ DWORD Sacl;
+ DWORD Dacl;
+} SECURITY_DESCRIPTOR_RELATIVE, *PISECURITY_DESCRIPTOR_RELATIVE;
+
+typedef struct {
+ BYTE Revision;
+ BYTE Sbz1;
+ SECURITY_DESCRIPTOR_CONTROL Control;
+ PSID Owner;
+ PSID Group;
+ PACL Sacl;
+ PACL Dacl;
+} SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR;
+
+#define SECURITY_DESCRIPTOR_MIN_LENGTH (sizeof(SECURITY_DESCRIPTOR))
+
+#include "poppack.h"
+
+#endif /* _SECURITY_DEFINED */
+
+#include "pshpack1.h"
+
+/*
+ * SID_AND_ATTRIBUTES
+ */
+
+typedef struct _SID_AND_ATTRIBUTES {
+ PSID Sid;
+ DWORD Attributes;
+} SID_AND_ATTRIBUTES ;
+
+/* security entities */
+#define SECURITY_NULL_RID (0x00000000L)
+#define SECURITY_WORLD_RID (0x00000000L)
+#define SECURITY_LOCAL_RID (0X00000000L)
+
+#define SECURITY_NULL_SID_AUTHORITY {0,0,0,0,0,0}
+
+/* S-1-1 */
+#define SECURITY_WORLD_SID_AUTHORITY {0,0,0,0,0,1}
+
+/* S-1-2 */
+#define SECURITY_LOCAL_SID_AUTHORITY {0,0,0,0,0,2}
+
+/* S-1-3 */
+#define SECURITY_CREATOR_SID_AUTHORITY {0,0,0,0,0,3}
+#define SECURITY_CREATOR_OWNER_RID (0x00000000L)
+#define SECURITY_CREATOR_GROUP_RID (0x00000001L)
+#define SECURITY_CREATOR_OWNER_SERVER_RID (0x00000002L)
+#define SECURITY_CREATOR_GROUP_SERVER_RID (0x00000003L)
+
+/* S-1-4 */
+#define SECURITY_NON_UNIQUE_AUTHORITY {0,0,0,0,0,4}
+
+/* S-1-5 */
+#define SECURITY_NT_AUTHORITY {0,0,0,0,0,5}
+#define SECURITY_DIALUP_RID 0x00000001L
+#define SECURITY_NETWORK_RID 0x00000002L
+#define SECURITY_BATCH_RID 0x00000003L
+#define SECURITY_INTERACTIVE_RID 0x00000004L
+#define SECURITY_LOGON_IDS_RID 0x00000005L
+#define SECURITY_SERVICE_RID 0x00000006L
+#define SECURITY_ANONYMOUS_LOGON_RID 0x00000007L
+#define SECURITY_PROXY_RID 0x00000008L
+#define SECURITY_ENTERPRISE_CONTROLLERS_RID 0x00000009L
+#define SECURITY_PRINCIPAL_SELF_RID 0x0000000AL
+#define SECURITY_AUTHENTICATED_USER_RID 0x0000000BL
+#define SECURITY_RESTRICTED_CODE_RID 0x0000000CL
+#define SECURITY_TERMINAL_SERVER_RID 0x0000000DL
+#define SECURITY_LOCAL_SYSTEM_RID 0x00000012L
+#define SECURITY_NT_NON_UNIQUE 0x00000015L
+#define SECURITY_BUILTIN_DOMAIN_RID 0x00000020L
+
+#define DOMAIN_GROUP_RID_ADMINS 0x00000200L
+#define DOMAIN_GROUP_RID_USERS 0x00000201L
+#define DOMAIN_GROUP_RID_GUESTS 0x00000202L
+
+#define DOMAIN_ALIAS_RID_ADMINS 0x00000220L
+#define DOMAIN_ALIAS_RID_USERS 0x00000221L
+#define DOMAIN_ALIAS_RID_GUESTS 0x00000222L
+
+#define SECURITY_SERVER_LOGON_RID SECURITY_ENTERPRISE_CONTROLLERS_RID
+
+#define SECURITY_LOGON_IDS_RID_COUNT (3L)
+
+/*
+ * TOKEN_USER
+ */
+
+typedef struct _TOKEN_USER {
+ SID_AND_ATTRIBUTES User;
+} TOKEN_USER;
+
+/*
+ * TOKEN_GROUPS
+ */
+
+typedef struct _TOKEN_GROUPS {
+ DWORD GroupCount;
+ SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
+} TOKEN_GROUPS;
+
+/*
+ * LUID_AND_ATTRIBUTES
+ */
+
+typedef union _LARGE_INTEGER {
+ struct {
+ DWORD LowPart;
+ LONG HighPart;
+ } DUMMYSTRUCTNAME;
+ LONGLONG QuadPart;
+} LARGE_INTEGER, *LPLARGE_INTEGER, *PLARGE_INTEGER;
+
+typedef union _ULARGE_INTEGER {
+ struct {
+ DWORD LowPart;
+ LONG HighPart;
+ } DUMMYSTRUCTNAME;
+ LONGLONG QuadPart;
+} ULARGE_INTEGER, *LPULARGE_INTEGER, *PULARGE_INTEGER;
+
+/*
+ * Locally Unique Identifier
+ */
+
+typedef LARGE_INTEGER LUID,*PLUID;
+
+typedef struct _LUID_AND_ATTRIBUTES {
+ LUID Luid;
+ DWORD Attributes;
+} LUID_AND_ATTRIBUTES;
+
+/*
+ * PRIVILEGE_SET
+ */
+
+typedef struct _PRIVILEGE_SET {
+ DWORD PrivilegeCount;
+ DWORD Control;
+ LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];
+} PRIVILEGE_SET, *PPRIVILEGE_SET;
+
+/*
+ * TOKEN_PRIVILEGES
+ */
+
+typedef struct _TOKEN_PRIVILEGES {
+ DWORD PrivilegeCount;
+ LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
+} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
+
+/*
+ * TOKEN_OWNER
+ */
+
+typedef struct _TOKEN_OWNER {
+ PSID Owner;
+} TOKEN_OWNER;
+
+/*
+ * TOKEN_PRIMARY_GROUP
+ */
+
+typedef struct _TOKEN_PRIMARY_GROUP {
+ PSID PrimaryGroup;
+} TOKEN_PRIMARY_GROUP;
+
+
+/*
+ * TOKEN_DEFAULT_DACL
+ */
+
+typedef struct _TOKEN_DEFAULT_DACL {
+ PACL DefaultDacl;
+} TOKEN_DEFAULT_DACL;
+
+/*
+ * TOKEN_SOURCEL
+ */
+
+typedef struct _TOKEN_SOURCE {
+ char Sourcename[8];
+ LUID SourceIdentifier;
+} TOKEN_SOURCE;
+
+/*
+ * TOKEN_TYPE
+ */
+
+typedef enum tagTOKEN_TYPE {
+ TokenPrimary = 1,
+ TokenImpersonation
+} TOKEN_TYPE;
+
+/*
+ * SECURITY_IMPERSONATION_LEVEL
+ */
+
+typedef enum _SECURITY_IMPERSONATION_LEVEL {
+ SecurityAnonymous,
+ SecurityIdentification,
+ SecurityImpersonation,
+ SecurityDelegation
+} SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL;
+
+
+typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE,
+ * PSECURITY_CONTEXT_TRACKING_MODE;
+/*
+ * Quality of Service
+ */
+
+typedef struct _SECURITY_QUALITY_OF_SERVICE {
+ DWORD Length;
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+ SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;
+ WIN_BOOL EffectiveOnly;
+} SECURITY_QUALITY_OF_SERVICE, *PSECURITY_QUALITY_OF_SERVICE;
+
+/*
+ * TOKEN_STATISTICS
+ */
+
+typedef struct _TOKEN_STATISTICS {
+ LUID TokenId;
+ LUID AuthenticationId;
+ LARGE_INTEGER ExpirationTime;
+ TOKEN_TYPE TokenType;
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+ DWORD DynamicCharged;
+ DWORD DynamicAvailable;
+ DWORD GroupCount;
+ DWORD PrivilegeCount;
+ LUID ModifiedId;
+} TOKEN_STATISTICS;
+
+/*
+ * ACLs of NT
+ */
+
+#define ACL_REVISION 2
+
+#define ACL_REVISION1 1
+#define ACL_REVISION2 2
+
+/* ACEs, directly starting after an ACL */
+typedef struct _ACE_HEADER {
+ BYTE AceType;
+ BYTE AceFlags;
+ WORD AceSize;
+} ACE_HEADER,*PACE_HEADER;
+
+/* AceType */
+#define ACCESS_ALLOWED_ACE_TYPE 0
+#define ACCESS_DENIED_ACE_TYPE 1
+#define SYSTEM_AUDIT_ACE_TYPE 2
+#define SYSTEM_ALARM_ACE_TYPE 3
+
+/* inherit AceFlags */
+#define OBJECT_INHERIT_ACE 0x01
+#define CONTAINER_INHERIT_ACE 0x02
+#define NO_PROPAGATE_INHERIT_ACE 0x04
+#define INHERIT_ONLY_ACE 0x08
+#define VALID_INHERIT_FLAGS 0x0F
+
+/* AceFlags mask for what events we (should) audit */
+#define SUCCESSFUL_ACCESS_ACE_FLAG 0x40
+#define FAILED_ACCESS_ACE_FLAG 0x80
+
+/* different ACEs depending on AceType
+ * SidStart marks the begin of a SID
+ * so the thing finally looks like this:
+ * 0: ACE_HEADER
+ * 4: ACCESS_MASK
+ * 8... : SID
+ */
+typedef struct _ACCESS_ALLOWED_ACE {
+ ACE_HEADER Header;
+ DWORD Mask;
+ DWORD SidStart;
+} ACCESS_ALLOWED_ACE,*PACCESS_ALLOWED_ACE;
+
+typedef struct _ACCESS_DENIED_ACE {
+ ACE_HEADER Header;
+ DWORD Mask;
+ DWORD SidStart;
+} ACCESS_DENIED_ACE,*PACCESS_DENIED_ACE;
+
+typedef struct _SYSTEM_AUDIT_ACE {
+ ACE_HEADER Header;
+ DWORD Mask;
+ DWORD SidStart;
+} SYSTEM_AUDIT_ACE,*PSYSTEM_AUDIT_ACE;
+
+typedef struct _SYSTEM_ALARM_ACE {
+ ACE_HEADER Header;
+ DWORD Mask;
+ DWORD SidStart;
+} SYSTEM_ALARM_ACE,*PSYSTEM_ALARM_ACE;
+
+typedef enum tagSID_NAME_USE {
+ SidTypeUser = 1,
+ SidTypeGroup,
+ SidTypeDomain,
+ SidTypeAlias,
+ SidTypeWellKnownGroup,
+ SidTypeDeletedAccount,
+ SidTypeInvalid,
+ SidTypeUnknown
+} SID_NAME_USE,*PSID_NAME_USE;
+
+/* Access rights */
+
+#define DELETE 0x00010000
+#define READ_CONTROL 0x00020000
+#define WRITE_DAC 0x00040000
+#define WRITE_OWNER 0x00080000
+#define SYNCHRONIZE 0x00100000
+#define STANDARD_RIGHTS_REQUIRED 0x000f0000
+
+#define STANDARD_RIGHTS_READ READ_CONTROL
+#define STANDARD_RIGHTS_WRITE READ_CONTROL
+#define STANDARD_RIGHTS_EXECUTE READ_CONTROL
+
+#define STANDARD_RIGHTS_ALL 0x001f0000
+
+#define SPECIFIC_RIGHTS_ALL 0x0000ffff
+
+#define GENERIC_READ 0x80000000
+#define GENERIC_WRITE 0x40000000
+#define GENERIC_EXECUTE 0x20000000
+#define GENERIC_ALL 0x10000000
+
+#define MAXIMUM_ALLOWED 0x02000000
+#define ACCESS_SYSTEM_SECURITY 0x01000000
+
+#define EVENT_MODIFY_STATE 0x0002
+#define EVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
+
+#define SEMAPHORE_MODIFY_STATE 0x0002
+#define SEMAPHORE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
+
+#define MUTEX_MODIFY_STATE 0x0001
+#define MUTEX_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1)
+
+#define PROCESS_TERMINATE 0x0001
+#define PROCESS_CREATE_THREAD 0x0002
+#define PROCESS_VM_OPERATION 0x0008
+#define PROCESS_VM_READ 0x0010
+#define PROCESS_VM_WRITE 0x0020
+#define PROCESS_DUP_HANDLE 0x0040
+#define PROCESS_CREATE_PROCESS 0x0080
+#define PROCESS_SET_QUOTA 0x0100
+#define PROCESS_SET_INFORMATION 0x0200
+#define PROCESS_QUERY_INFORMATION 0x0400
+#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0xfff)
+
+#define THREAD_TERMINATE 0x0001
+#define THREAD_SUSPEND_RESUME 0x0002
+#define THREAD_GET_CONTEXT 0x0008
+#define THREAD_SET_CONTEXT 0x0010
+#define THREAD_SET_INFORMATION 0x0020
+#define THREAD_QUERY_INFORMATION 0x0040
+#define THREAD_SET_THREAD_TOKEN 0x0080
+#define THREAD_IMPERSONATE 0x0100
+#define THREAD_DIRECT_IMPERSONATION 0x0200
+#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3ff)
+
+#define THREAD_BASE_PRIORITY_LOWRT 15
+#define THREAD_BASE_PRIORITY_MAX 2
+#define THREAD_BASE_PRIORITY_MIN -2
+#define THREAD_BASE_PRIORITY_IDLE -15
+
+#define FILE_READ_DATA 0x0001 /* file & pipe */
+#define FILE_LIST_DIRECTORY 0x0001 /* directory */
+#define FILE_WRITE_DATA 0x0002 /* file & pipe */
+#define FILE_ADD_FILE 0x0002 /* directory */
+#define FILE_APPEND_DATA 0x0004 /* file */
+#define FILE_ADD_SUBDIRECTORY 0x0004 /* directory */
+#define FILE_CREATE_PIPE_INSTANCE 0x0004 /* named pipe */
+#define FILE_READ_EA 0x0008 /* file & directory */
+#define FILE_READ_PROPERTIES FILE_READ_EA
+#define FILE_WRITE_EA 0x0010 /* file & directory */
+#define FILE_WRITE_PROPERTIES FILE_WRITE_EA
+#define FILE_EXECUTE 0x0020 /* file */
+#define FILE_TRAVERSE 0x0020 /* directory */
+#define FILE_DELETE_CHILD 0x0040 /* directory */
+#define FILE_READ_ATTRIBUTES 0x0080 /* all */
+#define FILE_WRITE_ATTRIBUTES 0x0100 /* all */
+#define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1ff)
+
+#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ | FILE_READ_DATA | \
+ FILE_READ_ATTRIBUTES | FILE_READ_EA | \
+ SYNCHRONIZE)
+#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | \
+ FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | \
+ FILE_APPEND_DATA | SYNCHRONIZE)
+#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE | FILE_EXECUTE | \
+ FILE_READ_ATTRIBUTES | SYNCHRONIZE)
+
+
+/* File attribute flags
+ */
+#define FILE_SHARE_READ 0x00000001L
+#define FILE_SHARE_WRITE 0x00000002L
+#define FILE_SHARE_DELETE 0x00000004L
+#define FILE_ATTRIBUTE_READONLY 0x00000001L
+#define FILE_ATTRIBUTE_HIDDEN 0x00000002L
+#define FILE_ATTRIBUTE_SYSTEM 0x00000004L
+#define FILE_ATTRIBUTE_LABEL 0x00000008L /* Not in Windows API */
+#define FILE_ATTRIBUTE_DIRECTORY 0x00000010L
+#define FILE_ATTRIBUTE_ARCHIVE 0x00000020L
+#define FILE_ATTRIBUTE_NORMAL 0x00000080L
+#define FILE_ATTRIBUTE_TEMPORARY 0x00000100L
+#define FILE_ATTRIBUTE_ATOMIC_WRITE 0x00000200L
+#define FILE_ATTRIBUTE_XACTION_WRITE 0x00000400L
+#define FILE_ATTRIBUTE_COMPRESSED 0x00000800L
+#define FILE_ATTRIBUTE_OFFLINE 0x00001000L
+
+/* File alignments (NT) */
+#define FILE_BYTE_ALIGNMENT 0x00000000
+#define FILE_WORD_ALIGNMENT 0x00000001
+#define FILE_LONG_ALIGNMENT 0x00000003
+#define FILE_QUAD_ALIGNMENT 0x00000007
+#define FILE_OCTA_ALIGNMENT 0x0000000f
+#define FILE_32_BYTE_ALIGNMENT 0x0000001f
+#define FILE_64_BYTE_ALIGNMENT 0x0000003f
+#define FILE_128_BYTE_ALIGNMENT 0x0000007f
+#define FILE_256_BYTE_ALIGNMENT 0x000000ff
+#define FILE_512_BYTE_ALIGNMENT 0x000001ff
+
+#define REG_NONE 0 /* no type */
+#define REG_SZ 1 /* string type (ASCII) */
+#define REG_EXPAND_SZ 2 /* string, includes %ENVVAR% (expanded by caller) (ASCII) */
+#define REG_BINARY 3 /* binary format, callerspecific */
+/* YES, REG_DWORD == REG_DWORD_LITTLE_ENDIAN */
+#define REG_DWORD 4 /* DWORD in little endian format */
+#define REG_DWORD_LITTLE_ENDIAN 4 /* DWORD in little endian format */
+#define REG_DWORD_BIG_ENDIAN 5 /* DWORD in big endian format */
+#define REG_LINK 6 /* symbolic link (UNICODE) */
+#define REG_MULTI_SZ 7 /* multiple strings, delimited by \0, terminated by \0\0 (ASCII) */
+#define REG_RESOURCE_LIST 8 /* resource list? huh? */
+#define REG_FULL_RESOURCE_DESCRIPTOR 9 /* full resource descriptor? huh? */
+#define REG_RESOURCE_REQUIREMENTS_LIST 10
+
+/* ----------------------------- begin registry ----------------------------- */
+
+/* Registry security values */
+#define OWNER_SECURITY_INFORMATION 0x00000001
+#define GROUP_SECURITY_INFORMATION 0x00000002
+#define DACL_SECURITY_INFORMATION 0x00000004
+#define SACL_SECURITY_INFORMATION 0x00000008
+
+#define REG_OPTION_RESERVED 0x00000000
+#define REG_OPTION_NON_VOLATILE 0x00000000
+#define REG_OPTION_VOLATILE 0x00000001
+#define REG_OPTION_CREATE_LINK 0x00000002
+#define REG_OPTION_BACKUP_RESTORE 0x00000004 /* FIXME */
+#define REG_OPTION_OPEN_LINK 0x00000008
+#define REG_LEGAL_OPTION (REG_OPTION_RESERVED| \
+ REG_OPTION_NON_VOLATILE| \
+ REG_OPTION_VOLATILE| \
+ REG_OPTION_CREATE_LINK| \
+ REG_OPTION_BACKUP_RESTORE| \
+ REG_OPTION_OPEN_LINK)
+
+
+#define REG_CREATED_NEW_KEY 0x00000001
+#define REG_OPENED_EXISTING_KEY 0x00000002
+
+/* For RegNotifyChangeKeyValue */
+#define REG_NOTIFY_CHANGE_NAME 0x1
+
+#define KEY_QUERY_VALUE 0x00000001
+#define KEY_SET_VALUE 0x00000002
+#define KEY_CREATE_SUB_KEY 0x00000004
+#define KEY_ENUMERATE_SUB_KEYS 0x00000008
+#define KEY_NOTIFY 0x00000010
+#define KEY_CREATE_LINK 0x00000020
+
+#define KEY_READ ((STANDARD_RIGHTS_READ| \
+ KEY_QUERY_VALUE| \
+ KEY_ENUMERATE_SUB_KEYS| \
+ KEY_NOTIFY) \
+ & (~SYNCHRONIZE) \
+ )
+#define KEY_WRITE ((STANDARD_RIGHTS_WRITE| \
+ KEY_SET_VALUE| \
+ KEY_CREATE_SUB_KEY) \
+ & (~SYNCHRONIZE) \
+ )
+#define KEY_EXECUTE ((KEY_READ) \
+ & (~SYNCHRONIZE)) \
+ )
+#define KEY_ALL_ACCESS ((STANDARD_RIGHTS_ALL| \
+ KEY_QUERY_VALUE| \
+ KEY_SET_VALUE| \
+ KEY_CREATE_SUB_KEY| \
+ KEY_ENUMERATE_SUB_KEYS| \
+ KEY_NOTIFY| \
+ KEY_CREATE_LINK) \
+ & (~SYNCHRONIZE) \
+ )
+/* ------------------------------ end registry ------------------------------ */
+
+
+#define RtlEqualMemory(Destination, Source, Length) (!memcmp((Destination),(Source),(Length)))
+#define RtlMoveMemory(Destination, Source, Length) memmove((Destination),(Source),(Length))
+#define RtlCopyMemory(Destination, Source, Length) memcpy((Destination),(Source),(Length))
+#define RtlFillMemory(Destination, Length, Fill) memset((Destination),(Fill),(Length))
+#define RtlZeroMemory(Destination, Length) memset((Destination),0,(Length))
+
+#include "poppack.h"
+
+#endif /* __WINE_WINNT_H */
diff --git a/src/libw32dll/wine/winreg.h b/src/libw32dll/wine/winreg.h
new file mode 100644
index 000000000..8c290b58f
--- /dev/null
+++ b/src/libw32dll/wine/winreg.h
@@ -0,0 +1,57 @@
+/*
+ * Win32 registry defines (see also winnt.h)
+ */
+#ifndef __WINE_WINREG_H
+#define __WINE_WINREG_H
+
+#include "winbase.h"
+#include "winnt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+/*
+#define SHELL_ERROR_SUCCESS 0L
+#define SHELL_ERROR_BADDB 1L
+#define SHELL_ERROR_BADKEY 2L
+#define SHELL_ERROR_CANTOPEN 3L
+#define SHELL_ERROR_CANTREAD 4L
+#define SHELL_ERROR_CANTWRITE 5L
+#define SHELL_ERROR_OUTOFMEMORY 6L
+#define SHELL_ERROR_INVALID_PARAMETER 7L
+#define SHELL_ERROR_ACCESS_DENIED 8L
+*/
+
+#define HKEY_CLASSES_ROOT ((HKEY) 0x80000000)
+#define HKEY_CURRENT_USER ((HKEY) 0x80000001)
+#define HKEY_LOCAL_MACHINE ((HKEY) 0x80000002)
+#define HKEY_USERS ((HKEY) 0x80000003)
+#define HKEY_PERFORMANCE_DATA ((HKEY) 0x80000004)
+#define HKEY_CURRENT_CONFIG ((HKEY) 0x80000005)
+#define HKEY_DYN_DATA ((HKEY) 0x80000006)
+
+/*
+ * registry provider structs
+ */
+typedef struct value_entA
+{ LPSTR ve_valuename;
+ DWORD ve_valuelen;
+ DWORD_PTR ve_valueptr;
+ DWORD ve_type;
+} VALENTA, *PVALENTA;
+
+typedef struct value_entW {
+ LPWSTR ve_valuename;
+ DWORD ve_valuelen;
+ DWORD_PTR ve_valueptr;
+ DWORD ve_type;
+} VALENTW, *PVALENTW;
+
+typedef ACCESS_MASK REGSAM;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* __WINE_WINREG_H */
diff --git a/src/libw32dll/wine/winuser.h b/src/libw32dll/wine/winuser.h
new file mode 100644
index 000000000..d74864ef7
--- /dev/null
+++ b/src/libw32dll/wine/winuser.h
@@ -0,0 +1,2929 @@
+#ifndef _WINUSER_
+#define _WINUSER_
+
+#ifndef RC_INVOKED
+#include <stdarg.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "pshpack1.h"
+
+/* flags for HIGHCONTRAST dwFlags field */
+#define HCF_HIGHCONTRASTON 0x00000001
+#define HCF_AVAILABLE 0x00000002
+#define HCF_HOTKEYACTIVE 0x00000004
+#define HCF_CONFIRMHOTKEY 0x00000008
+#define HCF_HOTKEYSOUND 0x00000010
+#define HCF_INDICATOR 0x00000020
+#define HCF_HOTKEYAVAILABLE 0x00000040
+
+typedef struct tagHIGHCONTRASTA
+{
+ UINT cbSize;
+ DWORD dwFlags;
+ LPSTR lpszDefaultScheme;
+} HIGHCONTRASTA, *LPHIGHCONTRASTA;
+
+typedef struct tagHIGHCONTRASTW
+{
+ UINT cbSize;
+ DWORD dwFlags;
+ LPWSTR lpszDefaultScheme;
+} HIGHCONTRASTW, *LPHIGHCONTRASTW;
+
+DECL_WINELIB_TYPE_AW(HIGHCONTRAST)
+DECL_WINELIB_TYPE_AW(LPHIGHCONTRAST)
+
+typedef struct
+{
+ UINT message;
+ UINT paramL;
+ UINT paramH;
+ DWORD time;
+ HWND hwnd;
+} EVENTMSG, *LPEVENTMSG;
+
+
+ /* Mouse hook structure */
+
+typedef struct
+{
+ POINT pt;
+ HWND hwnd;
+ UINT wHitTestCode;
+ DWORD dwExtraInfo;
+} MOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT, *LPMOUSEHOOKSTRUCT;
+
+
+ /* Hardware hook structure */
+
+typedef struct
+{
+ HWND hWnd;
+ UINT wMessage;
+ WPARAM wParam;
+ LPARAM lParam;
+} HARDWAREHOOKSTRUCT, *LPHARDWAREHOOKSTRUCT;
+
+
+ /* Debug hook structure */
+
+typedef struct
+{
+ DWORD idThread;
+ DWORD idThreadInstaller;
+ LPARAM lParam;
+ WPARAM wParam;
+ INT code;
+} DEBUGHOOKINFO, *LPDEBUGHOOKINFO;
+
+#define HKL_PREV 0
+#define HKL_NEXT 1
+
+#define KLF_ACTIVATE 0x00000001
+#define KLF_SUBSTITUTE_OK 0x00000002
+#define KLF_UNLOADPREVIOUS 0x00000004
+#define KLF_REORDER 0x00000008
+#define KLF_REPLACELANG 0x00000010
+#define KLF_NOTELLSHELL 0x00000080
+
+#define KL_NAMELENGTH 9
+
+ /***** Dialogs *****/
+#ifdef FSHIFT
+/* Gcc on Solaris has a version of this that we don't care about. */
+#undef FSHIFT
+#endif
+
+#define FVIRTKEY TRUE /* Assumed to be == TRUE */
+#define FNOINVERT 0x02
+#define FSHIFT 0x04
+#define FCONTROL 0x08
+#define FALT 0x10
+
+
+typedef struct tagANIMATIONINFO
+{
+ UINT cbSize;
+ INT iMinAnimate;
+} ANIMATIONINFO, *LPANIMATIONINFO;
+
+typedef struct tagNMHDR
+{
+ HWND hwndFrom;
+ UINT idFrom;
+ UINT code;
+} NMHDR, *LPNMHDR;
+
+typedef struct
+{
+ UINT cbSize;
+ INT iTabLength;
+ INT iLeftMargin;
+ INT iRightMargin;
+ UINT uiLengthDrawn;
+} DRAWTEXTPARAMS,*LPDRAWTEXTPARAMS;
+
+#define WM_USER 0x0400
+
+#define DT_EDITCONTROL 0x00002000
+#define DT_PATH_ELLIPSIS 0x00004000
+#define DT_END_ELLIPSIS 0x00008000
+#define DT_MODIFYSTRING 0x00010000
+#define DT_RTLREADING 0x00020000
+#define DT_WORD_ELLIPSIS 0x00040000
+
+typedef struct
+{
+ LPARAM lParam;
+ WPARAM16 wParam;
+ UINT16 message;
+ HWND16 hwnd;
+} CWPSTRUCT16, *LPCWPSTRUCT16;
+
+typedef struct
+{
+ LPARAM lParam;
+ WPARAM wParam;
+ UINT message;
+ HWND hwnd;
+} CWPSTRUCT, *LPCWPSTRUCT;
+
+
+
+typedef struct
+{
+ LRESULT lResult;
+ LPARAM lParam;
+ WPARAM16 wParam;
+ DWORD message;
+ HWND16 hwnd;
+} CWPRETSTRUCT16, *LPCWPRETSTRUCT16;
+
+typedef struct
+{
+ LRESULT lResult;
+ LPARAM lParam;
+ WPARAM wParam;
+ DWORD message;
+ HWND hwnd;
+} CWPRETSTRUCT, *LPCWPRETSTRUCT;
+
+typedef struct
+{
+ UINT length;
+ UINT flags;
+ UINT showCmd;
+ POINT ptMinPosition WINE_PACKED;
+ POINT ptMaxPosition WINE_PACKED;
+ RECT rcNormalPosition WINE_PACKED;
+} WINDOWPLACEMENT, *LPWINDOWPLACEMENT;
+
+
+ /* WINDOWPLACEMENT flags */
+#define WPF_SETMINPOSITION 0x0001
+#define WPF_RESTORETOMAXIMIZED 0x0002
+
+/***** Dialogs *****/
+
+ /* cbWndExtra bytes for dialog class */
+#define DLGWINDOWEXTRA 30
+
+/* Button control styles */
+#define BS_PUSHBUTTON 0x00000000L
+#define BS_DEFPUSHBUTTON 0x00000001L
+#define BS_CHECKBOX 0x00000002L
+#define BS_AUTOCHECKBOX 0x00000003L
+#define BS_RADIOBUTTON 0x00000004L
+#define BS_3STATE 0x00000005L
+#define BS_AUTO3STATE 0x00000006L
+#define BS_GROUPBOX 0x00000007L
+#define BS_USERBUTTON 0x00000008L
+#define BS_AUTORADIOBUTTON 0x00000009L
+#define BS_OWNERDRAW 0x0000000BL
+#define BS_LEFTTEXT 0x00000020L
+
+#define BS_TEXT 0x00000000L
+#define BS_ICON 0x00000040L
+#define BS_BITMAP 0x00000080L
+#define BS_LEFT 0x00000100L
+#define BS_RIGHT 0x00000200L
+#define BS_CENTER 0x00000300L
+#define BS_TOP 0x00000400L
+#define BS_BOTTOM 0x00000800L
+#define BS_VCENTER 0x00000C00L
+#define BS_PUSHLIKE 0x00001000L
+#define BS_MULTILINE 0x00002000L
+#define BS_NOTIFY 0x00004000L
+#define BS_FLAT 0x00008000L
+
+ /* Dialog styles */
+#define DS_ABSALIGN 0x0001
+#define DS_SYSMODAL 0x0002
+#define DS_3DLOOK 0x0004 /* win95 */
+#define DS_FIXEDSYS 0x0008 /* win95 */
+#define DS_NOFAILCREATE 0x0010 /* win95 */
+#define DS_LOCALEDIT 0x0020
+#define DS_SETFONT 0x0040
+#define DS_MODALFRAME 0x0080
+#define DS_NOIDLEMSG 0x0100
+#define DS_SETFOREGROUND 0x0200 /* win95 */
+#define DS_CONTROL 0x0400 /* win95 */
+#define DS_CENTER 0x0800 /* win95 */
+#define DS_CENTERMOUSE 0x1000 /* win95 */
+#define DS_CONTEXTHELP 0x2000 /* win95 */
+
+
+ /* Dialog messages */
+#define DM_GETDEFID (WM_USER+0)
+#define DM_SETDEFID (WM_USER+1)
+
+#define DC_HASDEFID 0x534b
+
+/* Owner draw control types */
+#define ODT_MENU 1
+#define ODT_LISTBOX 2
+#define ODT_COMBOBOX 3
+#define ODT_BUTTON 4
+#define ODT_STATIC 5
+
+/* Owner draw actions */
+#define ODA_DRAWENTIRE 0x0001
+#define ODA_SELECT 0x0002
+#define ODA_FOCUS 0x0004
+
+/* Owner draw state */
+#define ODS_SELECTED 0x0001
+#define ODS_GRAYED 0x0002
+#define ODS_DISABLED 0x0004
+#define ODS_CHECKED 0x0008
+#define ODS_FOCUS 0x0010
+#define ODS_COMBOBOXEDIT 0x1000
+#define ODS_HOTLIGHT 0x0040
+#define ODS_INACTIVE 0x0080
+
+/* Edit control styles */
+#define ES_LEFT 0x00000000
+#define ES_CENTER 0x00000001
+#define ES_RIGHT 0x00000002
+#define ES_MULTILINE 0x00000004
+#define ES_UPPERCASE 0x00000008
+#define ES_LOWERCASE 0x00000010
+#define ES_PASSWORD 0x00000020
+#define ES_AUTOVSCROLL 0x00000040
+#define ES_AUTOHSCROLL 0x00000080
+#define ES_NOHIDESEL 0x00000100
+#define ES_OEMCONVERT 0x00000400
+#define ES_READONLY 0x00000800
+#define ES_WANTRETURN 0x00001000
+#define ES_NUMBER 0x00002000
+
+/* OEM Resource Ordinal Numbers */
+#define OBM_CLOSED 32731
+#define OBM_RADIOCHECK 32732
+#define OBM_TRTYPE 32733
+#define OBM_LFARROWI 32734
+#define OBM_RGARROWI 32735
+#define OBM_DNARROWI 32736
+#define OBM_UPARROWI 32737
+#define OBM_COMBO 32738
+#define OBM_MNARROW 32739
+#define OBM_LFARROWD 32740
+#define OBM_RGARROWD 32741
+#define OBM_DNARROWD 32742
+#define OBM_UPARROWD 32743
+#define OBM_RESTORED 32744
+#define OBM_ZOOMD 32745
+#define OBM_REDUCED 32746
+#define OBM_RESTORE 32747
+#define OBM_ZOOM 32748
+#define OBM_REDUCE 32749
+#define OBM_LFARROW 32750
+#define OBM_RGARROW 32751
+#define OBM_DNARROW 32752
+#define OBM_UPARROW 32753
+#define OBM_CLOSE 32754
+#define OBM_OLD_RESTORE 32755
+#define OBM_OLD_ZOOM 32756
+#define OBM_OLD_REDUCE 32757
+#define OBM_BTNCORNERS 32758
+#define OBM_CHECKBOXES 32759
+#define OBM_CHECK 32760
+#define OBM_BTSIZE 32761
+#define OBM_OLD_LFARROW 32762
+#define OBM_OLD_RGARROW 32763
+#define OBM_OLD_DNARROW 32764
+#define OBM_OLD_UPARROW 32765
+#define OBM_SIZE 32766
+#define OBM_OLD_CLOSE 32767
+
+#define OCR_BUMMER 100
+#define OCR_DRAGOBJECT 101
+
+#define OCR_NORMAL 32512
+#define OCR_IBEAM 32513
+#define OCR_WAIT 32514
+#define OCR_CROSS 32515
+#define OCR_UP 32516
+#define OCR_SIZE 32640
+#define OCR_ICON 32641
+#define OCR_SIZENWSE 32642
+#define OCR_SIZENESW 32643
+#define OCR_SIZEWE 32644
+#define OCR_SIZENS 32645
+#define OCR_SIZEALL 32646
+#define OCR_ICOCUR 32647
+#define OCR_NO 32648
+#define OCR_APPSTARTING 32650
+#define OCR_HELP 32651 /* only defined in wine */
+
+#define OIC_SAMPLE 32512
+#define OIC_HAND 32513
+#define OIC_QUES 32514
+#define OIC_BANG 32515
+#define OIC_NOTE 32516
+#define OIC_PORTRAIT 32517
+#define OIC_LANDSCAPE 32518
+#define OIC_WINEICON 32519
+#define OIC_FOLDER 32520
+#define OIC_FOLDER2 32521
+#define OIC_FLOPPY 32522
+#define OIC_CDROM 32523
+#define OIC_HDISK 32524
+#define OIC_NETWORK 32525
+
+#define COLOR_SCROLLBAR 0
+#define COLOR_BACKGROUND 1
+#define COLOR_ACTIVECAPTION 2
+#define COLOR_INACTIVECAPTION 3
+#define COLOR_MENU 4
+#define COLOR_WINDOW 5
+#define COLOR_WINDOWFRAME 6
+#define COLOR_MENUTEXT 7
+#define COLOR_WINDOWTEXT 8
+#define COLOR_CAPTIONTEXT 9
+#define COLOR_ACTIVEBORDER 10
+#define COLOR_INACTIVEBORDER 11
+#define COLOR_APPWORKSPACE 12
+#define COLOR_HIGHLIGHT 13
+#define COLOR_HIGHLIGHTTEXT 14
+#define COLOR_BTNFACE 15
+#define COLOR_BTNSHADOW 16
+#define COLOR_GRAYTEXT 17
+#define COLOR_BTNTEXT 18
+#define COLOR_INACTIVECAPTIONTEXT 19
+#define COLOR_BTNHIGHLIGHT 20
+/* win95 colors */
+#define COLOR_3DDKSHADOW 21
+#define COLOR_3DLIGHT 22
+#define COLOR_INFOTEXT 23
+#define COLOR_INFOBK 24
+#define COLOR_DESKTOP COLOR_BACKGROUND
+#define COLOR_3DFACE COLOR_BTNFACE
+#define COLOR_3DSHADOW COLOR_BTNSHADOW
+#define COLOR_3DHIGHLIGHT COLOR_BTNHIGHLIGHT
+#define COLOR_3DHILIGHT COLOR_BTNHIGHLIGHT
+#define COLOR_BTNHILIGHT COLOR_BTNHIGHLIGHT
+/* win98 colors */
+#define COLOR_ALTERNATEBTNFACE 25 /* undocumented, constant's name unknown */
+#define COLOR_HOTLIGHT 26
+#define COLOR_GRADIENTACTIVECAPTION 27
+#define COLOR_GRADIENTINACTIVECAPTION 28
+
+ /* WM_CTLCOLOR values */
+#define CTLCOLOR_MSGBOX 0
+#define CTLCOLOR_EDIT 1
+#define CTLCOLOR_LISTBOX 2
+#define CTLCOLOR_BTN 3
+#define CTLCOLOR_DLG 4
+#define CTLCOLOR_SCROLLBAR 5
+#define CTLCOLOR_STATIC 6
+
+/* Edit control messages */
+#define EM_GETSEL 0x00b0
+#define EM_SETSEL 0x00b1
+#define EM_GETRECT 0x00b2
+#define EM_SETRECT 0x00b3
+#define EM_SETRECTNP 0x00b4
+#define EM_SCROLL 0x00b5
+#define EM_LINESCROLL 0x00b6
+#define EM_SCROLLCARET 0x00b7
+#define EM_GETMODIFY 0x00b8
+#define EM_SETMODIFY 0x00b9
+#define EM_GETLINECOUNT 0x00ba
+#define EM_LINEINDEX 0x00bb
+#define EM_SETHANDLE 0x00bc
+#define EM_GETHANDLE 0x00bd
+#define EM_GETTHUMB 0x00be
+/* FIXME : missing from specs 0x00bf and 0x00c0 */
+#define EM_LINELENGTH 0x00c1
+#define EM_REPLACESEL 0x00c2
+/* FIXME : missing from specs 0x00c3 */
+#define EM_GETLINE 0x00c4
+#define EM_LIMITTEXT 0x00c5
+#define EM_CANUNDO 0x00c6
+#define EM_UNDO 0x00c7
+#define EM_FMTLINES 0x00c8
+#define EM_LINEFROMCHAR 0x00c9
+/* FIXME : missing from specs 0x00ca */
+#define EM_SETTABSTOPS 0x00cb
+#define EM_SETPASSWORDCHAR 0x00cc
+#define EM_EMPTYUNDOBUFFER 0x00cd
+#define EM_GETFIRSTVISIBLELINE 0x00ce
+#define EM_SETREADONLY 0x00cf
+#define EM_SETWORDBREAKPROC 0x00d0
+#define EM_GETWORDBREAKPROC 0x00d1
+#define EM_GETPASSWORDCHAR 0x00d2
+#define EM_SETMARGINS 0x00d3
+#define EM_GETMARGINS 0x00d4
+#define EM_GETLIMITTEXT 0x00d5
+#define EM_POSFROMCHAR 0x00d6
+#define EM_CHARFROMPOS 0x00d7
+/* a name change since win95 */
+#define EM_SETLIMITTEXT EM_LIMITTEXT
+
+/* EDITWORDBREAKPROC code values */
+#define WB_LEFT 0
+#define WB_RIGHT 1
+#define WB_ISDELIMITER 2
+
+/* Edit control notification codes */
+#define EN_SETFOCUS 0x0100
+#define EN_KILLFOCUS 0x0200
+#define EN_CHANGE 0x0300
+#define EN_UPDATE 0x0400
+#define EN_ERRSPACE 0x0500
+#define EN_MAXTEXT 0x0501
+#define EN_HSCROLL 0x0601
+#define EN_VSCROLL 0x0602
+
+/* New since win95 : EM_SETMARGIN parameters */
+#define EC_LEFTMARGIN 0x0001
+#define EC_RIGHTMARGIN 0x0002
+#define EC_USEFONTINFO 0xffff
+
+
+/* Messages */
+
+ /* WM_GETDLGCODE values */
+
+
+#define WM_NULL 0x0000
+#define WM_CREATE 0x0001
+#define WM_DESTROY 0x0002
+#define WM_MOVE 0x0003
+#define WM_SIZEWAIT 0x0004
+#define WM_SIZE 0x0005
+#define WM_ACTIVATE 0x0006
+#define WM_SETFOCUS 0x0007
+#define WM_KILLFOCUS 0x0008
+#define WM_SETVISIBLE 0x0009
+#define WM_ENABLE 0x000a
+#define WM_SETREDRAW 0x000b
+#define WM_SETTEXT 0x000c
+#define WM_GETTEXT 0x000d
+#define WM_GETTEXTLENGTH 0x000e
+#define WM_PAINT 0x000f
+#define WM_CLOSE 0x0010
+#define WM_QUERYENDSESSION 0x0011
+#define WM_QUIT 0x0012
+#define WM_QUERYOPEN 0x0013
+#define WM_ERASEBKGND 0x0014
+#define WM_SYSCOLORCHANGE 0x0015
+#define WM_ENDSESSION 0x0016
+#define WM_SYSTEMERROR 0x0017
+#define WM_SHOWWINDOW 0x0018
+#define WM_CTLCOLOR 0x0019
+#define WM_WININICHANGE 0x001a
+#define WM_SETTINGCHANGE WM_WININICHANGE
+#define WM_DEVMODECHANGE 0x001b
+#define WM_ACTIVATEAPP 0x001c
+#define WM_FONTCHANGE 0x001d
+#define WM_TIMECHANGE 0x001e
+#define WM_CANCELMODE 0x001f
+#define WM_SETCURSOR 0x0020
+#define WM_MOUSEACTIVATE 0x0021
+#define WM_CHILDACTIVATE 0x0022
+#define WM_QUEUESYNC 0x0023
+#define WM_GETMINMAXINFO 0x0024
+
+#define WM_PAINTICON 0x0026
+#define WM_ICONERASEBKGND 0x0027
+#define WM_NEXTDLGCTL 0x0028
+#define WM_ALTTABACTIVE 0x0029
+#define WM_SPOOLERSTATUS 0x002a
+#define WM_DRAWITEM 0x002b
+#define WM_MEASUREITEM 0x002c
+#define WM_DELETEITEM 0x002d
+#define WM_VKEYTOITEM 0x002e
+#define WM_CHARTOITEM 0x002f
+#define WM_SETFONT 0x0030
+#define WM_GETFONT 0x0031
+#define WM_SETHOTKEY 0x0032
+#define WM_GETHOTKEY 0x0033
+#define WM_FILESYSCHANGE 0x0034
+#define WM_ISACTIVEICON 0x0035
+#define WM_QUERYPARKICON 0x0036
+#define WM_QUERYDRAGICON 0x0037
+#define WM_QUERYSAVESTATE 0x0038
+#define WM_COMPAREITEM 0x0039
+#define WM_TESTING 0x003a
+
+#define WM_OTHERWINDOWCREATED 0x003c
+#define WM_OTHERWINDOWDESTROYED 0x003d
+#define WM_ACTIVATESHELLWINDOW 0x003e
+
+#define WM_COMPACTING 0x0041
+
+#define WM_COMMNOTIFY 0x0044
+#define WM_WINDOWPOSCHANGING 0x0046
+#define WM_WINDOWPOSCHANGED 0x0047
+#define WM_POWER 0x0048
+
+ /* Win32 4.0 messages */
+#define WM_COPYDATA 0x004a
+#define WM_CANCELJOURNAL 0x004b
+#define WM_NOTIFY 0x004e
+#define WM_HELP 0x0053
+#define WM_NOTIFYFORMAT 0x0055
+
+#define WM_CONTEXTMENU 0x007b
+#define WM_STYLECHANGING 0x007c
+#define WM_STYLECHANGED 0x007d
+#define WM_DISPLAYCHANGE 0x007e
+#define WM_GETICON 0x007f
+#define WM_SETICON 0x0080
+
+ /* Non-client system messages */
+#define WM_NCCREATE 0x0081
+#define WM_NCDESTROY 0x0082
+#define WM_NCCALCSIZE 0x0083
+#define WM_NCHITTEST 0x0084
+#define WM_NCPAINT 0x0085
+#define WM_NCACTIVATE 0x0086
+
+#define WM_GETDLGCODE 0x0087
+#define WM_SYNCPAINT 0x0088
+#define WM_SYNCTASK 0x0089
+
+ /* Non-client mouse messages */
+#define WM_NCMOUSEMOVE 0x00a0
+#define WM_NCLBUTTONDOWN 0x00a1
+#define WM_NCLBUTTONUP 0x00a2
+#define WM_NCLBUTTONDBLCLK 0x00a3
+#define WM_NCRBUTTONDOWN 0x00a4
+#define WM_NCRBUTTONUP 0x00a5
+#define WM_NCRBUTTONDBLCLK 0x00a6
+#define WM_NCMBUTTONDOWN 0x00a7
+#define WM_NCMBUTTONUP 0x00a8
+#define WM_NCMBUTTONDBLCLK 0x00a9
+
+ /* Keyboard messages */
+#define WM_KEYDOWN 0x0100
+#define WM_KEYUP 0x0101
+#define WM_CHAR 0x0102
+#define WM_DEADCHAR 0x0103
+#define WM_SYSKEYDOWN 0x0104
+#define WM_SYSKEYUP 0x0105
+#define WM_SYSCHAR 0x0106
+#define WM_SYSDEADCHAR 0x0107
+#define WM_KEYFIRST WM_KEYDOWN
+#define WM_KEYLAST 0x0108
+
+/* Win32 4.0 messages for IME */
+#define WM_IME_STARTCOMPOSITION 0x010d
+#define WM_IME_ENDCOMPOSITION 0x010e
+#define WM_IME_COMPOSITION 0x010f
+#define WM_IME_KEYLAST 0x010f
+
+#define WM_INITDIALOG 0x0110
+#define WM_COMMAND 0x0111
+#define WM_SYSCOMMAND 0x0112
+#define WM_TIMER 0x0113
+#define WM_SYSTIMER 0x0118
+
+ /* scroll messages */
+#define WM_HSCROLL 0x0114
+#define WM_VSCROLL 0x0115
+
+/* Menu messages */
+#define WM_INITMENU 0x0116
+#define WM_INITMENUPOPUP 0x0117
+
+#define WM_MENUSELECT 0x011F
+#define WM_MENUCHAR 0x0120
+#define WM_ENTERIDLE 0x0121
+
+#define WM_LBTRACKPOINT 0x0131
+
+ /* Win32 CTLCOLOR messages */
+#define WM_CTLCOLORMSGBOX 0x0132
+#define WM_CTLCOLOREDIT 0x0133
+#define WM_CTLCOLORLISTBOX 0x0134
+#define WM_CTLCOLORBTN 0x0135
+#define WM_CTLCOLORDLG 0x0136
+#define WM_CTLCOLORSCROLLBAR 0x0137
+#define WM_CTLCOLORSTATIC 0x0138
+
+ /* Mouse messages */
+#define WM_MOUSEMOVE 0x0200
+#define WM_LBUTTONDOWN 0x0201
+#define WM_LBUTTONUP 0x0202
+#define WM_LBUTTONDBLCLK 0x0203
+#define WM_RBUTTONDOWN 0x0204
+#define WM_RBUTTONUP 0x0205
+#define WM_RBUTTONDBLCLK 0x0206
+#define WM_MBUTTONDOWN 0x0207
+#define WM_MBUTTONUP 0x0208
+#define WM_MBUTTONDBLCLK 0x0209
+#define WM_MOUSEWHEEL 0x020A
+#define WM_MOUSEFIRST WM_MOUSEMOVE
+
+
+#define WM_MOUSELAST WM_MOUSEWHEEL
+
+#define WHEEL_DELTA 120
+#define WHEEL_PAGESCROLL (UINT_MAX)
+#define WM_PARENTNOTIFY 0x0210
+#define WM_ENTERMENULOOP 0x0211
+#define WM_EXITMENULOOP 0x0212
+#define WM_NEXTMENU 0x0213
+
+ /* Win32 4.0 messages */
+#define WM_SIZING 0x0214
+#define WM_CAPTURECHANGED 0x0215
+#define WM_MOVING 0x0216
+
+ /* MDI messages */
+#define WM_MDICREATE 0x0220
+#define WM_MDIDESTROY 0x0221
+#define WM_MDIACTIVATE 0x0222
+#define WM_MDIRESTORE 0x0223
+#define WM_MDINEXT 0x0224
+#define WM_MDIMAXIMIZE 0x0225
+#define WM_MDITILE 0x0226
+#define WM_MDICASCADE 0x0227
+#define WM_MDIICONARRANGE 0x0228
+#define WM_MDIGETACTIVE 0x0229
+#define WM_MDIREFRESHMENU 0x0234
+
+ /* D&D messages */
+#define WM_DROPOBJECT 0x022A
+#define WM_QUERYDROPOBJECT 0x022B
+#define WM_BEGINDRAG 0x022C
+#define WM_DRAGLOOP 0x022D
+#define WM_DRAGSELECT 0x022E
+#define WM_DRAGMOVE 0x022F
+#define WM_MDISETMENU 0x0230
+
+#define WM_ENTERSIZEMOVE 0x0231
+#define WM_EXITSIZEMOVE 0x0232
+#define WM_DROPFILES 0x0233
+
+
+/* Win32 4.0 messages for IME */
+#define WM_IME_SETCONTEXT 0x0281
+#define WM_IME_NOTIFY 0x0282
+#define WM_IME_CONTROL 0x0283
+#define WM_IME_COMPOSITIONFULL 0x0284
+#define WM_IME_SELECT 0x0285
+#define WM_IME_CHAR 0x0286
+/* Win32 5.0 messages for IME */
+#define WM_IME_REQUEST 0x0288
+
+/* Win32 4.0 messages for IME */
+#define WM_IME_KEYDOWN 0x0290
+#define WM_IME_KEYUP 0x0291
+
+/* Clipboard command messages */
+#define WM_CUT 0x0300
+#define WM_COPY 0x0301
+#define WM_PASTE 0x0302
+#define WM_CLEAR 0x0303
+#define WM_UNDO 0x0304
+
+/* Clipboard owner messages */
+#define WM_RENDERFORMAT 0x0305
+#define WM_RENDERALLFORMATS 0x0306
+#define WM_DESTROYCLIPBOARD 0x0307
+
+/* Clipboard viewer messages */
+#define WM_DRAWCLIPBOARD 0x0308
+#define WM_PAINTCLIPBOARD 0x0309
+#define WM_VSCROLLCLIPBOARD 0x030A
+#define WM_SIZECLIPBOARD 0x030B
+#define WM_ASKCBFORMATNAME 0x030C
+#define WM_CHANGECBCHAIN 0x030D
+#define WM_HSCROLLCLIPBOARD 0x030E
+
+#define WM_QUERYNEWPALETTE 0x030F
+#define WM_PALETTEISCHANGING 0x0310
+#define WM_PALETTECHANGED 0x0311
+#define WM_HOTKEY 0x0312
+
+#define WM_PRINT 0x0317
+#define WM_PRINTCLIENT 0x0318
+
+ /* FIXME: This does not belong to any libwine interface header */
+ /* MFC messages [360-38f] */
+
+#define WM_QUERYAFXWNDPROC 0x0360
+#define WM_SIZEPARENT 0x0361
+#define WM_SETMESSAGESTRING 0x0362
+#define WM_IDLEUPDATECMDUI 0x0363
+#define WM_INITIALUPDATE 0x0364
+#define WM_COMMANDHELP 0x0365
+#define WM_HELPHITTEST 0x0366
+#define WM_EXITHELPMODE 0x0367
+#define WM_RECALCPARENT 0x0368
+#define WM_SIZECHILD 0x0369
+#define WM_KICKIDLE 0x036A
+#define WM_QUERYCENTERWND 0x036B
+#define WM_DISABLEMODAL 0x036C
+#define WM_FLOATSTATUS 0x036D
+#define WM_ACTIVATETOPLEVEL 0x036E
+#define WM_QUERY3DCONTROLS 0x036F
+#define WM_SOCKET_NOTIFY 0x0373
+#define WM_SOCKET_DEAD 0x0374
+#define WM_POPMESSAGESTRING 0x0375
+#define WM_OCC_LOADFROMSTREAM 0x0376
+#define WM_OCC_LOADFROMSTORAGE 0x0377
+#define WM_OCC_INITNEW 0x0378
+#define WM_OCC_LOADFROMSTREAM_EX 0x037A
+#define WM_OCC_LOADFROMSTORAGE_EX 0x037B
+#define WM_QUEUE_SENTINEL 0x0379
+
+#define WM_PENWINFIRST 0x0380
+#define WM_PENWINLAST 0x038F
+
+/* end of MFC messages */
+
+/* FIXME: The following two lines do not belong to any libwine interface header */
+#define WM_COALESCE_FIRST 0x0390
+#define WM_COALESCE_LAST 0x039F
+
+#define WM_APP 0x8000
+
+
+#define DLGC_WANTARROWS 0x0001
+#define DLGC_WANTTAB 0x0002
+#define DLGC_WANTALLKEYS 0x0004
+#define DLGC_WANTMESSAGE 0x0004
+#define DLGC_HASSETSEL 0x0008
+#define DLGC_DEFPUSHBUTTON 0x0010
+#define DLGC_UNDEFPUSHBUTTON 0x0020
+#define DLGC_RADIOBUTTON 0x0040
+#define DLGC_WANTCHARS 0x0080
+#define DLGC_STATIC 0x0100
+#define DLGC_BUTTON 0x2000
+
+/* Standard dialog button IDs */
+#define IDOK 1
+#define IDCANCEL 2
+#define IDABORT 3
+#define IDRETRY 4
+#define IDIGNORE 5
+#define IDYES 6
+#define IDNO 7
+#define IDCLOSE 8
+#define IDHELP 9
+
+/****** Window classes ******/
+
+typedef struct tagCREATESTRUCTA
+{
+ LPVOID lpCreateParams;
+ HINSTANCE hInstance;
+ HMENU hMenu;
+ HWND hwndParent;
+ INT cy;
+ INT cx;
+ INT y;
+ INT x;
+ LONG style;
+ LPCSTR lpszName;
+ LPCSTR lpszClass;
+ DWORD dwExStyle;
+} CREATESTRUCTA, *LPCREATESTRUCTA;
+
+typedef struct
+{
+ LPVOID lpCreateParams;
+ HINSTANCE hInstance;
+ HMENU hMenu;
+ HWND hwndParent;
+ INT cy;
+ INT cx;
+ INT y;
+ INT x;
+ LONG style;
+ LPCWSTR lpszName;
+ LPCWSTR lpszClass;
+ DWORD dwExStyle;
+} CREATESTRUCTW, *LPCREATESTRUCTW;
+
+DECL_WINELIB_TYPE_AW(CREATESTRUCT)
+DECL_WINELIB_TYPE_AW(LPCREATESTRUCT)
+
+typedef struct
+{
+ HDC hdc;
+ WIN_BOOL fErase;
+ RECT rcPaint;
+ WIN_BOOL fRestore;
+ WIN_BOOL fIncUpdate;
+ BYTE rgbReserved[32];
+} PAINTSTRUCT, *PPAINTSTRUCT, *LPPAINTSTRUCT;
+
+typedef struct
+{
+ HMENU hWindowMenu;
+ UINT idFirstChild;
+} CLIENTCREATESTRUCT, *LPCLIENTCREATESTRUCT;
+
+
+typedef struct
+{
+ LPCSTR szClass;
+ LPCSTR szTitle;
+ HINSTANCE hOwner;
+ INT x;
+ INT y;
+ INT cx;
+ INT cy;
+ DWORD style;
+ LPARAM lParam;
+} MDICREATESTRUCTA, *LPMDICREATESTRUCTA;
+
+typedef struct
+{
+ LPCWSTR szClass;
+ LPCWSTR szTitle;
+ HINSTANCE hOwner;
+ INT x;
+ INT y;
+ INT cx;
+ INT cy;
+ DWORD style;
+ LPARAM lParam;
+} MDICREATESTRUCTW, *LPMDICREATESTRUCTW;
+
+DECL_WINELIB_TYPE_AW(MDICREATESTRUCT)
+DECL_WINELIB_TYPE_AW(LPMDICREATESTRUCT)
+
+#define MDITILE_VERTICAL 0x0000
+#define MDITILE_HORIZONTAL 0x0001
+#define MDITILE_SKIPDISABLED 0x0002
+
+#define MDIS_ALLCHILDSTYLES 0x0001
+
+typedef struct {
+ DWORD styleOld;
+ DWORD styleNew;
+} STYLESTRUCT, *LPSTYLESTRUCT;
+
+ /* Offsets for GetWindowLong() and GetWindowWord() */
+#define GWL_USERDATA (-21)
+#define GWL_EXSTYLE (-20)
+#define GWL_STYLE (-16)
+#define GWW_ID (-12)
+#define GWL_ID GWW_ID
+#define GWW_HWNDPARENT (-8)
+#define GWL_HWNDPARENT GWW_HWNDPARENT
+#define GWW_HINSTANCE (-6)
+#define GWL_HINSTANCE GWW_HINSTANCE
+#define GWL_WNDPROC (-4)
+#define DWL_MSGRESULT 0
+#define DWL_DLGPROC 4
+#define DWL_USER 8
+
+ /* GetWindow() constants */
+#define GW_HWNDFIRST 0
+#define GW_HWNDLAST 1
+#define GW_HWNDNEXT 2
+#define GW_HWNDPREV 3
+#define GW_OWNER 4
+#define GW_CHILD 5
+
+ /* WM_GETMINMAXINFO struct */
+typedef struct
+{
+ POINT ptReserved;
+ POINT ptMaxSize;
+ POINT ptMaxPosition;
+ POINT ptMinTrackSize;
+ POINT ptMaxTrackSize;
+} MINMAXINFO, *PMINMAXINFO, *LPMINMAXINFO;
+
+
+ /* RedrawWindow() flags */
+#define RDW_INVALIDATE 0x0001
+#define RDW_INTERNALPAINT 0x0002
+#define RDW_ERASE 0x0004
+#define RDW_VALIDATE 0x0008
+#define RDW_NOINTERNALPAINT 0x0010
+#define RDW_NOERASE 0x0020
+#define RDW_NOCHILDREN 0x0040
+#define RDW_ALLCHILDREN 0x0080
+#define RDW_UPDATENOW 0x0100
+#define RDW_ERASENOW 0x0200
+#define RDW_FRAME 0x0400
+#define RDW_NOFRAME 0x0800
+
+/* debug flags */
+#define DBGFILL_ALLOC 0xfd
+#define DBGFILL_FREE 0xfb
+#define DBGFILL_BUFFER 0xf9
+#define DBGFILL_STACK 0xf7
+
+ /* WM_WINDOWPOSCHANGING/CHANGED struct */
+typedef struct tagWINDOWPOS
+{
+ HWND hwnd;
+ HWND hwndInsertAfter;
+ INT x;
+ INT y;
+ INT cx;
+ INT cy;
+ UINT flags;
+} WINDOWPOS, *PWINDOWPOS, *LPWINDOWPOS;
+
+
+ /* WM_MOUSEACTIVATE return values */
+#define MA_ACTIVATE 1
+#define MA_ACTIVATEANDEAT 2
+#define MA_NOACTIVATE 3
+#define MA_NOACTIVATEANDEAT 4
+
+ /* WM_ACTIVATE wParam values */
+#define WA_INACTIVE 0
+#define WA_ACTIVE 1
+#define WA_CLICKACTIVE 2
+
+/* WM_GETICON/WM_SETICON params values */
+#define ICON_SMALL 0
+#define ICON_BIG 1
+
+ /* WM_NCCALCSIZE parameter structure */
+typedef struct
+{
+ RECT rgrc[3];
+ WINDOWPOS *lppos;
+} NCCALCSIZE_PARAMS, *LPNCCALCSIZE_PARAMS;
+
+
+ /* WM_NCCALCSIZE return flags */
+#define WVR_ALIGNTOP 0x0010
+#define WVR_ALIGNLEFT 0x0020
+#define WVR_ALIGNBOTTOM 0x0040
+#define WVR_ALIGNRIGHT 0x0080
+#define WVR_HREDRAW 0x0100
+#define WVR_VREDRAW 0x0200
+#define WVR_REDRAW (WVR_HREDRAW | WVR_VREDRAW)
+#define WVR_VALIDRECTS 0x0400
+
+ /* WM_NCHITTEST return codes */
+#define HTERROR (-2)
+#define HTTRANSPARENT (-1)
+#define HTNOWHERE 0
+#define HTCLIENT 1
+#define HTCAPTION 2
+#define HTSYSMENU 3
+#define HTSIZE 4
+#define HTMENU 5
+#define HTHSCROLL 6
+#define HTVSCROLL 7
+#define HTMINBUTTON 8
+#define HTMAXBUTTON 9
+#define HTLEFT 10
+#define HTRIGHT 11
+#define HTTOP 12
+#define HTTOPLEFT 13
+#define HTTOPRIGHT 14
+#define HTBOTTOM 15
+#define HTBOTTOMLEFT 16
+#define HTBOTTOMRIGHT 17
+#define HTBORDER 18
+#define HTGROWBOX HTSIZE
+#define HTREDUCE HTMINBUTTON
+#define HTZOOM HTMAXBUTTON
+#define HTOBJECT 19
+#define HTCLOSE 20
+#define HTHELP 21
+#define HTSIZEFIRST HTLEFT
+#define HTSIZELAST HTBOTTOMRIGHT
+
+ /* WM_SYSCOMMAND parameters */
+#ifdef SC_SIZE /* at least HP-UX: already defined in /usr/include/sys/signal.h */
+#undef SC_SIZE
+#endif
+#define SC_SIZE 0xf000
+#define SC_MOVE 0xf010
+#define SC_MINIMIZE 0xf020
+#define SC_MAXIMIZE 0xf030
+#define SC_NEXTWINDOW 0xf040
+#define SC_PREVWINDOW 0xf050
+#define SC_CLOSE 0xf060
+#define SC_VSCROLL 0xf070
+#define SC_HSCROLL 0xf080
+#define SC_MOUSEMENU 0xf090
+#define SC_KEYMENU 0xf100
+#define SC_ARRANGE 0xf110
+#define SC_RESTORE 0xf120
+#define SC_TASKLIST 0xf130
+#define SC_SCREENSAVE 0xf140
+#define SC_HOTKEY 0xf150
+
+#define CS_VREDRAW 0x0001
+#define CS_HREDRAW 0x0002
+#define CS_KEYCVTWINDOW 0x0004
+#define CS_DBLCLKS 0x0008
+#define CS_OWNDC 0x0020
+#define CS_CLASSDC 0x0040
+#define CS_PARENTDC 0x0080
+#define CS_NOKEYCVT 0x0100
+#define CS_NOCLOSE 0x0200
+#define CS_SAVEBITS 0x0800
+#define CS_BYTEALIGNCLIENT 0x1000
+#define CS_BYTEALIGNWINDOW 0x2000
+#define CS_GLOBALCLASS 0x4000
+#define CS_IME 0x00010000
+
+#define PRF_CHECKVISIBLE 0x00000001L
+#define PRF_NONCLIENT 0x00000002L
+#define PRF_CLIENT 0x00000004L
+#define PRF_ERASEBKGND 0x00000008L
+#define PRF_CHILDREN 0x00000010L
+#define PRF_OWNED 0x00000020L
+
+ /* Offsets for GetClassLong() and GetClassWord() */
+#define GCL_MENUNAME (-8)
+#define GCW_HBRBACKGROUND (-10)
+#define GCL_HBRBACKGROUND GCW_HBRBACKGROUND
+#define GCW_HCURSOR (-12)
+#define GCL_HCURSOR GCW_HCURSOR
+#define GCW_HICON (-14)
+#define GCL_HICON GCW_HICON
+#define GCW_HMODULE (-16)
+#define GCL_HMODULE GCW_HMODULE
+#define GCW_CBWNDEXTRA (-18)
+#define GCL_CBWNDEXTRA GCW_CBWNDEXTRA
+#define GCW_CBCLSEXTRA (-20)
+#define GCL_CBCLSEXTRA GCW_CBCLSEXTRA
+#define GCL_WNDPROC (-24)
+#define GCW_STYLE (-26)
+#define GCL_STYLE GCW_STYLE
+#define GCW_ATOM (-32)
+#define GCW_HICONSM (-34)
+#define GCL_HICONSM GCW_HICONSM
+
+
+/***** Window hooks *****/
+
+ /* Hook values */
+#define WH_MIN (-1)
+#define WH_MSGFILTER (-1)
+#define WH_JOURNALRECORD 0
+#define WH_JOURNALPLAYBACK 1
+#define WH_KEYBOARD 2
+#define WH_GETMESSAGE 3
+#define WH_CALLWNDPROC 4
+#define WH_CBT 5
+#define WH_SYSMSGFILTER 6
+#define WH_MOUSE 7
+#define WH_HARDWARE 8
+#define WH_DEBUG 9
+#define WH_SHELL 10
+#define WH_FOREGROUNDIDLE 11
+#define WH_CALLWNDPROCRET 12
+#define WH_MAX 12
+
+#define WH_MINHOOK WH_MIN
+#define WH_MAXHOOK WH_MAX
+#define WH_NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1)
+
+ /* Hook action codes */
+#define HC_ACTION 0
+#define HC_GETNEXT 1
+#define HC_SKIP 2
+#define HC_NOREMOVE 3
+#define HC_NOREM HC_NOREMOVE
+#define HC_SYSMODALON 4
+#define HC_SYSMODALOFF 5
+
+ /* CallMsgFilter() values */
+#define MSGF_DIALOGBOX 0
+#define MSGF_MESSAGEBOX 1
+#define MSGF_MENU 2
+#define MSGF_MOVE 3
+#define MSGF_SIZE 4
+#define MSGF_SCROLLBAR 5
+#define MSGF_NEXTWINDOW 6
+#define MSGF_MAINLOOP 8
+#define MSGF_USER 4096
+
+typedef struct
+{
+ UINT style;
+ WNDPROC lpfnWndProc;
+ INT cbClsExtra;
+ INT cbWndExtra;
+ HINSTANCE hInstance;
+ HICON hIcon;
+ HCURSOR hCursor;
+ HBRUSH hbrBackground;
+ LPCSTR lpszMenuName;
+ LPCSTR lpszClassName;
+} WNDCLASSA, *LPWNDCLASSA;
+
+typedef struct
+{
+ UINT style;
+ WNDPROC lpfnWndProc;
+ INT cbClsExtra;
+ INT cbWndExtra;
+ HINSTANCE hInstance;
+ HICON hIcon;
+ HCURSOR hCursor;
+ HBRUSH hbrBackground;
+ LPCWSTR lpszMenuName;
+ LPCWSTR lpszClassName;
+} WNDCLASSW, *LPWNDCLASSW;
+
+DECL_WINELIB_TYPE_AW(WNDCLASS)
+DECL_WINELIB_TYPE_AW(LPWNDCLASS)
+
+typedef struct {
+ DWORD dwData;
+ DWORD cbData;
+ LPVOID lpData;
+} COPYDATASTRUCT, *PCOPYDATASTRUCT, *LPCOPYDATASTRUCT;
+
+typedef struct {
+ HMENU hmenuIn;
+ HMENU hmenuNext;
+ HWND hwndNext;
+} MDINEXTMENU, *PMDINEXTMENU, *LPMDINEXTMENU;
+
+/* WinHelp internal structure */
+typedef struct {
+ WORD size;
+ WORD command;
+ LONG data;
+ LONG reserved;
+ WORD ofsFilename;
+ WORD ofsData;
+} WINHELP,*LPWINHELP;
+
+typedef struct
+{
+ UINT16 mkSize;
+ BYTE mkKeyList;
+ BYTE szKeyphrase[1];
+} MULTIKEYHELP, *LPMULTIKEYHELP;
+
+typedef struct {
+ WORD wStructSize;
+ WORD x;
+ WORD y;
+ WORD dx;
+ WORD dy;
+ WORD wMax;
+ char rgchMember[2];
+} HELPWININFO, *LPHELPWININFO;
+
+#define HELP_CONTEXT 0x0001
+#define HELP_QUIT 0x0002
+#define HELP_INDEX 0x0003
+#define HELP_CONTENTS 0x0003
+#define HELP_HELPONHELP 0x0004
+#define HELP_SETINDEX 0x0005
+#define HELP_SETCONTENTS 0x0005
+#define HELP_CONTEXTPOPUP 0x0008
+#define HELP_FORCEFILE 0x0009
+#define HELP_KEY 0x0101
+#define HELP_COMMAND 0x0102
+#define HELP_PARTIALKEY 0x0105
+#define HELP_MULTIKEY 0x0201
+#define HELP_SETWINPOS 0x0203
+#define HELP_CONTEXTMENU 0x000a
+#define HELP_FINDER 0x000b
+#define HELP_WM_HELP 0x000c
+#define HELP_SETPOPUP_POS 0x000d
+
+#define HELP_TCARD 0x8000
+#define HELP_TCARD_DATA 0x0010
+#define HELP_TCARD_OTHER_CALLER 0x0011
+
+
+ /* ChangeDisplaySettings return codes */
+
+#define DISP_CHANGE_SUCCESSFUL 0
+#define DISP_CHANGE_RESTART 1
+#define DISP_CHANGE_FAILED (-1)
+#define DISP_CHANGE_BADMODE (-2)
+#define DISP_CHANGE_NOTUPDATED (-3)
+#define DISP_CHANGE_BADFLAGS (-4)
+#define DISP_CHANGE_BADPARAM (-5)
+
+/* ChangeDisplaySettings.dwFlags */
+#define CDS_UPDATEREGISTRY 0x00000001
+#define CDS_TEST 0x00000002
+#define CDS_FULLSCREEN 0x00000004
+#define CDS_GLOBAL 0x00000008
+#define CDS_SET_PRIMARY 0x00000010
+#define CDS_RESET 0x40000000
+#define CDS_SETRECT 0x20000000
+#define CDS_NORESET 0x10000000
+
+/* flags to FormatMessage */
+#define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100
+#define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200
+#define FORMAT_MESSAGE_FROM_STRING 0x00000400
+#define FORMAT_MESSAGE_FROM_HMODULE 0x00000800
+#define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000
+#define FORMAT_MESSAGE_ARGUMENT_ARRAY 0x00002000
+#define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF
+
+typedef struct
+{
+ UINT cbSize;
+ UINT style;
+ WNDPROC lpfnWndProc;
+ INT cbClsExtra;
+ INT cbWndExtra;
+ HINSTANCE hInstance;
+ HICON hIcon;
+ HCURSOR hCursor;
+ HBRUSH hbrBackground;
+ LPCSTR lpszMenuName;
+ LPCSTR lpszClassName;
+ HICON hIconSm;
+} WNDCLASSEXA, *LPWNDCLASSEXA;
+
+typedef struct
+{
+ UINT cbSize;
+ UINT style;
+ WNDPROC lpfnWndProc;
+ INT cbClsExtra;
+ INT cbWndExtra;
+ HINSTANCE hInstance;
+ HICON hIcon;
+ HCURSOR hCursor;
+ HBRUSH hbrBackground;
+ LPCWSTR lpszMenuName;
+ LPCWSTR lpszClassName;
+ HICON hIconSm;
+} WNDCLASSEXW, *LPWNDCLASSEXW;
+
+DECL_WINELIB_TYPE_AW(WNDCLASSEX)
+DECL_WINELIB_TYPE_AW(LPWNDCLASSEX)
+
+typedef struct tagMSG
+{
+ HWND hwnd;
+ UINT message;
+ WPARAM wParam;
+ LPARAM lParam;
+ DWORD time;
+ POINT pt;
+} MSG, *LPMSG;
+
+#define POINTSTOPOINT(pt, pts) \
+ { (pt).x = (LONG)(SHORT)LOWORD(*(LONG*)&pts); \
+ (pt).y = (LONG)(SHORT)HIWORD(*(LONG*)&pts); }
+
+#define POINTTOPOINTS(pt) (MAKELONG((short)((pt).x), (short)((pt).y)))
+
+
+/* Cursors / Icons */
+
+typedef struct {
+ WIN_BOOL fIcon;
+ DWORD xHotspot;
+ DWORD yHotspot;
+ HBITMAP hbmMask;
+ HBITMAP hbmColor;
+} ICONINFO,*LPICONINFO;
+
+
+/* this is the 6 byte accel struct used in Win32 when presented to the user */
+typedef struct
+{
+ BYTE fVirt;
+ BYTE pad0;
+ WORD key;
+ WORD cmd;
+} ACCEL, *LPACCEL;
+
+/* this is the 8 byte accel struct used in Win32 resources (internal only) */
+typedef struct
+{
+ BYTE fVirt;
+ BYTE pad0;
+ WORD key;
+ WORD cmd;
+ WORD pad1;
+} PE_ACCEL, *LPPE_ACCEL;
+
+
+/* Flags for TrackPopupMenu */
+#define TPM_LEFTBUTTON 0x0000
+#define TPM_RIGHTBUTTON 0x0002
+#define TPM_LEFTALIGN 0x0000
+#define TPM_CENTERALIGN 0x0004
+#define TPM_RIGHTALIGN 0x0008
+#define TPM_TOPALIGN 0x0000
+#define TPM_VCENTERALIGN 0x0010
+#define TPM_BOTTOMALIGN 0x0020
+#define TPM_HORIZONTAL 0x0000
+#define TPM_VERTICAL 0x0040
+#define TPM_NONOTIFY 0x0080
+#define TPM_RETURNCMD 0x0100
+
+typedef struct
+{
+ UINT cbSize;
+ RECT rcExclude;
+} TPMPARAMS, *LPTPMPARAMS;
+
+/* FIXME: not sure this one is correct */
+typedef struct {
+ UINT cbSize;
+ UINT fMask;
+ UINT fType;
+ UINT fState;
+ UINT wID;
+ HMENU hSubMenu;
+ HBITMAP hbmpChecked;
+ HBITMAP hbmpUnchecked;
+ DWORD dwItemData;
+ LPSTR dwTypeData;
+ UINT cch;
+ HBITMAP hbmpItem;
+} MENUITEMINFOA, *LPMENUITEMINFOA;
+
+typedef struct {
+ UINT cbSize;
+ UINT fMask;
+ UINT fType;
+ UINT fState;
+ UINT wID;
+ HMENU hSubMenu;
+ HBITMAP hbmpChecked;
+ HBITMAP hbmpUnchecked;
+ DWORD dwItemData;
+ LPWSTR dwTypeData;
+ UINT cch;
+ HBITMAP hbmpItem;
+} MENUITEMINFOW, *LPMENUITEMINFOW;
+
+DECL_WINELIB_TYPE_AW(MENUITEMINFO)
+DECL_WINELIB_TYPE_AW(LPMENUITEMINFO)
+
+typedef struct {
+ DWORD cbSize;
+ DWORD fMask;
+ DWORD dwStyle;
+ UINT cyMax;
+ HBRUSH hbrBack;
+ DWORD dwContextHelpID;
+ DWORD dwMenuData;
+} MENUINFO, *LPMENUINFO;
+
+typedef MENUINFO const * LPCMENUINFO;
+
+#define MIM_MAXHEIGHT 0x00000001
+#define MIM_BACKGROUND 0x00000002
+#define MIM_HELPID 0x00000004
+#define MIM_MENUDATA 0x00000008
+#define MIM_STYLE 0x00000010
+#define MIM_APPLYTOSUBMENUS 0x80000000
+
+typedef struct {
+ WORD versionNumber;
+ WORD offset;
+} MENUITEMTEMPLATEHEADER, *PMENUITEMTEMPLATEHEADER;
+
+
+typedef struct {
+ WORD mtOption;
+ WORD mtID;
+ WCHAR mtString[1];
+} MENUITEMTEMPLATE, *PMENUITEMTEMPLATE;
+
+
+typedef VOID MENUTEMPLATE;
+typedef PVOID *LPMENUTEMPLATE;
+
+/* Field specifiers for MENUITEMINFO[AW] type. */
+#define MIIM_STATE 0x00000001
+#define MIIM_ID 0x00000002
+#define MIIM_SUBMENU 0x00000004
+#define MIIM_CHECKMARKS 0x00000008
+#define MIIM_TYPE 0x00000010
+#define MIIM_DATA 0x00000020
+#define MIIM_STRING 0x00000040
+#define MIIM_BITMAP 0x00000080
+#define MIIM_FTYPE 0x00000100
+
+#define HBMMENU_CALLBACK ((HBITMAP) -1)
+#define HBMMENU_SYSTEM ((HBITMAP) 1)
+#define HBMMENU_MBAR_RESTORE ((HBITMAP) 2)
+#define HBMMENU_MBAR_MINIMIZE ((HBITMAP) 3)
+#define HBMMENU_MBAR_CLOSE ((HBITMAP) 5)
+#define HBMMENU_MBAR_CLOSE_D ((HBITMAP) 6)
+#define HBMMENU_MBAR_MINIMIZE_D ((HBITMAP) 7)
+#define HBMMENU_POPUP_CLOSE ((HBITMAP) 8)
+#define HBMMENU_POPUP_RESTORE ((HBITMAP) 9)
+#define HBMMENU_POPUP_MAXIMIZE ((HBITMAP) 10)
+#define HBMMENU_POPUP_MINIMIZE ((HBITMAP) 11)
+
+/* DrawState defines ... */
+typedef WIN_BOOL CALLBACK (*DRAWSTATEPROC)(HDC,LPARAM,WPARAM,INT,INT);
+
+/* WM_H/VSCROLL commands */
+#define SB_LINEUP 0
+#define SB_LINELEFT 0
+#define SB_LINEDOWN 1
+#define SB_LINERIGHT 1
+#define SB_PAGEUP 2
+#define SB_PAGELEFT 2
+#define SB_PAGEDOWN 3
+#define SB_PAGERIGHT 3
+#define SB_THUMBPOSITION 4
+#define SB_THUMBTRACK 5
+#define SB_TOP 6
+#define SB_LEFT 6
+#define SB_BOTTOM 7
+#define SB_RIGHT 7
+#define SB_ENDSCROLL 8
+
+/* Scroll bar selection constants */
+#define SB_HORZ 0
+#define SB_VERT 1
+#define SB_CTL 2
+#define SB_BOTH 3
+
+/* Scrollbar styles */
+#define SBS_HORZ 0x0000L
+#define SBS_VERT 0x0001L
+#define SBS_TOPALIGN 0x0002L
+#define SBS_LEFTALIGN 0x0002L
+#define SBS_BOTTOMALIGN 0x0004L
+#define SBS_RIGHTALIGN 0x0004L
+#define SBS_SIZEBOXTOPLEFTALIGN 0x0002L
+#define SBS_SIZEBOXBOTTOMRIGHTALIGN 0x0004L
+#define SBS_SIZEBOX 0x0008L
+#define SBS_SIZEGRIP 0x0010L
+
+/* EnableScrollBar() flags */
+#define ESB_ENABLE_BOTH 0x0000
+#define ESB_DISABLE_BOTH 0x0003
+
+#define ESB_DISABLE_LEFT 0x0001
+#define ESB_DISABLE_RIGHT 0x0002
+
+#define ESB_DISABLE_UP 0x0001
+#define ESB_DISABLE_DOWN 0x0002
+
+#define ESB_DISABLE_LTUP ESB_DISABLE_LEFT
+#define ESB_DISABLE_RTDN ESB_DISABLE_RIGHT
+
+/* Win32 button control messages */
+#define BM_GETCHECK 0x00f0
+#define BM_SETCHECK 0x00f1
+#define BM_GETSTATE 0x00f2
+#define BM_SETSTATE 0x00f3
+#define BM_SETSTYLE 0x00f4
+#define BM_CLICK 0x00f5
+#define BM_GETIMAGE 0x00f6
+#define BM_SETIMAGE 0x00f7
+/* Winelib button control messages */
+
+/* Button notification codes */
+#define BN_CLICKED 0
+#define BN_PAINT 1
+#define BN_HILITE 2
+#define BN_UNHILITE 3
+#define BN_DISABLE 4
+#define BN_DOUBLECLICKED 5
+
+/* Button states */
+#define BST_UNCHECKED 0x0000
+#define BST_CHECKED 0x0001
+#define BST_INDETERMINATE 0x0002
+#define BST_PUSHED 0x0004
+#define BST_FOCUS 0x0008
+
+/* Static Control Styles */
+#define SS_LEFT 0x00000000L
+#define SS_CENTER 0x00000001L
+#define SS_RIGHT 0x00000002L
+#define SS_ICON 0x00000003L
+#define SS_BLACKRECT 0x00000004L
+#define SS_GRAYRECT 0x00000005L
+#define SS_WHITERECT 0x00000006L
+#define SS_BLACKFRAME 0x00000007L
+#define SS_GRAYFRAME 0x00000008L
+#define SS_WHITEFRAME 0x00000009L
+
+#define SS_SIMPLE 0x0000000BL
+#define SS_LEFTNOWORDWRAP 0x0000000CL
+
+#define SS_OWNERDRAW 0x0000000DL
+#define SS_BITMAP 0x0000000EL
+#define SS_ENHMETAFILE 0x0000000FL
+
+#define SS_ETCHEDHORZ 0x00000010L
+#define SS_ETCHEDVERT 0x00000011L
+#define SS_ETCHEDFRAME 0x00000012L
+#define SS_TYPEMASK 0x0000001FL
+
+#define SS_NOPREFIX 0x00000080L
+#define SS_NOTIFY 0x00000100L
+#define SS_CENTERIMAGE 0x00000200L
+#define SS_RIGHTJUST 0x00000400L
+#define SS_REALSIZEIMAGE 0x00000800L
+#define SS_SUNKEN 0x00001000L
+
+/* Static Control Messages */
+#define STM_SETICON 0x0170
+#define STM_GETICON 0x0171
+#define STM_SETIMAGE 0x0172
+#define STM_GETIMAGE 0x0173
+
+/* Scrollbar messages */
+#define SBM_SETPOS 0x00e0
+#define SBM_GETPOS 0x00e1
+#define SBM_SETRANGE 0x00e2
+#define SBM_GETRANGE 0x00e3
+#define SBM_ENABLE_ARROWS 0x00e4
+#define SBM_SETRANGEREDRAW 0x00e6
+#define SBM_SETSCROLLINFO 0x00e9
+#define SBM_GETSCROLLINFO 0x00ea
+
+/* Scrollbar info */
+typedef struct
+{
+ UINT cbSize;
+ UINT fMask;
+ INT nMin;
+ INT nMax;
+ UINT nPage;
+ INT nPos;
+ INT nTrackPos;
+} SCROLLINFO, *LPSCROLLINFO;
+
+/* GetScrollInfo() flags */
+#define SIF_RANGE 0x0001
+#define SIF_PAGE 0x0002
+#define SIF_POS 0x0004
+#define SIF_DISABLENOSCROLL 0x0008
+#define SIF_TRACKPOS 0x0010
+#define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS)
+
+/* Listbox styles */
+#define LBS_NOTIFY 0x0001
+#define LBS_SORT 0x0002
+#define LBS_NOREDRAW 0x0004
+#define LBS_MULTIPLESEL 0x0008
+#define LBS_OWNERDRAWFIXED 0x0010
+#define LBS_OWNERDRAWVARIABLE 0x0020
+#define LBS_HASSTRINGS 0x0040
+#define LBS_USETABSTOPS 0x0080
+#define LBS_NOINTEGRALHEIGHT 0x0100
+#define LBS_MULTICOLUMN 0x0200
+#define LBS_WANTKEYBOARDINPUT 0x0400
+#define LBS_EXTENDEDSEL 0x0800
+#define LBS_DISABLENOSCROLL 0x1000
+#define LBS_NODATA 0x2000
+#define LBS_NOSEL 0x4000
+#define LBS_STANDARD (LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER)
+
+/* Listbox messages */
+#define LB_ADDSTRING 0x0180
+#define LB_INSERTSTRING 0x0181
+#define LB_DELETESTRING 0x0182
+#define LB_SELITEMRANGEEX 0x0183
+#define LB_RESETCONTENT 0x0184
+#define LB_SETSEL 0x0185
+#define LB_SETCURSEL 0x0186
+#define LB_GETSEL 0x0187
+#define LB_GETCURSEL 0x0188
+#define LB_GETTEXT 0x0189
+#define LB_GETTEXTLEN 0x018a
+#define LB_GETCOUNT 0x018b
+#define LB_SELECTSTRING 0x018c
+#define LB_DIR 0x018d
+#define LB_GETTOPINDEX 0x018e
+#define LB_FINDSTRING 0x018f
+#define LB_GETSELCOUNT 0x0190
+#define LB_GETSELITEMS 0x0191
+#define LB_SETTABSTOPS 0x0192
+#define LB_GETHORIZONTALEXTENT 0x0193
+#define LB_SETHORIZONTALEXTENT 0x0194
+#define LB_SETCOLUMNWIDTH 0x0195
+#define LB_ADDFILE 0x0196
+#define LB_SETTOPINDEX 0x0197
+#define LB_GETITEMRECT 0x0198
+#define LB_GETITEMDATA 0x0199
+#define LB_SETITEMDATA 0x019a
+#define LB_SELITEMRANGE 0x019b
+#define LB_SETANCHORINDEX 0x019c
+#define LB_GETANCHORINDEX 0x019d
+#define LB_SETCARETINDEX 0x019e
+#define LB_GETCARETINDEX 0x019f
+#define LB_SETITEMHEIGHT 0x01a0
+#define LB_GETITEMHEIGHT 0x01a1
+#define LB_FINDSTRINGEXACT 0x01a2
+#define LB_CARETON 0x01a3
+#define LB_CARETOFF 0x01a4
+#define LB_SETLOCALE 0x01a5
+#define LB_GETLOCALE 0x01a6
+#define LB_SETCOUNT 0x01a7
+#define LB_INITSTORAGE 0x01a8
+#define LB_ITEMFROMPOINT 0x01a9
+
+/* Listbox notification codes */
+#define LBN_ERRSPACE (-2)
+#define LBN_SELCHANGE 1
+#define LBN_DBLCLK 2
+#define LBN_SELCANCEL 3
+#define LBN_SETFOCUS 4
+#define LBN_KILLFOCUS 5
+
+/* Listbox message return values */
+#define LB_OKAY 0
+#define LB_ERR (-1)
+#define LB_ERRSPACE (-2)
+
+#define LB_CTLCODE 0L
+
+/* Combo box styles */
+#define CBS_SIMPLE 0x0001L
+#define CBS_DROPDOWN 0x0002L
+#define CBS_DROPDOWNLIST 0x0003L
+#define CBS_OWNERDRAWFIXED 0x0010L
+#define CBS_OWNERDRAWVARIABLE 0x0020L
+#define CBS_AUTOHSCROLL 0x0040L
+#define CBS_OEMCONVERT 0x0080L
+#define CBS_SORT 0x0100L
+#define CBS_HASSTRINGS 0x0200L
+#define CBS_NOINTEGRALHEIGHT 0x0400L
+#define CBS_DISABLENOSCROLL 0x0800L
+
+#define CBS_UPPERCASE 0x2000L
+#define CBS_LOWERCASE 0x4000L
+
+
+/* Combo box messages */
+#define CB_GETEDITSEL 0x0140
+#define CB_LIMITTEXT 0x0141
+#define CB_SETEDITSEL 0x0142
+#define CB_ADDSTRING 0x0143
+#define CB_DELETESTRING 0x0144
+#define CB_DIR 0x0145
+#define CB_GETCOUNT 0x0146
+#define CB_GETCURSEL 0x0147
+#define CB_GETLBTEXT 0x0148
+#define CB_GETLBTEXTLEN 0x0149
+#define CB_INSERTSTRING 0x014a
+#define CB_RESETCONTENT 0x014b
+#define CB_FINDSTRING 0x014c
+#define CB_SELECTSTRING 0x014d
+#define CB_SETCURSEL 0x014e
+#define CB_SHOWDROPDOWN 0x014f
+#define CB_GETITEMDATA 0x0150
+#define CB_SETITEMDATA 0x0151
+#define CB_GETDROPPEDCONTROLRECT 0x0152
+#define CB_SETITEMHEIGHT 0x0153
+#define CB_GETITEMHEIGHT 0x0154
+#define CB_SETEXTENDEDUI 0x0155
+#define CB_GETEXTENDEDUI 0x0156
+#define CB_GETDROPPEDSTATE 0x0157
+#define CB_FINDSTRINGEXACT 0x0158
+#define CB_SETLOCALE 0x0159
+#define CB_GETLOCALE 0x015a
+#define CB_GETTOPINDEX 0x015b
+#define CB_SETTOPINDEX 0x015c
+#define CB_GETHORIZONTALEXTENT 0x015d
+#define CB_SETHORIZONTALEXTENT 0x015e
+#define CB_GETDROPPEDWIDTH 0x015f
+#define CB_SETDROPPEDWIDTH 0x0160
+#define CB_INITSTORAGE 0x0161
+
+/* Combo box notification codes */
+#define CBN_ERRSPACE (-1)
+#define CBN_SELCHANGE 1
+#define CBN_DBLCLK 2
+#define CBN_SETFOCUS 3
+#define CBN_KILLFOCUS 4
+#define CBN_EDITCHANGE 5
+#define CBN_EDITUPDATE 6
+#define CBN_DROPDOWN 7
+#define CBN_CLOSEUP 8
+#define CBN_SELENDOK 9
+#define CBN_SELENDCANCEL 10
+
+/* Combo box message return values */
+#define CB_OKAY 0
+#define CB_ERR (-1)
+#define CB_ERRSPACE (-2)
+
+#define MB_OK 0x00000000
+#define MB_OKCANCEL 0x00000001
+#define MB_ABORTRETRYIGNORE 0x00000002
+#define MB_YESNOCANCEL 0x00000003
+#define MB_YESNO 0x00000004
+#define MB_RETRYCANCEL 0x00000005
+#define MB_TYPEMASK 0x0000000F
+
+#define MB_ICONHAND 0x00000010
+#define MB_ICONQUESTION 0x00000020
+#define MB_ICONEXCLAMATION 0x00000030
+#define MB_ICONASTERISK 0x00000040
+#define MB_USERICON 0x00000080
+#define MB_ICONMASK 0x000000F0
+
+#define MB_ICONINFORMATION MB_ICONASTERISK
+#define MB_ICONSTOP MB_ICONHAND
+#define MB_ICONWARNING MB_ICONEXCLAMATION
+#define MB_ICONERROR MB_ICONHAND
+
+#define MB_DEFBUTTON1 0x00000000
+#define MB_DEFBUTTON2 0x00000100
+#define MB_DEFBUTTON3 0x00000200
+#define MB_DEFBUTTON4 0x00000300
+#define MB_DEFMASK 0x00000F00
+
+#define MB_APPLMODAL 0x00000000
+#define MB_SYSTEMMODAL 0x00001000
+#define MB_TASKMODAL 0x00002000
+#define MB_MODEMASK 0x00003000
+
+#define MB_HELP 0x00004000
+#define MB_NOFOCUS 0x00008000
+#define MB_MISCMASK 0x0000C000
+
+#define MB_SETFOREGROUND 0x00010000
+#define MB_DEFAULT_DESKTOP_ONLY 0x00020000
+#define MB_SERVICE_NOTIFICATION 0x00040000
+#define MB_TOPMOST 0x00040000
+#define MB_RIGHT 0x00080000
+#define MB_RTLREADING 0x00100000
+
+#define HELPINFO_WINDOW 0x0001
+#define HELPINFO_MENUITEM 0x0002
+
+/* Structure pointed to by lParam of WM_HELP */
+typedef struct
+{
+ UINT cbSize; /* Size in bytes of this struct */
+ INT iContextType; /* Either HELPINFO_WINDOW or HELPINFO_MENUITEM */
+ INT iCtrlId; /* Control Id or a Menu item Id. */
+ HANDLE hItemHandle; /* hWnd of control or hMenu. */
+ DWORD dwContextId; /* Context Id associated with this item */
+ POINT MousePos; /* Mouse Position in screen co-ordinates */
+} HELPINFO,*LPHELPINFO;
+
+typedef void CALLBACK (*MSGBOXCALLBACK)(LPHELPINFO lpHelpInfo);
+
+typedef struct
+{
+ UINT cbSize;
+ HWND hwndOwner;
+ HINSTANCE hInstance;
+ LPCSTR lpszText;
+ LPCSTR lpszCaption;
+ DWORD dwStyle;
+ LPCSTR lpszIcon;
+ DWORD dwContextHelpId;
+ MSGBOXCALLBACK lpfnMsgBoxCallback;
+ DWORD dwLanguageId;
+} MSGBOXPARAMSA,*LPMSGBOXPARAMSA;
+
+typedef struct
+{
+ UINT cbSize;
+ HWND hwndOwner;
+ HINSTANCE hInstance;
+ LPCWSTR lpszText;
+ LPCWSTR lpszCaption;
+ DWORD dwStyle;
+ LPCWSTR lpszIcon;
+ DWORD dwContextHelpId;
+ MSGBOXCALLBACK lpfnMsgBoxCallback;
+ DWORD dwLanguageId;
+} MSGBOXPARAMSW,*LPMSGBOXPARAMSW;
+
+DECL_WINELIB_TYPE_AW(MSGBOXPARAMS)
+DECL_WINELIB_TYPE_AW(LPMSGBOXPARAMS)
+
+typedef struct _numberfmt32a {
+ UINT NumDigits;
+ UINT LeadingZero;
+ UINT Grouping;
+ LPCSTR lpDecimalSep;
+ LPCSTR lpThousandSep;
+ UINT NegativeOrder;
+} NUMBERFMTA;
+
+typedef struct _numberfmt32w {
+ UINT NumDigits;
+ UINT LeadingZero;
+ UINT Grouping;
+ LPCWSTR lpDecimalSep;
+ LPCWSTR lpThousandSep;
+ UINT NegativeOrder;
+} NUMBERFMTW;
+
+typedef struct _currencyfmt32a
+{
+ UINT NumDigits;
+ UINT LeadingZero;
+ UINT Grouping;
+ LPCSTR lpDecimalSep;
+ LPCSTR lpThousandSep;
+ UINT NegativeOrder;
+ UINT PositiveOrder;
+ LPCSTR lpCurrencySymbol;
+} CURRENCYFMTA;
+
+typedef struct _currencyfmt32w
+{
+ UINT NumDigits;
+ UINT LeadingZero;
+ UINT Grouping;
+ LPCWSTR lpDecimalSep;
+ LPCWSTR lpThousandSep;
+ UINT NegativeOrder;
+ UINT PositiveOrder;
+ LPCWSTR lpCurrencySymbol;
+} CURRENCYFMTW;
+
+#define MONITOR_DEFAULTTONULL 0x00000000
+#define MONITOR_DEFAULTTOPRIMARY 0x00000001
+#define MONITOR_DEFAULTTONEAREST 0x00000002
+
+#define MONITORINFOF_PRIMARY 0x00000001
+
+typedef struct tagMONITORINFO
+{
+ DWORD cbSize;
+ RECT rcMonitor;
+ RECT rcWork;
+ DWORD dwFlags;
+} MONITORINFO, *LPMONITORINFO;
+
+
+typedef WIN_BOOL CALLBACK (*MONITORENUMPROC)(HMONITOR,HDC,LPRECT,LPARAM);
+
+/* FIXME: use this instead of LPCVOID for CreateDialogIndirectParam
+ and DialogBoxIndirectParam */
+typedef struct tagDLGTEMPLATE
+{
+ DWORD style;
+ DWORD dwExtendedStyle;
+ WORD cdit;
+ short x;
+ short y;
+ short cx;
+ short cy;
+} DLGTEMPLATE;
+
+typedef DLGTEMPLATE *LPDLGTEMPLATEA;
+typedef DLGTEMPLATE *LPDLGTEMPLATEW;
+#define LPDLGTEMPLATE WINELIB_NAME_AW(LPDLGTEMPLATE)
+typedef const DLGTEMPLATE *LPCDLGTEMPLATEA;
+typedef const DLGTEMPLATE *LPCDLGTEMPLATEW;
+#define LPCDLGTEMPLATE WINELIB_NAME_AW(LPCDLGTEMPLATE)
+
+typedef struct tagDLGITEMTEMPLATE
+{
+ DWORD style;
+ DWORD dwExtendedStyle;
+ short x;
+ short y;
+ short cx;
+ short cy;
+ WORD id;
+} DLGITEMTEMPLATE;
+
+typedef DLGITEMTEMPLATE *LPDLGITEMTEMPLATEA;
+typedef DLGITEMTEMPLATE *LPDLGITEMTEMPLATEW;
+#define LPDLGITEMTEMPLATE WINELIB_NAME_AW(LPDLGITEMTEMPLATE)
+typedef const DLGITEMTEMPLATE *LPCDLGITEMTEMPLATEA;
+typedef const DLGITEMTEMPLATE *LPCDLGITEMTEMPLATEW;
+#define LPCDLGITEMTEMPLATE WINELIB_NAME_AW(LPCDLGITEMTEMPLATE)
+
+
+ /* CBT hook values */
+#define HCBT_MOVESIZE 0
+#define HCBT_MINMAX 1
+#define HCBT_QS 2
+#define HCBT_CREATEWND 3
+#define HCBT_DESTROYWND 4
+#define HCBT_ACTIVATE 5
+#define HCBT_CLICKSKIPPED 6
+#define HCBT_KEYSKIPPED 7
+#define HCBT_SYSCOMMAND 8
+#define HCBT_SETFOCUS 9
+
+ /* CBT hook structures */
+
+typedef struct
+{
+ CREATESTRUCTA *lpcs;
+ HWND hwndInsertAfter;
+} CBT_CREATEWNDA, *LPCBT_CREATEWNDA;
+
+typedef struct
+{
+ CREATESTRUCTW *lpcs;
+ HWND hwndInsertAfter;
+} CBT_CREATEWNDW, *LPCBT_CREATEWNDW;
+
+DECL_WINELIB_TYPE_AW(CBT_CREATEWND)
+DECL_WINELIB_TYPE_AW(LPCBT_CREATEWND)
+
+typedef struct
+{
+ WIN_BOOL fMouse;
+ HWND hWndActive;
+} CBTACTIVATESTRUCT, *LPCBTACTIVATESTRUCT;
+
+
+/* modifiers for RegisterHotKey */
+#define MOD_ALT 0x0001
+#define MOD_CONTROL 0x0002
+#define MOD_SHIFT 0x0004
+#define MOD_WIN 0x0008
+
+/* ids for RegisterHotKey */
+#define IDHOT_SNAPWINDOW (-1) /* SHIFT-PRINTSCRN */
+#define IDHOT_SNAPDESKTOP (-2) /* PRINTSCRN */
+
+ /* keybd_event flags */
+#define KEYEVENTF_EXTENDEDKEY 0x0001
+#define KEYEVENTF_KEYUP 0x0002
+#define KEYEVENTF_WINE_FORCEEXTENDED 0x8000
+
+ /* mouse_event flags */
+#define MOUSEEVENTF_MOVE 0x0001
+#define MOUSEEVENTF_LEFTDOWN 0x0002
+#define MOUSEEVENTF_LEFTUP 0x0004
+#define MOUSEEVENTF_RIGHTDOWN 0x0008
+#define MOUSEEVENTF_RIGHTUP 0x0010
+#define MOUSEEVENTF_MIDDLEDOWN 0x0020
+#define MOUSEEVENTF_MIDDLEUP 0x0040
+#define MOUSEEVENTF_WHEEL 0x0800
+#define MOUSEEVENTF_ABSOLUTE 0x8000
+
+/* ExitWindows() flags */
+#define EW_RESTARTWINDOWS 0x0042
+#define EW_REBOOTSYSTEM 0x0043
+#define EW_EXITANDEXECAPP 0x0044
+
+/* ExitWindowsEx() flags */
+#define EWX_LOGOFF 0
+#define EWX_SHUTDOWN 1
+#define EWX_REBOOT 2
+#define EWX_FORCE 4
+#define EWX_POWEROFF 8
+
+/* SetLastErrorEx types */
+#define SLE_ERROR 0x00000001
+#define SLE_MINORERROR 0x00000002
+#define SLE_WARNING 0x00000003
+
+/* Predefined resources */
+#define IDI_APPLICATIONA MAKEINTRESOURCEA(32512)
+#define IDI_APPLICATIONW MAKEINTRESOURCEW(32512)
+#define IDI_APPLICATION WINELIB_NAME_AW(IDI_APPLICATION)
+#define IDI_HANDA MAKEINTRESOURCEA(32513)
+#define IDI_HANDW MAKEINTRESOURCEW(32513)
+#define IDI_HAND WINELIB_NAME_AW(IDI_HAND)
+#define IDI_QUESTIONA MAKEINTRESOURCEA(32514)
+#define IDI_QUESTIONW MAKEINTRESOURCEW(32514)
+#define IDI_QUESTION WINELIB_NAME_AW(IDI_QUESTION)
+#define IDI_EXCLAMATIONA MAKEINTRESOURCEA(32515)
+#define IDI_EXCLAMATIONW MAKEINTRESOURCEW(32515)
+#define IDI_EXCLAMATION WINELIB_NAME_AW(IDI_EXCLAMATION)
+#define IDI_ASTERISKA MAKEINTRESOURCEA(32516)
+#define IDI_ASTERISKW MAKEINTRESOURCEW(32516)
+#define IDI_ASTERISK WINELIB_NAME_AW(IDI_ASTERISK)
+
+#define IDC_BUMMERA MAKEINTRESOURCEA(100)
+#define IDC_BUMMERW MAKEINTRESOURCEW(100)
+#define IDC_BUMMER WINELIB_NAME_AW(IDC_BUMMER)
+#define IDC_ARROWA MAKEINTRESOURCEA(32512)
+#define IDC_ARROWW MAKEINTRESOURCEW(32512)
+#define IDC_ARROW WINELIB_NAME_AW(IDC_ARROW)
+#define IDC_IBEAMA MAKEINTRESOURCEA(32513)
+#define IDC_IBEAMW MAKEINTRESOURCEW(32513)
+#define IDC_IBEAM WINELIB_NAME_AW(IDC_IBEAM)
+#define IDC_WAITA MAKEINTRESOURCEA(32514)
+#define IDC_WAITW MAKEINTRESOURCEW(32514)
+#define IDC_WAIT WINELIB_NAME_AW(IDC_WAIT)
+#define IDC_CROSSA MAKEINTRESOURCEA(32515)
+#define IDC_CROSSW MAKEINTRESOURCEW(32515)
+#define IDC_CROSS WINELIB_NAME_AW(IDC_CROSS)
+#define IDC_UPARROWA MAKEINTRESOURCEA(32516)
+#define IDC_UPARROWW MAKEINTRESOURCEW(32516)
+#define IDC_UPARROW WINELIB_NAME_AW(IDC_UPARROW)
+#define IDC_SIZEA MAKEINTRESOURCEA(32640)
+#define IDC_SIZEW MAKEINTRESOURCEW(32640)
+#define IDC_SIZE WINELIB_NAME_AW(IDC_SIZE)
+#define IDC_ICONA MAKEINTRESOURCEA(32641)
+#define IDC_ICONW MAKEINTRESOURCEW(32641)
+#define IDC_ICON WINELIB_NAME_AW(IDC_ICON)
+#define IDC_SIZENWSEA MAKEINTRESOURCEA(32642)
+#define IDC_SIZENWSEW MAKEINTRESOURCEW(32642)
+#define IDC_SIZENWSE WINELIB_NAME_AW(IDC_SIZENWSE)
+#define IDC_SIZENESWA MAKEINTRESOURCEA(32643)
+#define IDC_SIZENESWW MAKEINTRESOURCEW(32643)
+#define IDC_SIZENESW WINELIB_NAME_AW(IDC_SIZENESW)
+#define IDC_SIZEWEA MAKEINTRESOURCEA(32644)
+#define IDC_SIZEWEW MAKEINTRESOURCEW(32644)
+#define IDC_SIZEWE WINELIB_NAME_AW(IDC_SIZEWE)
+#define IDC_SIZENSA MAKEINTRESOURCEA(32645)
+#define IDC_SIZENSW MAKEINTRESOURCEW(32645)
+#define IDC_SIZENS WINELIB_NAME_AW(IDC_SIZENS)
+#define IDC_SIZEALLA MAKEINTRESOURCEA(32646)
+#define IDC_SIZEALLW MAKEINTRESOURCEW(32646)
+#define IDC_SIZEALL WINELIB_NAME_AW(IDC_SIZEALL)
+#define IDC_NOA MAKEINTRESOURCEA(32648)
+#define IDC_NOW MAKEINTRESOURCEW(32648)
+#define IDC_NO WINELIB_NAME_AW(IDC_NO)
+#define IDC_APPSTARTINGA MAKEINTRESOURCEA(32650)
+#define IDC_APPSTARTINGW MAKEINTRESOURCEW(32650)
+#define IDC_APPSTARTING WINELIB_NAME_AW(IDC_APPSTARTING)
+#define IDC_HELPA MAKEINTRESOURCEA(32651)
+#define IDC_HELPW MAKEINTRESOURCEW(32651)
+#define IDC_HELP WINELIB_NAME_AW(IDC_HELP)
+
+#define MNC_IGNORE 0
+#define MNC_CLOSE 1
+#define MNC_EXECUTE 2
+#define MNC_SELECT 3
+
+/* SystemParametersInfo */
+/* defines below are for all win versions */
+#define SPI_GETBEEP 1
+#define SPI_SETBEEP 2
+#define SPI_GETMOUSE 3
+#define SPI_SETMOUSE 4
+#define SPI_GETBORDER 5
+#define SPI_SETBORDER 6
+#define SPI_GETKEYBOARDSPEED 10
+#define SPI_SETKEYBOARDSPEED 11
+#define SPI_LANGDRIVER 12
+#define SPI_ICONHORIZONTALSPACING 13
+#define SPI_GETSCREENSAVETIMEOUT 14
+#define SPI_SETSCREENSAVETIMEOUT 15
+#define SPI_GETSCREENSAVEACTIVE 16
+#define SPI_SETSCREENSAVEACTIVE 17
+#define SPI_GETGRIDGRANULARITY 18
+#define SPI_SETGRIDGRANULARITY 19
+#define SPI_SETDESKWALLPAPER 20
+#define SPI_SETDESKPATTERN 21
+#define SPI_GETKEYBOARDDELAY 22
+#define SPI_SETKEYBOARDDELAY 23
+#define SPI_ICONVERTICALSPACING 24
+#define SPI_GETICONTITLEWRAP 25
+#define SPI_SETICONTITLEWRAP 26
+#define SPI_GETMENUDROPALIGNMENT 27
+#define SPI_SETMENUDROPALIGNMENT 28
+#define SPI_SETDOUBLECLKWIDTH 29
+#define SPI_SETDOUBLECLKHEIGHT 30
+#define SPI_GETICONTITLELOGFONT 31
+#define SPI_SETDOUBLECLICKTIME 32
+#define SPI_SETMOUSEBUTTONSWAP 33
+#define SPI_SETICONTITLELOGFONT 34
+#define SPI_GETFASTTASKSWITCH 35
+#define SPI_SETFASTTASKSWITCH 36
+#define SPI_SETDRAGFULLWINDOWS 37
+#define SPI_GETDRAGFULLWINDOWS 38
+
+#define SPI_GETFILTERKEYS 50
+#define SPI_SETFILTERKEYS 51
+#define SPI_GETTOGGLEKEYS 52
+#define SPI_SETTOGGLEKEYS 53
+#define SPI_GETMOUSEKEYS 54
+#define SPI_SETMOUSEKEYS 55
+#define SPI_GETSHOWSOUNDS 56
+#define SPI_SETSHOWSOUNDS 57
+#define SPI_GETSTICKYKEYS 58
+#define SPI_SETSTICKYKEYS 59
+#define SPI_GETACCESSTIMEOUT 60
+#define SPI_SETACCESSTIMEOUT 61
+
+#define SPI_GETSOUNDSENTRY 64
+#define SPI_SETSOUNDSENTRY 65
+
+/* defines below are for all win versions WINVER >= 0x0400 */
+#define SPI_SETDRAGFULLWINDOWS 37
+#define SPI_GETDRAGFULLWINDOWS 38
+#define SPI_GETNONCLIENTMETRICS 41
+#define SPI_SETNONCLIENTMETRICS 42
+#define SPI_GETMINIMIZEDMETRICS 43
+#define SPI_SETMINIMIZEDMETRICS 44
+#define SPI_GETICONMETRICS 45
+#define SPI_SETICONMETRICS 46
+#define SPI_SETWORKAREA 47
+#define SPI_GETWORKAREA 48
+#define SPI_SETPENWINDOWS 49
+
+#define SPI_GETSERIALKEYS 62
+#define SPI_SETSERIALKEYS 63
+#define SPI_GETHIGHCONTRAST 66
+#define SPI_SETHIGHCONTRAST 67
+#define SPI_GETKEYBOARDPREF 68
+#define SPI_SETKEYBOARDPREF 69
+#define SPI_GETSCREENREADER 70
+#define SPI_SETSCREENREADER 71
+#define SPI_GETANIMATION 72
+#define SPI_SETANIMATION 73
+#define SPI_GETFONTSMOOTHING 74
+#define SPI_SETFONTSMOOTHING 75
+#define SPI_SETDRAGWIDTH 76
+#define SPI_SETDRAGHEIGHT 77
+#define SPI_SETHANDHELD 78
+#define SPI_GETLOWPOWERTIMEOUT 79
+#define SPI_GETPOWEROFFTIMEOUT 80
+#define SPI_SETLOWPOWERTIMEOUT 81
+#define SPI_SETPOWEROFFTIMEOUT 82
+#define SPI_GETLOWPOWERACTIVE 83
+#define SPI_GETPOWEROFFACTIVE 84
+#define SPI_SETLOWPOWERACTIVE 85
+#define SPI_SETPOWEROFFACTIVE 86
+#define SPI_SETCURSORS 87
+#define SPI_SETICONS 88
+#define SPI_GETDEFAULTINPUTLANG 89
+#define SPI_SETDEFAULTINPUTLANG 90
+#define SPI_SETLANGTOGGLE 91
+#define SPI_GETWINDOWSEXTENSION 92
+#define SPI_SETMOUSETRAILS 93
+#define SPI_GETMOUSETRAILS 94
+#define SPI_SETSCREENSAVERRUNNING 97
+#define SPI_SCREENSAVERRUNNING SPI_SETSCREENSAVERRUNNING
+
+/* defines below are for all win versions (_WIN32_WINNT >= 0x0400) ||
+ * (_WIN32_WINDOWS > 0x0400) */
+#define SPI_GETMOUSEHOVERWIDTH 98
+#define SPI_SETMOUSEHOVERWIDTH 99
+#define SPI_GETMOUSEHOVERHEIGHT 100
+#define SPI_SETMOUSEHOVERHEIGHT 101
+#define SPI_GETMOUSEHOVERTIME 102
+#define SPI_SETMOUSEHOVERTIME 103
+#define SPI_GETWHEELSCROLLLINES 104
+#define SPI_SETWHEELSCROLLLINES 105
+
+#define SPI_GETSHOWIMEUI 110
+#define SPI_SETSHOWIMEUI 111
+
+/* defines below are for all win versions WINVER >= 0x0500 */
+#define SPI_GETMOUSESPEED 112
+#define SPI_SETMOUSESPEED 113
+#define SPI_GETSCREENSAVERRUNNING 114
+
+#define SPI_GETACTIVEWINDOWTRACKING 0x1000
+#define SPI_SETACTIVEWINDOWTRACKING 0x1001
+#define SPI_GETMENUANIMATION 0x1002
+#define SPI_SETMENUANIMATION 0x1003
+#define SPI_GETCOMBOBOXANIMATION 0x1004
+#define SPI_SETCOMBOBOXANIMATION 0x1005
+#define SPI_GETLISTBOXSMOOTHSCROLLING 0x1006
+#define SPI_SETLISTBOXSMOOTHSCROLLING 0x1007
+#define SPI_GETGRADIENTCAPTIONS 0x1008
+#define SPI_SETGRADIENTCAPTIONS 0x1009
+#define SPI_GETMENUUNDERLINES 0x100A
+#define SPI_SETMENUUNDERLINES 0x100B
+#define SPI_GETACTIVEWNDTRKZORDER 0x100C
+#define SPI_SETACTIVEWNDTRKZORDER 0x100D
+#define SPI_GETHOTTRACKING 0x100E
+#define SPI_SETHOTTRACKING 0x100F
+#define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000
+#define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001
+#define SPI_GETACTIVEWNDTRKTIMEOUT 0x2002
+#define SPI_SETACTIVEWNDTRKTIMEOUT 0x2003
+#define SPI_GETFOREGROUNDFLASHCOUNT 0x2004
+#define SPI_SETFOREGROUNDFLASHCOUNT 0x2005
+
+/* SystemParametersInfo flags */
+
+#define SPIF_UPDATEINIFILE 1
+#define SPIF_SENDWININICHANGE 2
+#define SPIF_SENDCHANGE SPIF_SENDWININICHANGE
+
+
+
+
+/* Window Styles */
+#define WS_OVERLAPPED 0x00000000L
+#define WS_POPUP 0x80000000L
+#define WS_CHILD 0x40000000L
+#define WS_MINIMIZE 0x20000000L
+#define WS_VISIBLE 0x10000000L
+#define WS_DISABLED 0x08000000L
+#define WS_CLIPSIBLINGS 0x04000000L
+#define WS_CLIPCHILDREN 0x02000000L
+#define WS_MAXIMIZE 0x01000000L
+#define WS_CAPTION 0x00C00000L
+#define WS_BORDER 0x00800000L
+#define WS_DLGFRAME 0x00400000L
+#define WS_VSCROLL 0x00200000L
+#define WS_HSCROLL 0x00100000L
+#define WS_SYSMENU 0x00080000L
+#define WS_THICKFRAME 0x00040000L
+#define WS_GROUP 0x00020000L
+#define WS_TABSTOP 0x00010000L
+#define WS_MINIMIZEBOX 0x00020000L
+#define WS_MAXIMIZEBOX 0x00010000L
+#define WS_TILED WS_OVERLAPPED
+#define WS_ICONIC WS_MINIMIZE
+#define WS_SIZEBOX WS_THICKFRAME
+#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME| WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
+#define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU)
+#define WS_CHILDWINDOW (WS_CHILD)
+#define WS_TILEDWINDOW (WS_OVERLAPPEDWINDOW)
+
+/* Window extended styles */
+#define WS_EX_DLGMODALFRAME 0x00000001L
+#define WS_EX_DRAGDETECT 0x00000002L
+#define WS_EX_NOPARENTNOTIFY 0x00000004L
+#define WS_EX_TOPMOST 0x00000008L
+#define WS_EX_ACCEPTFILES 0x00000010L
+#define WS_EX_TRANSPARENT 0x00000020L
+
+/* New Win95/WinNT4 styles */
+#define WS_EX_MDICHILD 0x00000040L
+#define WS_EX_TOOLWINDOW 0x00000080L
+#define WS_EX_WINDOWEDGE 0x00000100L
+#define WS_EX_CLIENTEDGE 0x00000200L
+#define WS_EX_CONTEXTHELP 0x00000400L
+#define WS_EX_RIGHT 0x00001000L
+#define WS_EX_LEFT 0x00000000L
+#define WS_EX_RTLREADING 0x00002000L
+#define WS_EX_LTRREADING 0x00000000L
+#define WS_EX_LEFTSCROLLBAR 0x00004000L
+#define WS_EX_RIGHTSCROLLBAR 0x00000000L
+#define WS_EX_CONTROLPARENT 0x00010000L
+#define WS_EX_STATICEDGE 0x00020000L
+#define WS_EX_APPWINDOW 0x00040000L
+
+#define WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE|WS_EX_CLIENTEDGE)
+#define WS_EX_PALETTEWINDOW (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW|WS_EX_TOPMOST)
+
+/* WINE internal... */
+#define WS_EX_TRAYWINDOW 0x80000000L
+
+/* Window scrolling */
+#define SW_SCROLLCHILDREN 0x0001
+#define SW_INVALIDATE 0x0002
+#define SW_ERASE 0x0004
+
+/* CreateWindow() coordinates */
+#define CW_USEDEFAULT ((INT)0x80000000)
+
+/* ChildWindowFromPointEx Flags */
+#define CWP_ALL 0x0000
+#define CWP_SKIPINVISIBLE 0x0001
+#define CWP_SKIPDISABLED 0x0002
+#define CWP_SKIPTRANSPARENT 0x0004
+
+ /* PeekMessage() options */
+#define PM_NOREMOVE 0x0000
+#define PM_REMOVE 0x0001
+#define PM_NOYIELD 0x0002
+
+/* WM_SHOWWINDOW wParam codes */
+#define SW_PARENTCLOSING 1
+#define SW_OTHERMAXIMIZED 2
+#define SW_PARENTOPENING 3
+#define SW_OTHERRESTORED 4
+
+ /* ShowWindow() codes */
+#define SW_HIDE 0
+#define SW_SHOWNORMAL 1
+#define SW_NORMAL 1
+#define SW_SHOWMINIMIZED 2
+#define SW_SHOWMAXIMIZED 3
+#define SW_MAXIMIZE 3
+#define SW_SHOWNOACTIVATE 4
+#define SW_SHOW 5
+#define SW_MINIMIZE 6
+#define SW_SHOWMINNOACTIVE 7
+#define SW_SHOWNA 8
+#define SW_RESTORE 9
+#define SW_SHOWDEFAULT 10
+#define SW_MAX 10
+#define SW_NORMALNA 0xCC /* undoc. flag in MinMaximize */
+
+ /* WM_SIZE message wParam values */
+#define SIZE_RESTORED 0
+#define SIZE_MINIMIZED 1
+#define SIZE_MAXIMIZED 2
+#define SIZE_MAXSHOW 3
+#define SIZE_MAXHIDE 4
+#define SIZENORMAL SIZE_RESTORED
+#define SIZEICONIC SIZE_MINIMIZED
+#define SIZEFULLSCREEN SIZE_MAXIMIZED
+#define SIZEZOOMSHOW SIZE_MAXSHOW
+#define SIZEZOOMHIDE SIZE_MAXHIDE
+
+/* SetWindowPos() and WINDOWPOS flags */
+#define SWP_NOSIZE 0x0001
+#define SWP_NOMOVE 0x0002
+#define SWP_NOZORDER 0x0004
+#define SWP_NOREDRAW 0x0008
+#define SWP_NOACTIVATE 0x0010
+#define SWP_FRAMECHANGED 0x0020 /* The frame changed: send WM_NCCALCSIZE */
+#define SWP_SHOWWINDOW 0x0040
+#define SWP_HIDEWINDOW 0x0080
+#define SWP_NOCOPYBITS 0x0100
+#define SWP_NOOWNERZORDER 0x0200 /* Don't do owner Z ordering */
+
+#define SWP_DRAWFRAME SWP_FRAMECHANGED
+#define SWP_NOREPOSITION SWP_NOOWNERZORDER
+
+#define SWP_NOSENDCHANGING 0x0400
+#define SWP_DEFERERASE 0x2000
+#define SWP_ASYNCWINDOWPOS 0x4000
+
+#define HWND_DESKTOP ((HWND)0)
+#define HWND_BROADCAST ((HWND)0xffff)
+
+/* SetWindowPos() hwndInsertAfter field values */
+#define HWND_TOP ((HWND)0)
+#define HWND_BOTTOM ((HWND)1)
+#define HWND_TOPMOST ((HWND)-1)
+#define HWND_NOTOPMOST ((HWND)-2)
+
+#define MF_INSERT 0x0000
+#define MF_CHANGE 0x0080
+#define MF_APPEND 0x0100
+#define MF_DELETE 0x0200
+#define MF_REMOVE 0x1000
+#define MF_END 0x0080
+
+#define MF_ENABLED 0x0000
+#define MF_GRAYED 0x0001
+#define MF_DISABLED 0x0002
+#define MF_STRING 0x0000
+#define MF_BITMAP 0x0004
+#define MF_UNCHECKED 0x0000
+#define MF_CHECKED 0x0008
+#define MF_POPUP 0x0010
+#define MF_MENUBARBREAK 0x0020
+#define MF_MENUBREAK 0x0040
+#define MF_UNHILITE 0x0000
+#define MF_HILITE 0x0080
+#define MF_OWNERDRAW 0x0100
+#define MF_USECHECKBITMAPS 0x0200
+#define MF_BYCOMMAND 0x0000
+#define MF_BYPOSITION 0x0400
+#define MF_SEPARATOR 0x0800
+#define MF_DEFAULT 0x1000
+#define MF_SYSMENU 0x2000
+#define MF_HELP 0x4000
+#define MF_RIGHTJUSTIFY 0x4000
+#define MF_MOUSESELECT 0x8000
+
+/* Flags for extended menu item types. */
+#define MFT_STRING MF_STRING
+#define MFT_BITMAP MF_BITMAP
+#define MFT_MENUBARBREAK MF_MENUBARBREAK
+#define MFT_MENUBREAK MF_MENUBREAK
+#define MFT_OWNERDRAW MF_OWNERDRAW
+#define MFT_RADIOCHECK 0x00000200L
+#define MFT_SEPARATOR MF_SEPARATOR
+#define MFT_RIGHTORDER 0x00002000L
+#define MFT_RIGHTJUSTIFY MF_RIGHTJUSTIFY
+
+/* Flags for extended menu item states. */
+#define MFS_GRAYED 0x00000003L
+#define MFS_DISABLED MFS_GRAYED
+#define MFS_CHECKED MF_CHECKED
+#define MFS_HILITE MF_HILITE
+#define MFS_ENABLED MF_ENABLED
+#define MFS_UNCHECKED MF_UNCHECKED
+#define MFS_UNHILITE MF_UNHILITE
+#define MFS_DEFAULT MF_DEFAULT
+#define MFS_MASK 0x0000108BL
+#define MFS_HOTTRACKDRAWN 0x10000000L
+#define MFS_CACHEDBMP 0x20000000L
+#define MFS_BOTTOMGAPDROP 0x40000000L
+#define MFS_TOPGAPDROP 0x80000000L
+#define MFS_GAPDROP 0xC0000000L
+
+/* for GetMenuDefaultItem */
+#define GMDI_USEDISABLED 0x0001L
+#define GMDI_GOINTOPOPUPS 0x0002L
+
+#define DT_TOP 0
+#define DT_LEFT 0
+#define DT_CENTER 1
+#define DT_RIGHT 2
+#define DT_VCENTER 4
+#define DT_BOTTOM 8
+#define DT_WORDBREAK 16
+#define DT_SINGLELINE 32
+#define DT_EXPANDTABS 64
+#define DT_TABSTOP 128
+#define DT_NOCLIP 256
+#define DT_EXTERNALLEADING 512
+#define DT_CALCRECT 1024
+#define DT_NOPREFIX 2048
+#define DT_INTERNAL 4096
+
+/* DrawCaption()/DrawCaptionTemp() flags */
+#define DC_ACTIVE 0x0001
+#define DC_SMALLCAP 0x0002
+#define DC_ICON 0x0004
+#define DC_TEXT 0x0008
+#define DC_INBUTTON 0x0010
+
+/* DrawEdge() flags */
+#define BDR_RAISEDOUTER 0x0001
+#define BDR_SUNKENOUTER 0x0002
+#define BDR_RAISEDINNER 0x0004
+#define BDR_SUNKENINNER 0x0008
+
+#define BDR_OUTER 0x0003
+#define BDR_INNER 0x000c
+#define BDR_RAISED 0x0005
+#define BDR_SUNKEN 0x000a
+
+#define EDGE_RAISED (BDR_RAISEDOUTER | BDR_RAISEDINNER)
+#define EDGE_SUNKEN (BDR_SUNKENOUTER | BDR_SUNKENINNER)
+#define EDGE_ETCHED (BDR_SUNKENOUTER | BDR_RAISEDINNER)
+#define EDGE_BUMP (BDR_RAISEDOUTER | BDR_SUNKENINNER)
+
+/* border flags */
+#define BF_LEFT 0x0001
+#define BF_TOP 0x0002
+#define BF_RIGHT 0x0004
+#define BF_BOTTOM 0x0008
+#define BF_DIAGONAL 0x0010
+#define BF_MIDDLE 0x0800 /* Fill in the middle */
+#define BF_SOFT 0x1000 /* For softer buttons */
+#define BF_ADJUST 0x2000 /* Calculate the space left over */
+#define BF_FLAT 0x4000 /* For flat rather than 3D borders */
+#define BF_MONO 0x8000 /* For monochrome borders */
+#define BF_TOPLEFT (BF_TOP | BF_LEFT)
+#define BF_TOPRIGHT (BF_TOP | BF_RIGHT)
+#define BF_BOTTOMLEFT (BF_BOTTOM | BF_LEFT)
+#define BF_BOTTOMRIGHT (BF_BOTTOM | BF_RIGHT)
+#define BF_RECT (BF_LEFT | BF_TOP | BF_RIGHT | BF_BOTTOM)
+#define BF_DIAGONAL_ENDTOPRIGHT (BF_DIAGONAL | BF_TOP | BF_RIGHT)
+#define BF_DIAGONAL_ENDTOPLEFT (BF_DIAGONAL | BF_TOP | BF_LEFT)
+#define BF_DIAGONAL_ENDBOTTOMLEFT (BF_DIAGONAL | BF_BOTTOM | BF_LEFT)
+#define BF_DIAGONAL_ENDBOTTOMRIGHT (BF_DIAGONAL | BF_BOTTOM | BF_RIGHT)
+
+/* DrawFrameControl() uType's */
+
+#define DFC_CAPTION 1
+#define DFC_MENU 2
+#define DFC_SCROLL 3
+#define DFC_BUTTON 4
+
+/* uState's */
+
+#define DFCS_CAPTIONCLOSE 0x0000
+#define DFCS_CAPTIONMIN 0x0001
+#define DFCS_CAPTIONMAX 0x0002
+#define DFCS_CAPTIONRESTORE 0x0003
+#define DFCS_CAPTIONHELP 0x0004 /* Windows 95 only */
+
+#define DFCS_MENUARROW 0x0000
+#define DFCS_MENUCHECK 0x0001
+#define DFCS_MENUBULLET 0x0002
+#define DFCS_MENUARROWRIGHT 0x0004
+
+#define DFCS_SCROLLUP 0x0000
+#define DFCS_SCROLLDOWN 0x0001
+#define DFCS_SCROLLLEFT 0x0002
+#define DFCS_SCROLLRIGHT 0x0003
+#define DFCS_SCROLLCOMBOBOX 0x0005
+#define DFCS_SCROLLSIZEGRIP 0x0008
+#define DFCS_SCROLLSIZEGRIPRIGHT 0x0010
+
+#define DFCS_BUTTONCHECK 0x0000
+#define DFCS_BUTTONRADIOIMAGE 0x0001
+#define DFCS_BUTTONRADIOMASK 0x0002 /* to draw nonsquare button */
+#define DFCS_BUTTONRADIO 0x0004
+#define DFCS_BUTTON3STATE 0x0008
+#define DFCS_BUTTONPUSH 0x0010
+
+/* additional state of the control */
+
+#define DFCS_INACTIVE 0x0100
+#define DFCS_PUSHED 0x0200
+#define DFCS_CHECKED 0x0400
+#define DFCS_ADJUSTRECT 0x2000 /* exclude surrounding edge */
+#define DFCS_FLAT 0x4000
+#define DFCS_MONO 0x8000
+
+/* Image type */
+#define DST_COMPLEX 0x0000
+#define DST_TEXT 0x0001
+#define DST_PREFIXTEXT 0x0002
+#define DST_ICON 0x0003
+#define DST_BITMAP 0x0004
+
+/* State type */
+#define DSS_NORMAL 0x0000
+#define DSS_UNION 0x0010 /* Gray string appearance */
+#define DSS_DISABLED 0x0020
+#define DSS_DEFAULT 0x0040 /* Make it bold */
+#define DSS_MONO 0x0080
+#define DSS_RIGHT 0x8000
+
+typedef struct
+{
+ UINT CtlType;
+ UINT CtlID;
+ UINT itemID;
+ UINT itemAction;
+ UINT itemState;
+ HWND hwndItem;
+ HDC hDC;
+ RECT rcItem WINE_PACKED;
+ DWORD itemData WINE_PACKED;
+} DRAWITEMSTRUCT, *PDRAWITEMSTRUCT, *LPDRAWITEMSTRUCT;
+
+
+typedef struct
+{
+ UINT CtlType;
+ UINT CtlID;
+ UINT itemID;
+ UINT itemWidth;
+ UINT itemHeight;
+ DWORD itemData;
+} MEASUREITEMSTRUCT, *PMEASUREITEMSTRUCT, *LPMEASUREITEMSTRUCT;
+
+
+typedef struct
+{
+ UINT CtlType;
+ UINT CtlID;
+ UINT itemID;
+ HWND hwndItem;
+ DWORD itemData;
+} DELETEITEMSTRUCT, *LPDELETEITEMSTRUCT;
+
+
+typedef struct
+{
+ UINT CtlType;
+ UINT CtlID;
+ HWND hwndItem;
+ UINT itemID1;
+ DWORD itemData1;
+ UINT itemID2;
+ DWORD itemData2;
+ DWORD dwLocaleId;
+} COMPAREITEMSTRUCT, *PCOMPAREITEMSTRUCT, *LPCOMPAREITEMSTRUCT;
+
+
+/* WM_KEYUP/DOWN/CHAR HIWORD(lParam) flags */
+#define KF_EXTENDED 0x0100
+#define KF_DLGMODE 0x0800
+#define KF_MENUMODE 0x1000
+#define KF_ALTDOWN 0x2000
+#define KF_REPEAT 0x4000
+#define KF_UP 0x8000
+
+/* Virtual key codes */
+#define VK_LBUTTON 0x01
+#define VK_RBUTTON 0x02
+#define VK_CANCEL 0x03
+#define VK_MBUTTON 0x04
+/* 0x05-0x07 Undefined */
+#define VK_BACK 0x08
+#define VK_TAB 0x09
+/* 0x0A-0x0B Undefined */
+#define VK_CLEAR 0x0C
+#define VK_RETURN 0x0D
+/* 0x0E-0x0F Undefined */
+#define VK_SHIFT 0x10
+#define VK_CONTROL 0x11
+#define VK_MENU 0x12
+#define VK_PAUSE 0x13
+#define VK_CAPITAL 0x14
+/* 0x15-0x19 Reserved for Kanji systems */
+/* 0x1A Undefined */
+#define VK_ESCAPE 0x1B
+/* 0x1C-0x1F Reserved for Kanji systems */
+#define VK_SPACE 0x20
+#define VK_PRIOR 0x21
+#define VK_NEXT 0x22
+#define VK_END 0x23
+#define VK_HOME 0x24
+#define VK_LEFT 0x25
+#define VK_UP 0x26
+#define VK_RIGHT 0x27
+#define VK_DOWN 0x28
+#define VK_SELECT 0x29
+#define VK_PRINT 0x2A /* OEM specific in Windows 3.1 SDK */
+#define VK_EXECUTE 0x2B
+#define VK_SNAPSHOT 0x2C
+#define VK_INSERT 0x2D
+#define VK_DELETE 0x2E
+#define VK_HELP 0x2F
+#define VK_0 0x30
+#define VK_1 0x31
+#define VK_2 0x32
+#define VK_3 0x33
+#define VK_4 0x34
+#define VK_5 0x35
+#define VK_6 0x36
+#define VK_7 0x37
+#define VK_8 0x38
+#define VK_9 0x39
+/* 0x3A-0x40 Undefined */
+#define VK_A 0x41
+#define VK_B 0x42
+#define VK_C 0x43
+#define VK_D 0x44
+#define VK_E 0x45
+#define VK_F 0x46
+#define VK_G 0x47
+#define VK_H 0x48
+#define VK_I 0x49
+#define VK_J 0x4A
+#define VK_K 0x4B
+#define VK_L 0x4C
+#define VK_M 0x4D
+#define VK_N 0x4E
+#define VK_O 0x4F
+#define VK_P 0x50
+#define VK_Q 0x51
+#define VK_R 0x52
+#define VK_S 0x53
+#define VK_T 0x54
+#define VK_U 0x55
+#define VK_V 0x56
+#define VK_W 0x57
+#define VK_X 0x58
+#define VK_Y 0x59
+#define VK_Z 0x5A
+
+#define VK_LWIN 0x5B
+#define VK_RWIN 0x5C
+#define VK_APPS 0x5D
+/* 0x5E-0x5F Unassigned */
+#define VK_NUMPAD0 0x60
+#define VK_NUMPAD1 0x61
+#define VK_NUMPAD2 0x62
+#define VK_NUMPAD3 0x63
+#define VK_NUMPAD4 0x64
+#define VK_NUMPAD5 0x65
+#define VK_NUMPAD6 0x66
+#define VK_NUMPAD7 0x67
+#define VK_NUMPAD8 0x68
+#define VK_NUMPAD9 0x69
+#define VK_MULTIPLY 0x6A
+#define VK_ADD 0x6B
+#define VK_SEPARATOR 0x6C
+#define VK_SUBTRACT 0x6D
+#define VK_DECIMAL 0x6E
+#define VK_DIVIDE 0x6F
+#define VK_F1 0x70
+#define VK_F2 0x71
+#define VK_F3 0x72
+#define VK_F4 0x73
+#define VK_F5 0x74
+#define VK_F6 0x75
+#define VK_F7 0x76
+#define VK_F8 0x77
+#define VK_F9 0x78
+#define VK_F10 0x79
+#define VK_F11 0x7A
+#define VK_F12 0x7B
+#define VK_F13 0x7C
+#define VK_F14 0x7D
+#define VK_F15 0x7E
+#define VK_F16 0x7F
+#define VK_F17 0x80
+#define VK_F18 0x81
+#define VK_F19 0x82
+#define VK_F20 0x83
+#define VK_F21 0x84
+#define VK_F22 0x85
+#define VK_F23 0x86
+#define VK_F24 0x87
+/* 0x88-0x8F Unassigned */
+#define VK_NUMLOCK 0x90
+#define VK_SCROLL 0x91
+/* 0x92-0x9F Unassigned */
+/*
+ * differencing between right and left shift/control/alt key.
+ * Used only by GetAsyncKeyState() and GetKeyState().
+ */
+#define VK_LSHIFT 0xA0
+#define VK_RSHIFT 0xA1
+#define VK_LCONTROL 0xA2
+#define VK_RCONTROL 0xA3
+#define VK_LMENU 0xA4
+#define VK_RMENU 0xA5
+/* 0xA6-0xB9 Unassigned */
+#define VK_OEM_1 0xBA
+#define VK_OEM_PLUS 0xBB
+#define VK_OEM_COMMA 0xBC
+#define VK_OEM_MINUS 0xBD
+#define VK_OEM_PERIOD 0xBE
+#define VK_OEM_2 0xBF
+#define VK_OEM_3 0xC0
+/* 0xC1-0xDA Unassigned */
+#define VK_OEM_4 0xDB
+#define VK_OEM_5 0xDC
+#define VK_OEM_6 0xDD
+#define VK_OEM_7 0xDE
+/* 0xDF-0xE4 OEM specific */
+
+#define VK_PROCESSKEY 0xE5
+
+/* 0xE6 OEM specific */
+/* 0xE7-0xE8 Unassigned */
+/* 0xE9-0xF5 OEM specific */
+
+#define VK_ATTN 0xF6
+#define VK_CRSEL 0xF7
+#define VK_EXSEL 0xF8
+#define VK_EREOF 0xF9
+#define VK_PLAY 0xFA
+#define VK_ZOOM 0xFB
+#define VK_NONAME 0xFC
+#define VK_PA1 0xFD
+#define VK_OEM_CLEAR 0xFE
+
+ /* Key status flags for mouse events */
+#define MK_LBUTTON 0x0001
+#define MK_RBUTTON 0x0002
+#define MK_SHIFT 0x0004
+#define MK_CONTROL 0x0008
+#define MK_MBUTTON 0x0010
+
+ /* Queue status flags */
+#define QS_KEY 0x0001
+#define QS_MOUSEMOVE 0x0002
+#define QS_MOUSEBUTTON 0x0004
+#define QS_MOUSE (QS_MOUSEMOVE | QS_MOUSEBUTTON)
+#define QS_POSTMESSAGE 0x0008
+#define QS_TIMER 0x0010
+#define QS_PAINT 0x0020
+#define QS_SENDMESSAGE 0x0040
+#define QS_HOTKEY 0x0080
+#define QS_INPUT (QS_MOUSE | QS_KEY)
+#define QS_ALLEVENTS (QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY)
+#define QS_ALLINPUT (QS_ALLEVENTS | QS_SENDMESSAGE)
+
+#define DDL_READWRITE 0x0000
+#define DDL_READONLY 0x0001
+#define DDL_HIDDEN 0x0002
+#define DDL_SYSTEM 0x0004
+#define DDL_DIRECTORY 0x0010
+#define DDL_ARCHIVE 0x0020
+
+#define DDL_POSTMSGS 0x2000
+#define DDL_DRIVES 0x4000
+#define DDL_EXCLUSIVE 0x8000
+
+ /* Shell hook values */
+#define HSHELL_WINDOWCREATED 1
+#define HSHELL_WINDOWDESTROYED 2
+#define HSHELL_ACTIVATESHELLWINDOW 3
+
+/* Predefined Clipboard Formats */
+#define CF_TEXT 1
+#define CF_BITMAP 2
+#define CF_METAFILEPICT 3
+#define CF_SYLK 4
+#define CF_DIF 5
+#define CF_TIFF 6
+#define CF_OEMTEXT 7
+#define CF_DIB 8
+#define CF_PALETTE 9
+#define CF_PENDATA 10
+#define CF_RIFF 11
+#define CF_WAVE 12
+#define CF_ENHMETAFILE 14
+#define CF_HDROP 15
+#define CF_LOCALE 16
+#define CF_MAX 17
+
+#define CF_OWNERDISPLAY 0x0080
+#define CF_DSPTEXT 0x0081
+#define CF_DSPBITMAP 0x0082
+#define CF_DSPMETAFILEPICT 0x0083
+
+/* "Private" formats don't get GlobalFree()'d */
+#define CF_PRIVATEFIRST 0x0200
+#define CF_PRIVATELAST 0x02FF
+
+/* "GDIOBJ" formats do get DeleteObject()'d */
+#define CF_GDIOBJFIRST 0x0300
+#define CF_GDIOBJLAST 0x03FF
+
+
+/* DragObject stuff */
+
+typedef struct
+{
+ HWND16 hWnd;
+ HANDLE16 hScope;
+ WORD wFlags;
+ HANDLE16 hList;
+ HANDLE16 hOfStruct;
+ POINT16 pt WINE_PACKED;
+ LONG l WINE_PACKED;
+} DRAGINFO, *LPDRAGINFO;
+
+#define DRAGOBJ_PROGRAM 0x0001
+#define DRAGOBJ_DATA 0x0002
+#define DRAGOBJ_DIRECTORY 0x0004
+#define DRAGOBJ_MULTIPLE 0x0008
+#define DRAGOBJ_EXTERNAL 0x8000
+
+#define DRAG_PRINT 0x544E5250
+#define DRAG_FILE 0x454C4946
+
+/* types of LoadImage */
+#define IMAGE_BITMAP 0
+#define IMAGE_ICON 1
+#define IMAGE_CURSOR 2
+#define IMAGE_ENHMETAFILE 3
+
+/* loadflags to LoadImage */
+#define LR_DEFAULTCOLOR 0x0000
+#define LR_MONOCHROME 0x0001
+#define LR_COLOR 0x0002
+#define LR_COPYRETURNORG 0x0004
+#define LR_COPYDELETEORG 0x0008
+#define LR_LOADFROMFILE 0x0010
+#define LR_LOADTRANSPARENT 0x0020
+#define LR_DEFAULTSIZE 0x0040
+#define LR_VGA_COLOR 0x0080
+#define LR_LOADMAP3DCOLORS 0x1000
+#define LR_CREATEDIBSECTION 0x2000
+#define LR_COPYFROMRESOURCE 0x4000
+#define LR_SHARED 0x8000
+
+/* Flags for DrawIconEx. */
+#define DI_MASK 1
+#define DI_IMAGE 2
+#define DI_NORMAL (DI_MASK | DI_IMAGE)
+#define DI_COMPAT 4
+#define DI_DEFAULTSIZE 8
+
+ /* misc messages */
+#define WM_CPL_LAUNCH (WM_USER + 1000)
+#define WM_CPL_LAUNCHED (WM_USER + 1001)
+
+/* WM_NOTIFYFORMAT commands and return values */
+#define NFR_ANSI 1
+#define NFR_UNICODE 2
+#define NF_QUERY 3
+#define NF_REQUERY 4
+
+#include "poppack.h"
+#define EnumTaskWindows(handle,proc,lparam) \
+ EnumThreadWindows(handle,proc,lparam)
+#define OemToAnsiA OemToCharA
+#define OemToAnsiW OemToCharW
+#define OemToAnsi WINELIB_NAME_AW(OemToAnsi)
+#define OemToAnsiBuffA OemToCharBuffA
+#define OemToAnsiBuffW OemToCharBuffW
+#define OemToAnsiBuff WINELIB_NAME_AW(OemToAnsiBuff)
+#define AnsiToOemA CharToOemA
+#define AnsiToOemW CharToOemW
+#define AnsiToOem WINELIB_NAME_AW(AnsiToOem)
+#define AnsiToOemBuffA CharToOemBuffA
+#define AnsiToOemBuffW CharToOemBuffW
+#define AnsiToOemBuff WINELIB_NAME_AW(AnsiToOemBuff)
+/* NOTE: This is SYSTEM.3, not USER.182, which is also named KillSystemTimer */
+WORD WINAPI SYSTEM_KillSystemTimer( WORD );
+
+/* Extra functions that don't exist in the Windows API */
+
+HPEN WINAPI GetSysColorPen(INT);
+INT WINAPI LoadMessageA(HMODULE,UINT,WORD,LPSTR,INT);
+INT WINAPI LoadMessageW(HMODULE,UINT,WORD,LPWSTR,INT);
+
+VOID WINAPI ScreenSwitchEnable16(WORD);
+
+#define WC_DIALOG (LPSTR)((DWORD)((WORD)( 0x8002)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WINUSER_ */
diff --git a/src/libw32dll/wineacm.h b/src/libw32dll/wineacm.h
new file mode 100644
index 000000000..f215d754d
--- /dev/null
+++ b/src/libw32dll/wineacm.h
@@ -0,0 +1,55 @@
+/* -*- tab-width: 8; c-basic-offset: 4 -*- */
+
+/***********************************************************************
+ * Wine specific - Win32
+ */
+typedef struct _WINE_ACMDRIVERID *PWINE_ACMDRIVERID;
+typedef struct _WINE_ACMDRIVER *PWINE_ACMDRIVER;
+
+typedef struct _WINE_ACMOBJ
+{
+ PWINE_ACMDRIVERID pACMDriverID;
+} WINE_ACMOBJ, *PWINE_ACMOBJ;
+
+typedef struct _WINE_ACMDRIVER
+{
+ WINE_ACMOBJ obj;
+ HDRVR hDrvr;
+ DRIVERPROC pfnDriverProc;
+ PWINE_ACMDRIVER pNextACMDriver;
+} WINE_ACMDRIVER;
+
+typedef struct _WINE_ACMSTREAM
+{
+ WINE_ACMOBJ obj;
+ PWINE_ACMDRIVER pDrv;
+ ACMDRVSTREAMINSTANCE drvInst;
+ HACMDRIVER hAcmDriver;
+} WINE_ACMSTREAM, *PWINE_ACMSTREAM;
+
+typedef struct _WINE_ACMDRIVERID
+{
+ LPSTR pszDriverAlias;
+ LPSTR pszFileName;
+ HINSTANCE hInstModule; /* NULL if global */
+ DWORD dwProcessID; /* ID of process which installed a local driver */
+ WIN_BOOL bEnabled;
+ PWINE_ACMDRIVER pACMDriverList;
+ PWINE_ACMDRIVERID pNextACMDriverID;
+ PWINE_ACMDRIVERID pPrevACMDriverID;
+} WINE_ACMDRIVERID;
+
+/* From internal.c */
+extern HANDLE MSACM_hHeap;
+extern PWINE_ACMDRIVERID MSACM_pFirstACMDriverID;
+extern PWINE_ACMDRIVERID MSACM_pLastACMDriverID;
+PWINE_ACMDRIVERID MSACM_RegisterDriver(
+ LPSTR pszDriverAlias, LPSTR pszFileName,
+ HINSTANCE hinstModule);
+void MSACM_RegisterAllDrivers(void);
+PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p);
+void MSACM_UnregisterAllDrivers(void);
+PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID);
+PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver);
+PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj);
+
diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am
new file mode 100644
index 000000000..993659dc1
--- /dev/null
+++ b/src/xine-engine/Makefile.am
@@ -0,0 +1,82 @@
+##
+## Process this file with automake to produce Makefile.in
+##
+
+CFLAGS = @GLOBAL_CFLAGS@
+
+lib_LTLIBRARIES = libxine.la
+
+if HAVE_W32DLL
+W32_LIBS = $(top_srcdir)/src/libw32dll/libw32dll.la
+endif
+
+##libxine_la_SOURCES = xine.c buffer.c metronom.c configfile.c \
+## monitor.c utils.c audio_decoder.c video_decoder.c load_plugins.c
+libxine_la_SOURCES = metronom.c configfile.c monitor.c utils.c cpu_accel.c
+libxine_la_DEPENDENCIES = libsdeps
+libxine_la_LIBADD = \
+ $(top_srcdir)/src/demuxers/libdemux.la \
+ $(top_srcdir)/src/libmpeg2/libmpeg2.la \
+ $(top_srcdir)/src/libac3/libac3.la \
+ $(top_srcdir)/src/libmpg123/libmpg123.la \
+ $(W32_LIBS) \
+## $(top_srcdir)/src/libspudec/libspudec.la \
+ $(THREAD_LIBS) \
+ $(DYNAMIC_LD_LIBS)
+ -lXext -lm
+libxine_la_LDFLAGS = -version-info 5:0:5
+
+include_HEADERS = buffer.h metronom.h configfile.h \
+ monitor.h cpu_accel.h attributes.h utils.h audio_decoder.h \
+ video_decoder.h
+noinst_HEADERS = xine_internal.h
+
+cpu_accel.lo:
+ $(CC) -DHAVE_CONFIG_H $(INCLUDES) -pipe `echo "@DEBUG_CFLAGS@" | sed -e 's/\-DDEBUG//' -e 's/\-g//'` -fomit-frame-pointer -Wall -Wp,-MD,.deps/cpu_accel.P -c $(basename $@).c -o $@
+# echo timestamp > $(basename $@).o
+
+
+debug:
+ $(MAKE) CFLAGS="$(DEBUG_CFLAGS)"
+
+
+libsdeps:
+## @cd $(top_builddir)/src/demuxers && $(MAKE) libdemux.la
+## @cd $(top_builddir)/src/libmpeg2 && $(MAKE) libmpeg2.la
+## @cd $(top_builddir)/src/libac3 && $(MAKE) libac3.la
+## @cd $(top_builddir)/src/libmpg123 && $(MAKE) libmpg123.la
+##@W32DLL_DEP@ @cd $(top_builddir)/src/libw32dll && $(MAKE) libw32dll.la
+## @cd $(top_builddir)/src/libspudec && $(MAKE) libspudec.la
+
+
+##
+## Install header files (default=$includedir/xine)
+##
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)/xine
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p; \
+ done
+
+
+##
+## Remove them
+##
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/xine/$$p; \
+ done
+
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/xine-engine/attributes.h b/src/xine-engine/attributes.h
new file mode 100644
index 000000000..8ed7aef9e
--- /dev/null
+++ b/src/xine-engine/attributes.h
@@ -0,0 +1,27 @@
+/*
+ * attributes.h
+ * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+//use gcc attribs to align critical data structures
+#ifdef ATTRIBUTE_ALIGNED_MAX
+#define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align)))
+#else
+#define ATTR_ALIGN(align)
+#endif
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
new file mode 100644
index 000000000..f879093e0
--- /dev/null
+++ b/src/xine-engine/audio_decoder.c
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: audio_decoder.c,v 1.1 2001/04/18 22:36:01 f1rmb Exp $
+ *
+ *
+ * functions that implement audio decoding
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "audio_decoder.h"
+
+#define MAX_NUM_DECODERS 10
+
+typedef struct ad_globals_s {
+
+ pthread_t mAudioThread;
+
+ fifo_buffer_t *mBufAudio;
+
+ audio_decoder_t *mDecoders[MAX_NUM_DECODERS];
+ audio_decoder_t *mCurDecoder;
+
+ uint32_t mnCurPos;
+
+ ao_instance_t *mAudioOut
+
+ gui_status_callback_func_t gui_status_callback;
+
+ int mbStreamFinished;
+
+ pthread_mutex_t mXineLock;
+
+} ad_globals_t;
+
+static ad_globals_t gAD;
+
+
+void *audio_decoder_loop (void *dummy) {
+
+ buf_element_t *pBuf;
+ int bRunning = 1;
+
+ while (bRunning) {
+
+ pBuf = gAD.mBufAudio->fifo_buffer_get (gAD.mBufAudio);
+
+ if (gAD.mAudioOut) {
+
+ gAD.mnCurPos = pBuf->nInputPos;
+
+ /*
+ if (gXine.mnStatus == XINE_PLAY)
+ gXine.mStatusCallback (gXine.mnStatus);
+ */
+
+ switch (pBuf->nType) {
+
+ case BUF_STREAMSTART:
+ if (gAD.mCurDecoder) {
+ gAD.mCurDecoder->close ();
+ gAD.mCurDecoder = NULL;
+ }
+
+ pthread_mutex_lock (&gAD.mXineLock);
+ gAD.mbStreamFinished = 0;
+ pthread_mutex_unlock (&gAD.mXineLock);
+
+ break;
+
+ case BUF_AC3AUDIO:
+ case BUF_MPEGAUDIO:
+ case BUF_MSAUDIO:
+ case BUF_LINEARPCM:
+
+ decoder = gAD.mDecoders [pBuf->nType];
+
+ if (decoder) {
+ if (gAD.mCurDecoder != decoder) {
+
+ if (gAD.mCurDecoder)
+ gAD.mCurDecoder->close ();
+
+ gAD.mCurDecoder = decoder;
+ gAD.mCurDecoder->init (gAD.mVideoOut);
+
+ }
+
+ decoder->decode_data (pBuf);
+ }
+
+ break;
+
+ case BUF_STREAMEND:
+ if (gAD.mCurDecoder) {
+ gAD.mCurDecoder->close ();
+ gAD.mCurDecoder = NULL;
+ }
+
+ gAD.mbStreamFinished = 1;
+
+ pthread_mutex_lock (&gAD.mXineLock);
+
+ gVD.mbStreamFinished = 1;
+
+ if (video_decoder_is_stream_finished ()) {
+ pthread_mutex_unlock (&gAD.mXineLock);
+ xine_notify_stream_finished ();
+ } else
+ pthread_mutex_unlock (&gAD.mXineLock);
+
+ break;
+
+ case BUF_QUIT:
+ if (gAD.mCurDecoder) {
+ gAD.mCurDecoder->close ();
+ gAD.mCurDecoder = NULL;
+ }
+ bRunning = 0;
+ break;
+
+ }
+ }
+ pBuf->free_buffer (pBuf);
+ }
+
+ return NULL;
+}
+
+int audio_decoder_is_stream_finished () {
+ return gAD.mbStreamFinished ;
+}
+
+uint32_t audio_decoder_get_pos () {
+ return gAD.mnCurPos;
+}
+
+fifo_buffer_t *audio_decoder_init (ao_instance_t *audio_out,
+ pthread_mutex_t xine_lock) {
+
+ gAD.mAudioOut = audio_out;
+ gAD.mXineLock = xine_lock;
+
+ gAD.mCurDecoder = NULL;
+ for (i=0; i<MAX_NUM_DECODERS; i++)
+ gAD.mDecoders[i] = NULL;
+
+ gAD.mDecoders[BUF_AC3AUDIO] = init_audio_decoder_ac3dec ();
+ gAD.mDecoders[BUF_MPEGAUDIO] = init_audio_decoder_mpg123 ();
+ gAD.mDecoders[BUF_MSAUDIO] = init_audio_decoder_msaudio ();
+ gAD.mDecoders[BUF_LINEARPCM] = init_audio_decoder_linearpcm ();
+
+ gAD.mBufAudio = fifo_buffer_new ();
+
+ pthread_create (&gAD.mAudioThread, NULL, audio_decoder_loop, NULL) ;
+
+ printf ("audio_decoder_init: audio thread created\n");
+
+ return gAD.mBufAudio;
+}
+
+void audio_decoder_shutdown () {
+
+ buf_element_t *pBuf;
+
+ gAD.mBufAudio->fifo_buffer_clear(gAD.mBufAudio);
+
+ pBuf = gAD.mBufAudio->buffer_pool_alloc ();
+ pBuf->nType = BUF_QUIT;
+ gAD.mBufAudio->fifo_buffer_put (gAD.mBufAudio, pBuf);
+
+ pthread_join (gAD.mAudioThread, &p);
+}
+
+
diff --git a/src/xine-engine/audio_decoder.h b/src/xine-engine/audio_decoder.h
new file mode 100644
index 000000000..b7d6e4243
--- /dev/null
+++ b/src/xine-engine/audio_decoder.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: audio_decoder.h,v 1.1 2001/04/18 22:36:05 f1rmb Exp $
+ *
+ *
+ * functions that implement audio decoding
+ */
+
+#ifndef HAVE_VIDEO_DECODER_H
+#define VIDEO_DECODER_H
+
+#include "buffer.h"
+
+/*
+ * generic xine audio decoder plugin interface
+ */
+
+typedef struct audio_decoder_s
+{
+
+ /* get interface version */
+ int (*get_version) (void);
+
+ int (*can_handle) (int buf_type);
+
+ void (*init) (ao_instance_t *audio_out);
+
+ void (*decode_data) (buf_element_t *buf);
+
+ void (*close) (void);
+
+} audio_decoder_t;
+
+/*
+ * init audio decoders, allocate audio fifo,
+ * start audio decoder thread
+ */
+
+fifo_buffer_t *audio_decoder_init (ao_instance_t *audio_out,
+ pthread_mutex_t xine_lock) ;
+
+/*
+ * quit audio thread
+ */
+
+void audio_decoder_shutdown ();
+
+
+#endif
diff --git a/src/xine-engine/buffer.c b/src/xine-engine/buffer.c
new file mode 100644
index 000000000..c45a93cb6
--- /dev/null
+++ b/src/xine-engine/buffer.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: buffer.c,v 1.1 2001/04/18 22:36:01 f1rmb Exp $
+ *
+ *
+ * contents:
+ *
+ * buffer_entry structure - serves as a transport encapsulation
+ * of the mpeg audio/video data through xine
+ *
+ * free buffer pool management routines
+ *
+ * FIFO buffer structures/routines
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "buffer.h"
+#include "utils.h"
+
+/*
+ * global variables
+ */
+
+buf_element_t *gBufferPoolTop; /* a stack actually */
+pthread_mutex_t gBufferPoolMutex;
+pthread_cond_t gBufferPoolCondNotEmpty;
+int gBufferPoolNumFree;
+
+/*
+ * put a previously allocated buffer element back into the buffer pool
+ */
+static void buffer_pool_free (buf_element_t *pBufElement) {
+
+ pthread_mutex_lock (&gBufferPoolMutex);
+
+ pBufElement->next = gBufferPoolTop;
+ gBufferPoolTop = pBufElement;
+
+ gBufferPoolNumFree++;
+
+ pthread_cond_signal (&gBufferPoolCondNotEmpty);
+
+ pthread_mutex_unlock (&gBufferPoolMutex);
+}
+
+/*
+ * check if there are no more free elements
+ */
+static int buffer_pool_isempty (void) {
+ return gBufferPoolNumFree<7;
+}
+
+/*
+ * check if there are no more free elements
+ */
+static buf_element_t *buffer_pool_alloc (void) {
+
+ buf_element_t *pBuf;
+
+ pthread_mutex_lock (&gBufferPoolMutex);
+
+ while (!gBufferPoolTop) {
+ pthread_cond_wait (&gBufferPoolCondNotEmpty, &gBufferPoolMutex);
+ }
+
+ pBuf = gBufferPoolTop;
+ gBufferPoolTop = gBufferPoolTop->next;
+ gBufferPoolNumFree--;
+
+ pthread_mutex_unlock (&gBufferPoolMutex);
+
+ return pBuf;
+}
+
+/*
+ * append buffer element to fifo buffer
+ */
+static void fifo_buffer_put (fifo_buffer_t *pFifo, buf_element_t *pBufElement) {
+
+ pthread_mutex_lock (&pFifo->mMutex);
+
+ if (pFifo->mpLast)
+ pFifo->mpLast->next = pBufElement;
+ else
+ pFifo->mpFirst = pBufElement;
+
+ pFifo->mpLast = pBufElement;
+ pBufElement->next = NULL;
+
+ pthread_cond_signal (&pFifo->mNotEmpty);
+
+ pthread_mutex_unlock (&pFifo->mMutex);
+}
+
+/*
+ * get element from fifo buffer
+ */
+static buf_element_t *fifo_buffer_get (fifo_buffer_t *pFifo) {
+
+ buf_element_t *pBuf;
+
+ pthread_mutex_lock (&pFifo->mMutex);
+
+ while (pFifo->mpFirst==NULL) {
+ pthread_cond_wait (&pFifo->mNotEmpty, &pFifo->mMutex);
+ }
+
+ pBuf = pFifo->mpFirst;
+
+ pFifo->mpFirst = pFifo->mpFirst->next;
+ if (pFifo->mpFirst==NULL)
+ pFifo->mpLast = NULL;
+
+ pthread_mutex_unlock (&pFifo->mMutex);
+
+ return pBuf;
+}
+
+/*
+ * clear buffer (put all contained buffer elements back into buffer pool)
+ */
+static void fifo_buffer_clear (fifo_buffer_t *pFifo) {
+
+ buf_element_t *pBuf;
+
+ pthread_mutex_lock (&pFifo->mMutex);
+
+ while (pFifo->mpFirst != NULL) {
+
+ pBuf = pFifo->mpFirst;
+
+ pFifo->mpFirst = pFifo->mpFirst->next;
+ if (pFifo->mpFirst==NULL)
+ pFifo->mpLast = NULL;
+
+ buffer_pool_free (pBuf);
+ }
+
+ pthread_mutex_unlock (&pFifo->mMutex);
+}
+
+/*
+ * allocate and initialize new (empty) fifo buffer
+ */
+static fifo_buffer_t *fifo_buffer_new (void) {
+
+ fifo_buffer_t *pFifo;
+
+ pFifo = xmalloc (sizeof (fifo_buffer_t));
+
+ pFifo->mpFirst = NULL;
+ pFifo->mpLast = NULL;
+ pFifo->fifo_buffer_put = fifo_buffer_put;
+ pFifo->fifo_buffer_get = fifo_buffer_get;
+ pFifo->fifo_buffer_clear = fifo_buffer_clear;
+
+ pthread_mutex_init (&pFifo->mMutex, NULL);
+ pthread_cond_init (&pFifo->mNotEmpty, NULL);
+
+ return pFifo;
+}
+
+/*
+ * init buffer pool, allocate nNumBuffers of buf_size bytes each
+ */
+fifobuf_functions_t *buffer_pool_init (int nNumBuffers, uint32_t buf_size) {
+
+ int i;
+ const int alignment = 2048;
+ char *pMultiBuffer = NULL;
+
+ if ((buf_size % alignment) == 0) {
+ printf ("Allocating %d buffers of %ld bytes in one chunk (alignment = %d)\n", nNumBuffers, (long int)buf_size, alignment);
+ pMultiBuffer = xmalloc_aligned (alignment, nNumBuffers * buf_size);
+ }
+
+ gBufferPoolTop = NULL;
+
+ pthread_mutex_init (&gBufferPoolMutex, NULL);
+ pthread_cond_init (&gBufferPoolCondNotEmpty, NULL);
+
+ for (i = 0; i<nNumBuffers; i++) {
+ buf_element_t *pBuf;
+
+ pBuf = xmalloc (sizeof (buf_element_t));
+
+ if (pMultiBuffer != NULL) {
+ pBuf->pMem = pMultiBuffer;
+ pMultiBuffer += buf_size;
+ }
+ else
+ pBuf->pMem = malloc_aligned (buf_size, alignment);
+
+ pBuf->nMaxSize = buf_size;
+ pBuf->free_buffer = buffer_pool_free;
+
+ buffer_pool_free (pBuf);
+ }
+ gBufferPoolNumFree = nNumBuffers;
+
+ return &fifobuf_op;
+}
diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h
new file mode 100644
index 000000000..a57d219ba
--- /dev/null
+++ b/src/xine-engine/buffer.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: buffer.h,v 1.1 2001/04/18 22:36:05 f1rmb Exp $
+ *
+ *
+ * contents:
+ *
+ * buffer_entry structure - serves as a transport encapsulation
+ * of the mpeg audio/video data through xine
+ *
+ * free buffer pool management routines
+ *
+ * FIFO buffer structures/routines
+ *
+ */
+
+#ifndef HAVE_BUFFER_H
+#define HAVE_BUFFER_H
+
+#include <stdio.h>
+#include <pthread.h>
+#include <inttypes.h>
+
+/*
+ * buffer types
+ *
+ * a buffer type ID describes the contents of a buffer
+ * it consists of three fields:
+ *
+ * buf_type = 0xMMDDCCCC
+ *
+ * MM : major buffer type (CONTROL, VIDEO, AUDIO, SPU)
+ * DD : decoder selection (e.g. MPEG, OPENDIVX ... for VIDEO)
+ * CCCC : channel number or other subtype information for the decoder
+ */
+
+#define BUF_MAJOR_MASK 0xFF000000
+#define BUF_DECODER_MASK 0x00FF0000
+
+/* control buffer types */
+
+#define BUF_CONTROL_BASE 0x01000000
+#define BUF_CONTROL_START 0x01000000
+#define BUF_CONTROL_END 0x01000001
+#define BUF_CONTROL_QUIT 0x01000002
+
+/* video buffer types: */
+
+#define BUF_VIDEO_BASE 0x02000000
+#define BUF_VIDEO_MPEG 0x02000000
+#define BUF_VIDEO_OPENDIVX 0x02010000
+#define BUF_VIDEO_QUICKTIME 0x02020000
+#define BUF_VIDEO_AVI 0x02030000
+
+/* audio buffer types: */
+
+#define BUF_AUDIO_BASE 0x03000000
+#define BUF_AUDIO_AC3 0x03000000
+#define BUF_AUDIO_MPEG 0x03010000
+#define BUF_AUDIO_LPCM 0x03020000
+#define BUF_AUDIO_AVI 0x03030000
+
+/* spu buffer types: */
+
+#define BUF_SPU_BASE 0x04000000
+#define BUF_SPU_CLUT 0x04000000
+#define BUF_SPU_PACKAGE 0x04010000
+
+
+typedef struct buf_element_s buf_element_t;
+struct buf_element_s {
+ buf_element_t *next;
+
+ unsigned char *mem;
+ unsigned char *content; /* start of raw content in pMem (without header etc) */
+
+ uint32_t size ; /* size of _content_ */
+ uint32_t max_size;
+ uint32_t type;
+ uint32_t PTS, DTS;
+ off_t input_pos; /* remember where this buf came from in the input source */
+ int frame_end; /* avi */
+
+ void (*free_buffer) (buf_element_t *buf);
+
+} ;
+
+typedef struct fifo_buffer_s fifo_buffer_t;
+struct fifo_buffer_s
+{
+ buf_element_t *first, *last;
+
+ pthread_mutex_t mutex;
+ pthread_cond_t not_empty;
+
+ /*
+ * functions to access this fifo:
+ */
+
+ void (*put) (fifo_buffer_t *fifo, buf_element_t *buf);
+
+ buf_element_t *(*get) (fifo_buffer_t *fifo);
+
+ void (*clear) (fifo_buffer_t *fifo) ;
+
+ /*
+ * alloc buffer for this fifo from global buf pool
+ * you don't have to use this function to allocate a buffer,
+ * an input plugin can decide to implement it's own
+ * buffer allocation functions
+ */
+
+ buf_element_t *(*buffer_pool_alloc) (void);
+
+} ;
+
+/*
+ * allocate and initialize new (empty) fifo buffer
+ */
+
+fifo_buffer_t *fifo_buffer_new (void);
+
+/*
+ * init global buffer pool,
+ * allocate nNumBuffers of buf_size bytes each
+ */
+
+void buffer_pool_init (int num_buffers, uint32_t buf_size);
+
+#endif
diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c
new file mode 100644
index 000000000..1903db791
--- /dev/null
+++ b/src/xine-engine/configfile.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: configfile.c,v 1.1 2001/04/18 22:36:01 f1rmb Exp $
+ *
+ * config file management - implementation
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "configfile.h"
+#include "utils.h"
+
+typedef struct cfg_entry_s {
+ struct cfg_entry_s *next;
+ char *key, *value;
+} cfg_entry_t;
+
+struct cfg_data_s {
+ cfg_entry_t *gConfig, *gConfigLast;
+};
+
+
+
+/*
+ * internal utility functions
+ *******************************/
+
+void config_file_add (config_values_t *this, char *key, char *value) {
+
+ cfg_entry_t *entry;
+ int len;
+
+ entry = (cfg_entry_t *) xmalloc (sizeof (cfg_entry_t));
+
+ len = strlen (key);
+ entry->key = (char *) xmalloc (len+2);
+ strncpy (entry->key, key, len+1);
+
+ len = strlen (value);
+ entry->value = (char *) xmalloc (len+21);
+ strncpy (entry->value, value, len+1);
+
+ entry->next = NULL;
+
+ if (this->data->gConfigLast)
+ this->data->gConfigLast->next = entry;
+ else
+ this->data->gConfig = entry;
+
+ this->data->gConfigLast = entry;
+
+}
+
+
+
+
+cfg_entry_t *config_file_search (config_values_t *this, char *key) {
+ cfg_entry_t *entry;
+
+ entry = this->data->gConfig;
+
+ while (entry && strcmp (entry->key, key))
+ entry = entry->next;
+
+ return entry;
+}
+
+
+
+/*
+ * external interface
+ ***********************/
+
+static char *config_file_lookup_str (config_values_t *this,
+ char *key, char*str_default) {
+ cfg_entry_t *entry;
+
+ entry = config_file_search (this, key);
+
+ if (entry)
+ return entry->value;
+
+ config_file_add (this, key, str_default);
+
+ return str_default;
+}
+
+
+
+
+static int config_file_lookup_int (config_values_t *this,
+ char *key, int n_default) {
+
+ cfg_entry_t *entry;
+ char str[25];
+
+ entry = config_file_search (this, key);
+
+ if (entry) {
+ int n;
+
+ if (sscanf (entry->value, "%d", &n) == 1)
+ return n;
+ }
+
+ sprintf (str, "%d", n_default);
+
+ config_file_add (this, key, str);
+
+ return n_default;
+}
+
+
+
+
+static void config_file_set_int (config_values_t *this,
+ char *key, int value) {
+
+ cfg_entry_t *entry;
+
+ entry = config_file_search (this, key);
+
+ if (entry) {
+ sprintf (entry->value, "%d", value);
+ }
+ else {
+ char str[25];
+ sprintf (str, "%d", value);
+
+ config_file_add (this, key, str);
+ }
+}
+
+
+
+
+static void config_file_set_str (config_values_t *this,
+ char *key, char *value) {
+
+ cfg_entry_t *entry;
+
+ entry = config_file_search (this, key);
+
+ if (entry) {
+ int len;
+
+ free (entry->value);
+
+ len = strlen (value);
+ entry->value = (char *) xmalloc (len+20);
+ strncpy (entry->value, value, len);
+
+ }
+ else {
+ config_file_add (this, key, value);
+ }
+}
+
+
+
+
+static void config_file_save (config_values_t *this) {
+ FILE *f_config;
+ char filename[1024];
+
+ sprintf (filename, "%s/.xinerc", get_homedir());
+
+ f_config = fopen (filename, "w");
+
+ if (f_config) {
+
+ cfg_entry_t *entry;
+
+ fprintf (f_config, "#\n# xine config file\n#\n");
+
+ entry = this->data->gConfig;
+
+ while (entry) {
+ fprintf (f_config, "%s:%s\n",entry->key,entry->value);
+ entry = entry->next;
+ }
+
+ fclose (f_config);
+ }
+}
+
+
+
+
+static void config_file_read (config_values_t *this, char *filename){
+
+ FILE *f_config;
+
+ f_config = fopen (filename, "r");
+
+ if (f_config) {
+
+ char line[1024];
+ char *value;
+
+ while (fgets (line, 1023, f_config)) {
+ line[strlen(line)-1]= (char) 0; /* eliminate lf */
+
+ if (line[0] == '#')
+ continue;
+
+ if ((value = strchr (line, ':'))) {
+ *value = (char) 0;
+ value++;
+
+ config_file_add (this, line, value);
+ }
+
+ }
+
+ fclose (f_config);
+ }
+}
+
+
+
+
+config_values_t *config_file_init (char *filename) {
+
+ config_values_t *this;
+ cfg_data_t *data;
+
+ if ( (this = xmalloc(sizeof(config_values_t))) ) {
+ if ( (data = xmalloc(sizeof(cfg_data_t))) ) {
+ data->gConfig = NULL;
+ data->gConfigLast = NULL;
+ this->data = data;
+ config_file_read (this, filename);
+
+ }
+ else {
+ fprintf (stderr, "WARNING: could not allocate config data\n");
+ }
+ }
+ else {
+ fprintf (stderr, "WARNING: could not allocate config values list\n");
+ }
+
+ this->lookup_str = config_file_lookup_str;
+ this->lookup_int = config_file_lookup_int;
+ this->set_str = config_file_set_str;
+ this->set_int = config_file_set_int;
+ this->save = config_file_save;
+ this->read = config_file_read;
+
+ return this;
+}
+
+
+/*
+ * $Log: configfile.c,v $
+ * Revision 1.1 2001/04/18 22:36:01 f1rmb
+ * Initial revision
+ *
+ * Revision 1.8 2001/03/31 03:42:25 guenter
+ * more cleanups, started xv driver
+ *
+ * Revision 1.7 2001/03/28 12:30:25 siggi
+ * fixed init function
+ * added read function (multiple config files now supported)
+ *
+ * Revision 1.6 2001/03/27 17:12:49 siggi
+ * made config file handler a dynamic "object"
+ *
+ */
diff --git a/src/xine-engine/configfile.h b/src/xine-engine/configfile.h
new file mode 100644
index 000000000..1e5de7be9
--- /dev/null
+++ b/src/xine-engine/configfile.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: configfile.h,v 1.1 2001/04/18 22:36:05 f1rmb Exp $
+ *
+ * config file management
+ *
+ */
+
+
+#ifndef HAVE_CONFIGFILE_H
+#define HAVE_CONFIGFILE_H
+
+#include <inttypes.h>
+
+typedef struct config_values_s config_values_t;
+typedef struct cfg_data_s cfg_data_t;
+
+struct config_values_s {
+ /*
+ * lookup config values
+ */
+ char* (*lookup_str) (config_values_t *this,
+ char *key, char *str_default);
+
+ int (*lookup_int) (config_values_t *this,
+ char *key, int n_default);
+
+ /*
+ * set config values
+ */
+
+ void (*set_str) (config_values_t *this,
+ char *key, char *value) ;
+
+ void (*set_int) (config_values_t *this,
+ char *key, int value) ;
+
+ /*
+ * write config file to disk
+ */
+ void (*save) (config_values_t *this);
+
+ /*
+ * read config file from disk, ovverriding values in memory
+ * if you also want to clear values that are not in the file,
+ * use _init instead!
+ */
+ void (*read) (config_values_t *this, char *filename);
+
+ /*
+ * contains private data of this config file
+ */
+ cfg_data_t *data;
+};
+
+/*
+ * init internal data structures, read config file
+ * (if it exists)
+ */
+config_values_t *config_file_init (char *filename);
+
+
+#endif
+
+/*
+ * $Log: configfile.h,v $
+ * Revision 1.1 2001/04/18 22:36:05 f1rmb
+ * Initial revision
+ *
+ * Revision 1.6 2001/03/31 03:42:25 guenter
+ * more cleanups, started xv driver
+ *
+ * Revision 1.5 2001/03/28 12:30:25 siggi
+ * fixed init function
+ * added read function (multiple config files now supported)
+ *
+ * Revision 1.4 2001/03/27 21:49:02 siggi
+ * started touching demuxers
+ *
+ */
+
+
+
+
diff --git a/src/xine-engine/cpu_accel.c b/src/xine-engine/cpu_accel.c
new file mode 100644
index 000000000..bd3a55fc0
--- /dev/null
+++ b/src/xine-engine/cpu_accel.c
@@ -0,0 +1,110 @@
+/*
+ * cpu_accel.c
+ * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include <inttypes.h>
+
+#include "attributes.h"
+#include "cpu_accel.h"
+
+#ifdef ARCH_X86
+static uint32_t x86_accel (void)
+{
+ uint32_t eax, ebx, ecx, edx;
+ int AMD;
+ uint32_t caps;
+
+#define cpuid(op,eax,ebx,ecx,edx) \
+ asm ("cpuid" \
+ : "=a" (eax), \
+ "=b" (ebx), \
+ "=c" (ecx), \
+ "=d" (edx) \
+ : "a" (op) \
+ : "cc")
+
+ asm ("pushfl\n\t"
+ "popl %0\n\t"
+ "movl %0,%1\n\t"
+ "xorl $0x200000,%0\n\t"
+ "pushl %0\n\t"
+ "popfl\n\t"
+ "pushfl\n\t"
+ "popl %0"
+ : "=a" (eax),
+ "=b" (ebx)
+ :
+ : "cc");
+
+ if (eax == ebx) /* no cpuid */
+ return 0;
+
+ cpuid (0x00000000, eax, ebx, ecx, edx);
+ if (!eax) /* vendor string only */
+ return 0;
+
+ AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65);
+
+ cpuid (0x00000001, eax, ebx, ecx, edx);
+ if (! (edx & 0x00800000)) /* no MMX */
+ return 0;
+
+ caps = MM_ACCEL_X86_MMX;
+ if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */
+ caps = MM_ACCEL_X86_MMX | MM_ACCEL_X86_MMXEXT;
+
+ cpuid (0x80000000, eax, ebx, ecx, edx);
+ if (eax < 0x80000001) /* no extended capabilities */
+ return caps;
+
+ cpuid (0x80000001, eax, ebx, ecx, edx);
+
+ if (edx & 0x80000000)
+ caps |= MM_ACCEL_X86_3DNOW;
+
+ if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */
+ caps |= MM_ACCEL_X86_MMXEXT;
+
+ return caps;
+}
+#endif
+
+uint32_t mm_accel (void)
+{
+#ifdef ARCH_X86
+ static int got_accel = 0;
+ static uint32_t accel;
+
+ if (!got_accel) {
+ got_accel = 1;
+ accel = x86_accel ();
+ }
+
+ return accel;
+#else
+#ifdef HAVE_MLIB
+ return MM_ACCEL_MLIB;
+#else
+ return 0;
+#endif
+#endif
+}
diff --git a/src/xine-engine/cpu_accel.h b/src/xine-engine/cpu_accel.h
new file mode 100644
index 000000000..9583b6681
--- /dev/null
+++ b/src/xine-engine/cpu_accel.h
@@ -0,0 +1,514 @@
+/*
+ * cpu_accel.h - based on mmx.h, sse.h
+ * Copyright (C) 1997-1999 H. Dietz and R. Fisher
+ *
+ * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
+ *
+ * mpeg2dec is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * mpeg2dec is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * xine specific modifications 2001 by G. Bartsch
+ *
+ */
+
+/*
+ * The type of an value that fits in an MMX register (note that long
+ * long constant values MUST be suffixed by LL and unsigned long long
+ * values by ULL, lest they be truncated by the compiler)
+ */
+
+#ifndef _CPU_ACCEL_H
+#define _CPU_ACCEL_H
+
+#include "attributes.h"
+
+/* generic accelerations */
+#define MM_ACCEL_MLIB 0x00000001
+
+/* x86 accelerations */
+#define MM_ACCEL_X86_MMX 0x80000000
+#define MM_ACCEL_X86_3DNOW 0x40000000
+#define MM_ACCEL_X86_MMXEXT 0x20000000
+
+uint32_t mm_accel (void) ;
+
+#ifdef ARCH_X86
+
+typedef union {
+ long long q; /* Quadword (64-bit) value */
+ unsigned long long uq; /* Unsigned Quadword */
+ int d[2]; /* 2 Doubleword (32-bit) values */
+ unsigned int ud[2]; /* 2 Unsigned Doubleword */
+ short w[4]; /* 4 Word (16-bit) values */
+ unsigned short uw[4]; /* 4 Unsigned Word */
+ char b[8]; /* 8 Byte (8-bit) values */
+ unsigned char ub[8]; /* 8 Unsigned Byte */
+ float s[2]; /* Single-precision (32-bit) value */
+} ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */
+
+
+
+#define mmx_i2r(op,imm,reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define mmx_m2r(op,mem,reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define mmx_r2m(op,reg,mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ )
+
+#define mmx_r2r(op,regs,regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+
+#define emms() __asm__ __volatile__ ("emms")
+
+#define movd_m2r(var,reg) mmx_m2r (movd, var, reg)
+#define movd_r2m(reg,var) mmx_r2m (movd, reg, var)
+#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd)
+
+#define movq_m2r(var,reg) mmx_m2r (movq, var, reg)
+#define movq_r2m(reg,var) mmx_r2m (movq, reg, var)
+#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd)
+
+#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg)
+#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd)
+#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg)
+#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd)
+
+#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg)
+#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd)
+
+#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg)
+#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd)
+#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg)
+#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd)
+#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg)
+#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd)
+
+#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg)
+#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd)
+#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg)
+#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd)
+
+#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg)
+#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd)
+#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg)
+#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd)
+
+#define pand_m2r(var,reg) mmx_m2r (pand, var, reg)
+#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd)
+
+#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg)
+#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd)
+
+#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg)
+#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd)
+#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg)
+#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd)
+#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg)
+#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd)
+
+#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg)
+#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd)
+#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg)
+#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd)
+#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg)
+#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd)
+
+#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg)
+#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd)
+
+#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg)
+#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd)
+
+#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg)
+#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd)
+
+#define por_m2r(var,reg) mmx_m2r (por, var, reg)
+#define por_r2r(regs,regd) mmx_r2r (por, regs, regd)
+
+#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg)
+#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg)
+#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd)
+#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg)
+#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg)
+#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd)
+#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg)
+#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg)
+#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd)
+
+#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg)
+#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg)
+#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd)
+#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg)
+#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg)
+#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd)
+
+#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg)
+#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg)
+#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd)
+#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg)
+#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg)
+#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd)
+#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg)
+#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg)
+#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd)
+
+#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg)
+#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd)
+#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg)
+#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd)
+#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg)
+#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd)
+
+#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg)
+#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd)
+#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg)
+#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd)
+
+#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg)
+#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd)
+#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg)
+#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd)
+
+#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg)
+#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd)
+#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg)
+#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd)
+#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg)
+#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd)
+
+#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg)
+#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd)
+#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg)
+#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd)
+#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg)
+#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd)
+
+#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg)
+#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd)
+
+
+/* 3DNOW extensions */
+
+#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg)
+#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd)
+
+
+/* AMD MMX extensions - also available in intel SSE */
+
+
+#define mmx_m2ri(op,mem,reg,imm) \
+ __asm__ __volatile__ (#op " %1, %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem), "X" (imm))
+#define mmx_r2ri(op,regs,regd,imm) \
+ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define mmx_fetch(mem,hint) \
+ __asm__ __volatile__ ("prefetch" #hint " %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+
+#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg)
+
+#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var)
+
+#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg)
+#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd)
+#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg)
+#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd)
+
+#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm)
+
+#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm)
+
+#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg)
+#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd)
+
+#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg)
+#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd)
+
+#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg)
+#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd)
+
+#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg)
+#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd)
+
+#define pmovmskb(mmreg,reg) \
+ __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
+
+#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg)
+#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd)
+
+#define prefetcht0(mem) mmx_fetch (mem, t0)
+#define prefetcht1(mem) mmx_fetch (mem, t1)
+#define prefetcht2(mem) mmx_fetch (mem, t2)
+#define prefetchnta(mem) mmx_fetch (mem, nta)
+
+#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg)
+#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd)
+
+#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm)
+#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm)
+
+#define sfence() __asm__ __volatile__ ("sfence\n\t")
+
+typedef union {
+ float sf[4]; /* Single-precision (32-bit) value */
+} ATTR_ALIGN(16) sse_t; /* On a 16 byte (128-bit) boundary */
+
+
+#define sse_i2r(op, imm, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define sse_m2r(op, mem, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define sse_r2m(op, reg, mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=X" (mem) \
+ : /* nothing */ )
+
+#define sse_r2r(op, regs, regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+#define sse_r2ri(op, regs, regd, imm) \
+ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
+ : /* nothing */ \
+ : "X" (imm) )
+
+#define sse_m2ri(op, mem, reg, subop) \
+ __asm__ __volatile__ (#op " %0, %%" #reg ", " #subop \
+ : /* nothing */ \
+ : "X" (mem))
+
+
+#define movaps_m2r(var, reg) sse_m2r(movaps, var, reg)
+#define movaps_r2m(reg, var) sse_r2m(movaps, reg, var)
+#define movaps_r2r(regs, regd) sse_r2r(movaps, regs, regd)
+
+#define movntps_r2m(xmmreg, var) sse_r2m(movntps, xmmreg, var)
+
+#define movups_m2r(var, reg) sse_m2r(movups, var, reg)
+#define movups_r2m(reg, var) sse_r2m(movups, reg, var)
+#define movups_r2r(regs, regd) sse_r2r(movups, regs, regd)
+
+#define movhlps_r2r(regs, regd) sse_r2r(movhlps, regs, regd)
+
+#define movlhps_r2r(regs, regd) sse_r2r(movlhps, regs, regd)
+
+#define movhps_m2r(var, reg) sse_m2r(movhps, var, reg)
+#define movhps_r2m(reg, var) sse_r2m(movhps, reg, var)
+
+#define movlps_m2r(var, reg) sse_m2r(movlps, var, reg)
+#define movlps_r2m(reg, var) sse_r2m(movlps, reg, var)
+
+#define movss_m2r(var, reg) sse_m2r(movss, var, reg)
+#define movss_r2m(reg, var) sse_r2m(movss, reg, var)
+#define movss_r2r(regs, regd) sse_r2r(movss, regs, regd)
+
+#define shufps_m2r(var, reg, index) sse_m2ri(shufps, var, reg, index)
+#define shufps_r2r(regs, regd, index) sse_r2ri(shufps, regs, regd, index)
+
+#define cvtpi2ps_m2r(var, xmmreg) sse_m2r(cvtpi2ps, var, xmmreg)
+#define cvtpi2ps_r2r(mmreg, xmmreg) sse_r2r(cvtpi2ps, mmreg, xmmreg)
+
+#define cvtps2pi_m2r(var, mmreg) sse_m2r(cvtps2pi, var, mmreg)
+#define cvtps2pi_r2r(xmmreg, mmreg) sse_r2r(cvtps2pi, mmreg, xmmreg)
+
+#define cvttps2pi_m2r(var, mmreg) sse_m2r(cvttps2pi, var, mmreg)
+#define cvttps2pi_r2r(xmmreg, mmreg) sse_r2r(cvttps2pi, mmreg, xmmreg)
+
+#define cvtsi2ss_m2r(var, xmmreg) sse_m2r(cvtsi2ss, var, xmmreg)
+#define cvtsi2ss_r2r(reg, xmmreg) sse_r2r(cvtsi2ss, reg, xmmreg)
+
+#define cvtss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg)
+#define cvtss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg)
+
+#define cvttss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg)
+#define cvttss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg)
+
+#define movmskps(xmmreg, reg) \
+ __asm__ __volatile__ ("movmskps %" #xmmreg ", %" #reg)
+
+#define addps_m2r(var, reg) sse_m2r(addps, var, reg)
+#define addps_r2r(regs, regd) sse_r2r(addps, regs, regd)
+
+#define addss_m2r(var, reg) sse_m2r(addss, var, reg)
+#define addss_r2r(regs, regd) sse_r2r(addss, regs, regd)
+
+#define subps_m2r(var, reg) sse_m2r(subps, var, reg)
+#define subps_r2r(regs, regd) sse_r2r(subps, regs, regd)
+
+#define subss_m2r(var, reg) sse_m2r(subss, var, reg)
+#define subss_r2r(regs, regd) sse_r2r(subss, regs, regd)
+
+#define mulps_m2r(var, reg) sse_m2r(mulps, var, reg)
+#define mulps_r2r(regs, regd) sse_r2r(mulps, regs, regd)
+
+#define mulss_m2r(var, reg) sse_m2r(mulss, var, reg)
+#define mulss_r2r(regs, regd) sse_r2r(mulss, regs, regd)
+
+#define divps_m2r(var, reg) sse_m2r(divps, var, reg)
+#define divps_r2r(regs, regd) sse_r2r(divps, regs, regd)
+
+#define divss_m2r(var, reg) sse_m2r(divss, var, reg)
+#define divss_r2r(regs, regd) sse_r2r(divss, regs, regd)
+
+#define rcpps_m2r(var, reg) sse_m2r(rcpps, var, reg)
+#define rcpps_r2r(regs, regd) sse_r2r(rcpps, regs, regd)
+
+#define rcpss_m2r(var, reg) sse_m2r(rcpss, var, reg)
+#define rcpss_r2r(regs, regd) sse_r2r(rcpss, regs, regd)
+
+#define rsqrtps_m2r(var, reg) sse_m2r(rsqrtps, var, reg)
+#define rsqrtps_r2r(regs, regd) sse_r2r(rsqrtps, regs, regd)
+
+#define rsqrtss_m2r(var, reg) sse_m2r(rsqrtss, var, reg)
+#define rsqrtss_r2r(regs, regd) sse_r2r(rsqrtss, regs, regd)
+
+#define sqrtps_m2r(var, reg) sse_m2r(sqrtps, var, reg)
+#define sqrtps_r2r(regs, regd) sse_r2r(sqrtps, regs, regd)
+
+#define sqrtss_m2r(var, reg) sse_m2r(sqrtss, var, reg)
+#define sqrtss_r2r(regs, regd) sse_r2r(sqrtss, regs, regd)
+
+#define andps_m2r(var, reg) sse_m2r(andps, var, reg)
+#define andps_r2r(regs, regd) sse_r2r(andps, regs, regd)
+
+#define andnps_m2r(var, reg) sse_m2r(andnps, var, reg)
+#define andnps_r2r(regs, regd) sse_r2r(andnps, regs, regd)
+
+#define orps_m2r(var, reg) sse_m2r(orps, var, reg)
+#define orps_r2r(regs, regd) sse_r2r(orps, regs, regd)
+
+#define xorps_m2r(var, reg) sse_m2r(xorps, var, reg)
+#define xorps_r2r(regs, regd) sse_r2r(xorps, regs, regd)
+
+#define maxps_m2r(var, reg) sse_m2r(maxps, var, reg)
+#define maxps_r2r(regs, regd) sse_r2r(maxps, regs, regd)
+
+#define maxss_m2r(var, reg) sse_m2r(maxss, var, reg)
+#define maxss_r2r(regs, regd) sse_r2r(maxss, regs, regd)
+
+#define minps_m2r(var, reg) sse_m2r(minps, var, reg)
+#define minps_r2r(regs, regd) sse_r2r(minps, regs, regd)
+
+#define minss_m2r(var, reg) sse_m2r(minss, var, reg)
+#define minss_r2r(regs, regd) sse_r2r(minss, regs, regd)
+
+#define cmpps_m2r(var, reg, op) sse_m2ri(cmpps, var, reg, op)
+#define cmpps_r2r(regs, regd, op) sse_r2ri(cmpps, regs, regd, op)
+
+#define cmpeqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 0)
+#define cmpeqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 0)
+
+#define cmpltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 1)
+#define cmpltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 1)
+
+#define cmpleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 2)
+#define cmpleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 2)
+
+#define cmpunordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 3)
+#define cmpunordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 3)
+
+#define cmpneqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 4)
+#define cmpneqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 4)
+
+#define cmpnltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 5)
+#define cmpnltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 5)
+
+#define cmpnleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 6)
+#define cmpnleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 6)
+
+#define cmpordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 7)
+#define cmpordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 7)
+
+#define cmpss_m2r(var, reg, op) sse_m2ri(cmpss, var, reg, op)
+#define cmpss_r2r(regs, regd, op) sse_r2ri(cmpss, regs, regd, op)
+
+#define cmpeqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 0)
+#define cmpeqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 0)
+
+#define cmpltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 1)
+#define cmpltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 1)
+
+#define cmpless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 2)
+#define cmpless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 2)
+
+#define cmpunordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 3)
+#define cmpunordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 3)
+
+#define cmpneqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 4)
+#define cmpneqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 4)
+
+#define cmpnltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 5)
+#define cmpnltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 5)
+
+#define cmpnless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 6)
+#define cmpnless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 6)
+
+#define cmpordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 7)
+#define cmpordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 7)
+
+#define comiss_m2r(var, reg) sse_m2r(comiss, var, reg)
+#define comiss_r2r(regs, regd) sse_r2r(comiss, regs, regd)
+
+#define ucomiss_m2r(var, reg) sse_m2r(ucomiss, var, reg)
+#define ucomiss_r2r(regs, regd) sse_r2r(ucomiss, regs, regd)
+
+#define unpcklps_m2r(var, reg) sse_m2r(unpcklps, var, reg)
+#define unpcklps_r2r(regs, regd) sse_r2r(unpcklps, regs, regd)
+
+#define unpckhps_m2r(var, reg) sse_m2r(unpckhps, var, reg)
+#define unpckhps_r2r(regs, regd) sse_r2r(unpckhps, regs, regd)
+
+#define fxrstor(mem) \
+ __asm__ __volatile__ ("fxrstor %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define fxsave(mem) \
+ __asm__ __volatile__ ("fxsave %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define stmxcsr(mem) \
+ __asm__ __volatile__ ("stmxcsr %0" \
+ : /* nothing */ \
+ : "X" (mem))
+
+#define ldmxcsr(mem) \
+ __asm__ __volatile__ ("ldmxcsr %0" \
+ : /* nothing */ \
+ : "X" (mem))
+#endif /*ARCH_X86 */
+
+#endif
+
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
new file mode 100644
index 000000000..4984566db
--- /dev/null
+++ b/src/xine-engine/load_plugins.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: load_plugins.c,v 1.1 2001/04/18 22:36:09 f1rmb Exp $
+ *
+ *
+ * Load input/demux/audio_out/video_out plugins
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <dlfcn.h>
+
+#include "xine.h"
+#include "xine_internal.h"
+#include "demuxers/demux.h"
+#include "input/input_plugin.h"
+#include "metronom.h"
+#include "configfile.h"
+#include "monitor.h"
+
+/* debugging purposes only */
+extern uint32_t xine_debug;
+
+/*
+ *
+ */
+void xine_load_demux_plugins (xine_t *this) {
+ DIR *dir;
+
+ this->demuxer_plugins[0] = *(init_demux_mpeg (xine_debug));
+ this->demuxer_plugins[1] = *(init_demux_mpeg_block (xine_debug));
+ this->demuxer_plugins[2] = *(init_demux_avi (xine_debug));
+ this->demuxer_plugins[3] = *(init_demux_mpeg_audio (xine_debug));
+ this->demuxer_plugins[4] = *(init_demux_mpeg_elem (xine_debug));
+ this->num_demuxer_plugins = 5;
+
+ dir = opendir (XINE_DEMUXDIR) ;
+
+ if (dir) {
+ struct dirent *pEntry;
+
+ while ((pEntry = readdir (dir)) != NULL) {
+ char str[1024];
+ void *plugin;
+
+ int nLen = strlen (pEntry->d_name);
+
+ if ((strncasecmp(pEntry->d_name, "demux_", 6) == 0) &&
+ ((pEntry->d_name[nLen-3]=='.')
+ && (pEntry->d_name[nLen-2]=='s')
+ && (pEntry->d_name[nLen-1]=='o'))) {
+
+ /*
+ * demux plugin found => load it
+ */
+
+ sprintf (str, "%s/%s", XINE_DEMUXDIR, pEntry->d_name);
+
+ if(!(plugin = dlopen (str, RTLD_LAZY))) {
+ fprintf(stderr, "%s(%d): %s doesn't seem to be installed (%s)\n",
+ __FILE__, __LINE__, str, dlerror());
+ exit(1);
+ }
+ else {
+ void *(*getinfo) (fifobuf_functions_t *, uint32_t);
+
+ if((getinfo = dlsym(plugin, "demux_plugin_getinfo")) != NULL) {
+ demux_functions_t *dxp;
+
+ dxp = (demux_functions_t *) getinfo(this->fifo_funcs, xine_debug);
+ dxp->handle = plugin;
+ dxp->filename = str;
+ this->demuxer_plugins[this->num_demuxer_plugins] = *dxp;
+
+
+ printf("demux plugin found : %s(%s)\n",
+ this->demuxer_plugins[this->num_demuxer_plugins].filename,
+ pEntry->d_name);
+
+ this->num_demuxer_plugins++;
+ }
+
+ if(this->num_demuxer_plugins > DEMUXER_PLUGIN_MAX) {
+ fprintf(stderr, "%s(%d): too many demux plugins installed, "
+ "exiting.\n", __FILE__, __LINE__);
+ exit(1);
+ }
+ }
+ }
+ }
+ }
+
+ if (this->num_demuxer_plugins == 5)
+ printf ("No extra demux plugins found in %s\n", XINE_DEMUXDIR);
+
+ /*
+ * init demuxer
+ */
+
+ this->cur_demuxer_plugin = NULL;
+}
+
+/*
+ *
+ */
+void xine_load_input_plugins (xine_t *this) {
+ DIR *dir;
+
+ this->num_input_plugins = 0;
+
+ dir = opendir (XINE_PLUGINDIR) ;
+
+ if (dir) {
+ struct dirent *pEntry;
+
+ while ((pEntry = readdir (dir)) != NULL) {
+
+ char str[1024];
+ void *plugin;
+
+ int nLen = strlen (pEntry->d_name);
+
+ if ((strncasecmp(pEntry->d_name, "input_", 6) == 0) &&
+ ((pEntry->d_name[nLen-3]=='.')
+ && (pEntry->d_name[nLen-2]=='s')
+ && (pEntry->d_name[nLen-1]=='o'))) {
+
+ /*
+ * input plugin found => load it
+ */
+
+ sprintf (str, "%s/%s", XINE_PLUGINDIR, pEntry->d_name);
+
+ if(!(plugin = dlopen (str, RTLD_LAZY))) {
+ fprintf(stderr, "%s(%d): %s doesn't seem to be installed (%s)\n",
+ __FILE__, __LINE__, str, dlerror());
+ exit(1);
+ }
+ else {
+ void *(*getinfo) (uint32_t);
+
+ if((getinfo = dlsym(plugin, "input_plugin_getinfo")) != NULL) {
+ input_plugin_t *ipp;
+
+ ipp = (input_plugin_t *) getinfo(xine_debug);
+ ipp->handle = plugin;
+ ipp->filename = str;
+ this->input_plugins[this->num_input_plugins] = *ipp;
+
+ this->input_plugins[this->num_input_plugins].init();
+
+ printf("input plugin found : %s(%s)\n",
+ this->input_plugins[this->num_input_plugins].filename,
+ pEntry->d_name);
+
+ this->num_input_plugins++;
+
+ }
+
+ if(this->num_input_plugins > INPUT_PLUGIN_MAX) {
+ fprintf(stderr, "%s(%d): too many input plugins installed, "
+ "exiting.\n", __FILE__, __LINE__);
+ exit(1);
+ }
+ }
+ }
+ }
+ }
+
+ if (this->num_input_plugins == 0) {
+ printf ("No input plugins found in %s! - "
+ "Did you install xine correctly??\n", XINE_PLUGINDIR);
+ exit (1);
+ }
+
+}
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
new file mode 100644
index 000000000..e71f2b8b6
--- /dev/null
+++ b/src/xine-engine/metronom.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: metronom.c,v 1.1 2001/04/18 22:36:04 f1rmb Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/time.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <math.h>
+
+#include "monitor.h"
+#include "xine.h"
+#include "xine_internal.h"
+#include "metronom.h"
+#include "utils.h"
+
+#define MAX_PTS_TOLERANCE 5000
+#define MAX_VIDEO_DELTA 1600
+#define AUDIO_SAMPLE_NUM 32768
+
+static void metronom_reset (metronom_t *this) {
+
+ this->video_vpts = 0;
+ this->audio_vpts = 0;
+
+ this->video_pts_delta = 0;
+ this->audio_pts_delta = 0;
+
+ this->last_video_pts = 0;
+ this->num_video_vpts_guessed = 1;
+ this->num_audio_samples_guessed = 1;
+
+ this->sync_pts = 0;
+ this->sync_vpts = 0;
+
+ this->av_offset = 0;
+
+ this->stopped = 1;
+}
+
+static void metronom_set_video_rate (metronom_t *this, uint32_t pts_per_frame) {
+ this->pts_per_frame = pts_per_frame;
+}
+
+static uint32_t metronom_get_video_rate (metronom_t *this) {
+ return this->pts_per_frame + this->video_pts_delta;
+}
+
+static void metronom_set_audio_rate (metronom_t *this, uint32_t pts_per_smpls) {
+ this->pts_per_smpls = pts_per_smpls;
+
+ xprintf (METRONOM | VERBOSE, "metronom: %d pts per %d samples\n", pts_per_smpls, AUDIO_SAMPLE_NUM);
+
+}
+
+static uint32_t metronom_got_spu_packet (metronom_t *this, uint32_t pts) {
+ /* FIXME: Nasty hack */
+
+ return this->sync_pts;
+}
+
+static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts) {
+
+ uint32_t vpts;
+
+ if (pts) {
+
+ /*
+ * calc delta to compensate wrong framerates
+ */
+
+ if (this->last_video_vpts && (pts>this->last_video_pts)) {
+ int32_t vpts_diff;
+ uint32_t synced_vpts ;
+ int32_t diff;
+
+ diff = pts - this->last_video_pts;
+ synced_vpts = this->last_video_vpts + diff;
+ vpts_diff = synced_vpts - this->video_vpts;
+
+ this->video_pts_delta += vpts_diff / (this->num_video_vpts_guessed);
+
+ if (abs(this->video_pts_delta) >= MAX_VIDEO_DELTA)
+ this->video_pts_delta = 0;
+
+ this->num_video_vpts_guessed = 0;
+ /* printf ("delta: %d\n", this->video_pts_delta); */
+ }
+
+ /*
+ * sync if necessary and possible
+ */
+
+ if (this->sync_vpts && (pts>this->sync_pts)) {
+
+ int32_t vpts_diff;
+ uint32_t synced_vpts ;
+ int32_t diff;
+
+ diff = pts - this->sync_pts;
+ synced_vpts = this->sync_vpts + diff;
+ vpts_diff = synced_vpts - this->video_vpts;
+
+ xprintf (METRONOM | VERBOSE, "metronom: video calced vpts : %d <=> synced vpts : %d (diff: %d, delta: %d)\n",
+ this->video_vpts, synced_vpts, vpts_diff, this->video_pts_delta);
+
+ if (abs(vpts_diff)>MAX_PTS_TOLERANCE) {
+ if (synced_vpts>this->video_vpts) {
+ this->video_vpts = synced_vpts;
+ }
+ } else
+ xprintf (METRONOM | VERBOSE, "metronom: video tolerating diff\n");
+
+ } else
+ xprintf (METRONOM | VERBOSE, "metronom: video not synced on this one\n");
+
+ this->sync_pts = pts;
+ this->sync_vpts = this->video_vpts;
+ this->last_video_vpts = this->video_vpts;
+ this->last_video_pts = pts;
+ }
+
+ vpts = this->video_vpts;
+ this->video_vpts += this->pts_per_frame + this->video_pts_delta;
+ this->num_video_vpts_guessed++ ;
+
+ xprintf (METRONOM | VERBOSE, "metronom: video vpts for %10d : %10d\n", pts, vpts);
+
+ return vpts + this->av_offset;
+}
+
+
+static uint32_t metronom_got_audio_samples (metronom_t *this, uint32_t pts, uint32_t nsamples) {
+
+ uint32_t vpts;
+
+ xprintf (METRONOM | VERBOSE, "metronom: got %d audio samples (pts=%d)\n",
+ nsamples,pts);
+
+ if (pts) {
+ int32_t diff;
+
+ diff = pts - this->sync_pts;
+
+ if (this->sync_vpts && (pts>this->sync_pts)) {
+
+ int32_t vpts_diff;
+ uint32_t synced_vpts = this->sync_vpts + diff;
+
+ vpts_diff = synced_vpts - this->audio_vpts;
+
+ xprintf (METRONOM | VERBOSE, "metronom: audio calced vpts : %d <=> synced vpts : %d (diff: %d, delta: %d)\n",
+ this->audio_vpts, synced_vpts, vpts_diff, this->audio_pts_delta);
+ if (abs(vpts_diff)>5000) {
+
+ /* calc delta for wrong samplerates */
+
+ this->audio_pts_delta += vpts_diff*AUDIO_SAMPLE_NUM / (this->num_audio_samples_guessed);
+
+ if (abs(this->audio_pts_delta) >= 10000)
+ this->audio_pts_delta = 0;
+
+ if (synced_vpts>this->audio_vpts)
+ this->audio_vpts = synced_vpts;
+
+ } else
+ xprintf (METRONOM | VERBOSE, "metronom: audio tolerating diff\n");
+
+ } else
+ xprintf (METRONOM | VERBOSE, "metronom: audio not synced on this one\n");
+
+ this->sync_pts = pts;
+ this->sync_vpts = this->audio_vpts;
+ this->num_audio_samples_guessed = 0;
+ }
+
+ vpts = this->audio_vpts;
+ this->audio_vpts += nsamples * (this->audio_pts_delta + this->pts_per_smpls) / AUDIO_SAMPLE_NUM;
+ this->num_audio_samples_guessed += nsamples;
+
+ xprintf (METRONOM | VERBOSE, "metronom: audio vpts for %10d : %10d\n", pts, vpts);
+
+ return vpts;
+}
+
+static void metronom_set_av_offset (metronom_t *this, int32_t pts) {
+ this->av_offset = pts;
+ printf ("metronom: av_offset=%d pts\n", pts);
+}
+
+static int32_t metronom_get_av_offset (metronom_t *this) {
+ return this->av_offset;
+}
+
+
+
+/*
+ * ****************************************
+ * master clock feature
+ * ****************************************
+ */
+
+
+static void metronom_start_clock (metronom_t *this, uint32_t pts) {
+ gettimeofday(&this->start_time, NULL);
+ this->last_pts = this->start_pts = pts;
+ this->stopped = 0;
+}
+
+
+static uint32_t metronom_get_current_time (metronom_t *this) {
+
+ uint32_t pts;
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ pts = (tv.tv_sec - this->start_time.tv_sec) * 90000;
+ pts += (tv.tv_usec - this->start_time.tv_usec) / 10 * 9 / 10;
+ pts += this->start_pts;
+
+ if (this->stopped || (this->last_pts > pts)) {
+ //printf("tm_current_pts(): timer STOPPED!\n");
+ pts = this->last_pts;
+ }
+
+ return pts;
+}
+
+
+static void metronom_stop_clock(metronom_t *this) {
+ this->stopped = 1;
+ this->last_pts = this->get_current_time(this);
+}
+
+
+static void metronom_resume_clock(metronom_t *this) {
+ this->start_clock(this, this->last_pts);
+}
+
+
+
+static void metronom_adjust_clock(metronom_t *this, uint32_t desired_pts)
+{
+ int delta;
+
+ /* FIXME: this should be softer than a brute force warp... */
+ delta = desired_pts;
+ delta -= this->get_current_time(this);
+ this->start_pts += delta;
+ /* printf("adjusting start_pts to %d\n", this->start_pts); */
+}
+
+metronom_t * metronom_init () {
+
+ metronom_t *this = xmalloc (sizeof (metronom_t));
+
+ this->reset = metronom_reset;
+ this->set_video_rate = metronom_set_video_rate;
+ this->get_video_rate = metronom_get_video_rate;
+ this->set_audio_rate = metronom_set_audio_rate;
+ this->got_video_frame = metronom_got_video_frame;
+ this->got_audio_samples = metronom_got_audio_samples;
+ this->got_spu_packet = metronom_got_spu_packet;
+ this->set_av_offset = metronom_set_av_offset;
+ this->get_av_offset = metronom_get_av_offset;
+ this->start_clock = metronom_start_clock;
+ this->stop_clock = metronom_stop_clock;
+ this->resume_clock = metronom_resume_clock;
+ this->get_current_time = metronom_get_current_time;
+ this->adjust_clock = metronom_adjust_clock;
+
+ this->reset (this);
+
+ return this;
+}
+
diff --git a/src/xine-engine/metronom.h b/src/xine-engine/metronom.h
new file mode 100644
index 000000000..a16b9ef20
--- /dev/null
+++ b/src/xine-engine/metronom.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: metronom.h,v 1.1 2001/04/18 22:36:07 f1rmb Exp $
+ *
+ * metronom: general pts => virtual calculation/assoc
+ *
+ * virtual pts: unit 1/90000 sec, always increasing
+ * can be used for synchronization
+ * video/audio frame with same pts also have same vpts
+ * but pts is likely to differ from vpts
+ *
+ */
+
+
+#ifndef HAVE_METRONOM_H
+#define HAVE_METRONOM_H
+
+#include <inttypes.h>
+#include <sys/time.h>
+
+typedef struct metronom_s metronom_t ;
+
+struct metronom_s {
+
+ /*
+ * clear all cached data, reset current vpts ... called if new input
+ * file is reached
+ */
+
+ void (*reset) (metronom_t *this);
+
+ /*
+ * called by video output driver to inform metronom about current framerate
+ *
+ * parameter pts_per_frame : frame display duration in 1/90000 sec
+ */
+ void (*set_video_rate) (metronom_t *this, uint32_t pts_per_frame);
+
+ /*
+ * return current video rate (including delta corrections)
+ */
+
+ uint32_t (*get_video_rate) (metronom_t *this);
+
+ /*
+ * called by audio output driver to inform metronom about current audio
+ * bitrate
+ *
+ * parameter pts_per_smpls : 1/90000 sec per 65536 samples
+ */
+ void (*set_audio_rate) (metronom_t *this, uint32_t pts_per_smpls);
+
+ /*
+ * called by video output driver for *every* frame
+ *
+ * parameter pts: pts for frame if known, 0 otherwise
+ *
+ * return value: virtual pts for frame
+ *
+ */
+
+ uint32_t (*got_video_frame) (metronom_t *this, uint32_t pts);
+
+ /*
+ * called by audio output driver whenever audio samples are delivered to it
+ *
+ * parameter pts : pts for audio data if known, 0 otherwise
+ * nsamples : number of samples delivered
+ *
+ * return value: virtual pts for audio data
+ *
+ */
+
+ uint32_t (*got_audio_samples) (metronom_t *this, uint32_t pts, uint32_t nsamples);
+
+ /*
+ * called by SPU decoder whenever a packet is delivered to it
+ *
+ * parameter pts : pts for SPU packet if known, 0 otherwise
+ *
+ * return value: virtual pts for SPU packet
+ *
+ */
+
+ uint32_t (*got_spu_packet) (metronom_t *this, uint32_t pts);
+
+ /*
+ * manually correct audio <-> video sync
+ */
+ void (*set_av_offset) (metronom_t *this, int32_t pts);
+
+ int32_t (*get_av_offset) (metronom_t *this);
+
+ /*
+ * ****************************************
+ * master clock functions
+ * ****************************************
+ */
+
+ /*
+ * start metronom clock (no clock reset)
+ */
+ void (*start_clock) (metronom_t *this, uint32_t pts);
+
+
+ /*
+ * stop metronom clock
+ */
+ void (*stop_clock) (metronom_t *this);
+
+
+ /*
+ * resume clock from where it was stopped
+ */
+ void (*resume_clock) (metronom_t *this);
+
+
+ /*
+ * get current clock value in vpts
+ */
+ uint32_t (*get_current_time) (metronom_t *this);
+
+
+ /*
+ * adjust master clock to external timer (e.g. audio hardware)
+ */
+ void (*adjust_clock) (metronom_t *this, uint32_t desired_pts);
+
+ /*
+ * metronom internal stuff
+ */
+
+ uint32_t pts_per_frame;
+ uint32_t pts_per_smpls;
+
+ int32_t audio_pts_delta;
+
+ uint32_t video_vpts;
+ uint32_t audio_vpts;
+
+ uint32_t sync_pts;
+ uint32_t sync_vpts;
+
+ /* video delta for wrong framerates */
+ uint32_t last_video_pts;
+ uint32_t last_video_vpts;
+ int num_video_vpts_guessed;
+ int32_t video_pts_delta;
+
+ int num_audio_samples_guessed;
+
+ int32_t av_offset;
+
+ struct timeval start_time;
+ uint32_t start_pts, last_pts;
+ int stopped ;
+};
+
+metronom_t *metronom_init ();
+
+#endif
+
diff --git a/src/xine-engine/monitor.c b/src/xine-engine/monitor.c
new file mode 100644
index 000000000..6fb23340e
--- /dev/null
+++ b/src/xine-engine/monitor.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: monitor.c,v 1.1 2001/04/18 22:36:04 f1rmb Exp $
+ *
+ * debug print and profiling functions - implementation
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "monitor.h"
+#include <stdio.h>
+
+#define MAX_ID 5
+
+#ifdef DEBUG
+
+long long int profiler_times[MAX_ID+1] ;
+long long int profiler_start[MAX_ID+1] ;
+char * profiler_label[MAX_ID+1] ;
+
+void profiler_init () {
+ int i;
+ for (i=0; i<MAX_ID; i++) {
+ profiler_times[i] = 0;
+ profiler_start[i] = 0;
+ profiler_label[i] = "??";
+ }
+}
+
+void profiler_set_label (int id, char *label) {
+ profiler_label[id] = label;
+}
+
+#ifdef ARCH_X86
+__inline__ unsigned long long int rdtsc()
+{
+ unsigned long long int x;
+ __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
+ return x;
+}
+#endif
+
+void profiler_start_count (int id) {
+#ifdef ARCH_X86
+ profiler_start[id] = rdtsc();
+#endif
+}
+
+void profiler_stop_count (int id) {
+#ifdef ARCH_X86
+ profiler_times[id] += rdtsc() - profiler_start[id];
+#endif
+}
+
+void profiler_print_results () {
+ int i;
+
+ printf ("\n\nPerformance analysis (cpu cycles):\n\n");
+ for (i=0; i<MAX_ID; i++) {
+ printf ("%d:\t%s\t%12lld\n", i, profiler_label[i], profiler_times[i]);
+ }
+}
+
+#endif
diff --git a/src/xine-engine/monitor.h b/src/xine-engine/monitor.h
new file mode 100644
index 000000000..e338be535
--- /dev/null
+++ b/src/xine-engine/monitor.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: monitor.h,v 1.1 2001/04/18 22:36:07 f1rmb Exp $
+ *
+ * debug print and profiling functions
+ *
+ */
+
+#ifndef HAVE_MONITOR_H
+#define HAVE_MONITOR_H
+
+#include <inttypes.h>
+
+extern uint32_t xine_debug;
+
+#define VERBOSE (xine_debug & 0x8000>>1)
+#define METRONOM (xine_debug & 0x8000>>2)
+#define AUDIO (xine_debug & 0x8000>>3)
+#define DEMUX (xine_debug & 0x8000>>4)
+#define INPUT (xine_debug & 0x8000>>5)
+#define VIDEO (xine_debug & 0x8000>>6)
+#define VPTS (xine_debug & 0x8000>>7)
+#define MPEG (xine_debug & 0x8000>>8)
+#define VAVI (xine_debug & 0x8000>>9)
+#define AC3 (xine_debug & 0x8000>>10)
+#define LOOP (xine_debug & 0x8000>>11)
+#define GUI (xine_debug & 0x8000>>12)
+
+#define perr(FMT,ARGS...) {fprintf(stderr, FMT, ##ARGS);fflush(stderr);}
+
+#ifdef DEBUG
+
+/*
+ * Debug stuff
+ */
+
+//#define perr(FMT,ARGS...) {fprintf(stderr, FMT, ##ARGS);fflush(stderr);}
+
+#define xprintf(LVL, FMT, ARGS...) { \
+ if(LVL) { \
+ printf(FMT, ##ARGS); \
+ } \
+ }
+/*
+ * profiling
+ */
+
+void profiler_init ();
+
+void profiler_set_label (int id, char *label);
+
+void profiler_start_count (int id);
+
+void profiler_stop_count (int id);
+
+void profiler_print_results ();
+
+#else /* no DEBUG, release version */
+
+//#define perr(FMT,ARGS...)
+
+#define xprintf(LVL, FMT, ARGS...)
+
+#define profiler_init()
+#define profiler_set_label(id, label)
+#define profiler_start_count(id)
+#define profiler_stop_count(id)
+#define profiler_print_results()
+
+#endif /* DEBUG*/
+
+#endif /* HAVE_MONITOR_H */
diff --git a/src/xine-engine/utils.c b/src/xine-engine/utils.c
new file mode 100644
index 000000000..3c6c0f532
--- /dev/null
+++ b/src/xine-engine/utils.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: utils.c,v 1.1 2001/04/18 22:36:04 f1rmb Exp $
+ *
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/types.h>
+
+/*
+ *
+ */
+void *xmalloc(size_t size) {
+ void *ptrmalloc, *ptrmemset;
+
+ if((ptrmalloc = malloc(size)) == NULL) {
+ fprintf(stderr, "%s: malloc() failed: %s.\n",
+ __FUNCTION__, strerror(errno));
+ return NULL;
+ }
+
+ if((ptrmemset = memset(ptrmalloc, 0, size)) == NULL) {
+ fprintf(stderr, "%s: memset() failed: %s.\n",
+ __FUNCTION__, strerror(errno));
+ return NULL;
+ }
+
+ return ptrmemset;
+}
+
+/*
+ *
+ */
+void *xmalloc_aligned (size_t alignment, size_t size) {
+ void *pMem;
+
+ pMem = xmalloc (size+alignment);
+
+ while ((int) pMem % alignment)
+ pMem++;
+
+ return pMem;
+}
+
+/*
+ *
+ */
+const char *get_homedir(void) {
+ struct passwd *pw = NULL;
+ char *homedir = NULL;
+#ifdef HAVE_GETPWUID_R
+ int ret;
+ struct passwd pwd;
+ char *buffer = NULL;
+ int bufsize = 128;
+
+ buffer = (char *) xmalloc(bufsize);
+
+ if((ret = getpwuid_r(getuid(), &pwd, buffer, bufsize, &pw)) < 0) {
+#else
+ if((pw = getpwuid(getuid())) == NULL) {
+#endif
+ if((homedir = getenv("HOME")) == NULL) {
+ fprintf(stderr, "Unable to get home directory, set it to /tmp.\n");
+ homedir = strdup("/tmp");
+ }
+ }
+ else {
+ if(pw)
+ homedir = strdup(pw->pw_dir);
+ }
+
+
+#ifdef HAVE_GETPWUID_R
+ if(buffer)
+ free(buffer);
+#endif
+
+ return homedir;
+}
+
+/*
+ *
+ */
+char *chomp(char *str) {
+ char *pbuf;
+
+ pbuf = str;
+
+ while(*pbuf != '\0') pbuf++;
+
+ while(pbuf > str) {
+ if(*pbuf == '\r' || *pbuf == '\n' || *pbuf == '"') pbuf = '\0';
+ pbuf--;
+ }
+
+ while(*pbuf == '=' || *pbuf == '"') pbuf++;
+
+ return pbuf;
+}
diff --git a/src/xine-engine/utils.h b/src/xine-engine/utils.h
new file mode 100644
index 000000000..d68cd0999
--- /dev/null
+++ b/src/xine-engine/utils.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: utils.h,v 1.1 2001/04/18 22:36:09 f1rmb Exp $
+ *
+ */
+#ifndef HAVE_UTILS_H
+#define HAVE_UTILS_H
+
+void *xmalloc(size_t size);
+
+void *xmalloc_aligned(size_t alignment, size_t size);
+
+const char *get_homedir(void);
+
+/*
+ * Clean a string (remove spaces and '=' at the begin,
+ * and '\n', '\r' and spaces at the end.
+ */
+
+char *chomp (char *str);
+
+#endif
diff --git a/src/xine-engine/video_decoder.c b/src/xine-engine/video_decoder.c
new file mode 100644
index 000000000..a3f5532ce
--- /dev/null
+++ b/src/xine-engine/video_decoder.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: video_decoder.c,v 1.1 2001/04/18 22:36:04 f1rmb Exp $
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xine.h"
+#include "xine_internal.h"
+#include "video_out/video_out.h"
+#include "video_decoder.h"
+
+#define MAX_NUM_DECODERS 10
+
+typedef struct vd_globals_s {
+
+ pthread_t mVideoThread;
+
+ fifo_buffer_t *mBufVideo;
+
+ video_decoder_t *mDecoders[MAX_NUM_DECODERS];
+ video_decoder_t *mCurDecoder;
+
+ uint32_t mnCurInputPos;
+
+ vo_instance_t *mVideoOut;
+
+ gui_status_callback_func_t gui_status_callback;
+
+ int mbStreamFinished;
+
+ pthread_mutex_t mXineLock;
+
+} vd_globals_t;
+
+static vd_globals_t gVD;
+
+void *video_decoder_loop () {
+
+ buf_element_t *pBuf;
+ int bRunning = 1;
+
+ while (bRunning) {
+
+ pBuf = gVD.mBufVideo->fifo_buffer_get (gVD.mBufVideo);
+
+ gVD.mnCurInputPos = pBuf->nInputPos;
+
+ switch (pBuf->nType) {
+ case BUF_STREAMSTART:
+ if (gVD.mCurDecoder) {
+ gVD.mCurDecoder->close ();
+ gVD.mCurDecoder = NULL;
+ }
+
+ pthread_mutex_lock (&gVD.mXineLock);
+ gVD.mbStreamFinished = 0;
+ pthread_mutex_unlock (&gVD.mXineLock);
+
+ break;
+
+ case BUF_MPEGVIDEO:
+ case BUF_AVIVIDEO:
+
+ decoder = gVD.mDecoders [pBuf->nType];
+
+ if (decoder) {
+ if (gVD.mCurDecoder != decoder) {
+
+ if (gVD.mCurDecoder)
+ gVD.mCurDecoder->close ();
+
+ gVD.mCurDecoder = decoder;
+ gVD.mCurDecoder->init (gVD.mVideoOut);
+
+ }
+
+ decoder->decode_data (pBuf);
+ }
+
+ break;
+
+ case BUF_STREAMEND:
+ if (gVD.mCurDecoder) {
+ gVD.mCurDecoder->close ();
+ gVD.mCurDecoder = NULL;
+ }
+
+ gVD.mbStreamFinished = 1;
+
+ pthread_mutex_lock (&gVD.mXineLock);
+
+ gVD.mbVideoFinished = 1;
+
+ if (audio_decoder_is_stream_finished ()) {
+ pthread_mutex_unlock (&gVD.mXineLock);
+ xine_notify_stream_finished ();
+ } else
+ pthread_mutex_unlock (&gVD.mXineLock);
+
+ break;
+
+ case BUF_QUIT:
+ if (gVD.mCurDecoder) {
+ gVD.mCurDecoder->close ();
+ gVD.mCurDecoder = NULL;
+ }
+ bRunning = 0;
+ break;
+
+ }
+
+ pBuf->free_buffer (pBuf);
+ }
+
+ return NULL;
+}
+
+int video_decoder_is_stream_finished () {
+ return gVD.mbStreamFinished ;
+}
+
+uint32_t video_decoder_get_pos () {
+ return gVD.mnCurPos;
+}
+
+fifo_buffer_t *video_decoder_init (vo_instance_t *video_out,
+ pthread_mutex_t xine_lock) {
+
+ gVD.mVideoOut = video_out;
+ gVD.mXineLock = xine_lock;
+
+ gVD.mCurDecoder = NULL;
+ for (i=0; i<MAX_NUM_DECODERS; i++)
+ gVD.mDecoders[i] = NULL;
+
+ gVD.mDecoders[BUF_MPEGVIDEO] = init_video_decoder_mpeg2dec ();
+ gVD.mDecoders[BUF_AVIVIDEO] = init_video_decoder_avi ();
+
+ gVD.mBufVideo = fifo_buffer_new ();
+
+ pthread_create (&gVD.mVideoThread, NULL, video_decoder_loop, NULL) ;
+
+ printf ("video_decoder_init: video thread created\n");
+
+ return gVD.mBufVideo;
+}
+
+void video_decoder_shutdown () {
+
+ buf_element_t *pBuf;
+
+ gVD.mBufVideo->fifo_buffer_clear(gVD.mBufVideo);
+
+ pBuf = gVD.mBufVideo->buffer_pool_alloc ();
+ pBuf->nType = BUF_QUIT;
+ gVD.mBufVideo->fifo_buffer_put (gVD.mBufVideo, pBuf);
+
+ pthread_join (gVD.mVideoThread, &p);
+}
diff --git a/src/xine-engine/video_decoder.h b/src/xine-engine/video_decoder.h
new file mode 100644
index 000000000..ee9abfe33
--- /dev/null
+++ b/src/xine-engine/video_decoder.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: video_decoder.h,v 1.1 2001/04/18 22:36:09 f1rmb Exp $
+ *
+ *
+ * functions that implement video decoding
+ */
+
+#ifndef HAVE_VIDEO_DECODER_H
+#define VIDEO_DECODER_H
+
+#include <pthread.h>
+#include "buffer.h"
+#include "video_out.h"
+
+/*
+ * generic xine video decoder plugin interface
+ */
+
+typedef struct video_decoder_s
+{
+
+ /* get interface version */
+ int (*get_version) (void);
+
+ int (*can_handle) (int buf_type);
+
+ void (*init) (vo_instance_t *video_out);
+
+ void (*decode_data) (buf_element_t *buf);
+
+ void (*release_img_buffers) (void);
+
+ void (*close) (void);
+
+} video_decoder_t;
+
+/*
+ * init video decoders, allocate video fifo,
+ * start video decoder thread
+ */
+
+fifo_buffer_t *video_decoder_init (vo_instance_t *video_out,
+ pthread_mutex_t xine_lock) ;
+
+/*
+ * quit video thread
+ */
+
+void video_decoder_shutdown ();
+
+uint32_t video_decoder_get_pos ();
+
+int video_decoder_is_stream_finished ();
+
+#endif
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
new file mode 100644
index 000000000..9093e50ec
--- /dev/null
+++ b/src/xine-engine/xine.c
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: xine.c,v 1.1 2001/04/18 22:36:05 f1rmb Exp $
+ *
+ * top-level xine functions
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <pthread.h>
+#if defined (__linux__)
+#include <endian.h>
+#elif defined (__FreeBSD__)
+#include <machine/endian.h>
+#endif
+
+#include "xine.h"
+#include "xine_internal.h"
+#include "audio_out.h"
+#include "video_out.h"
+#include "demuxers/demux.h"
+#include "buffer.h"
+#include "libac3/ac3.h"
+#include "libmpg123/mpg123.h"
+#include "libmpg123/mpglib.h"
+#include "libmpeg2/mpeg2.h"
+#ifdef ARCH_X86
+#include "libw32dll/w32codec.h"
+#endif
+#include "libspudec/spudec.h"
+#include "input/input_plugin.h"
+#include "metronom.h"
+#include "configfile.h"
+#include "monitor.h"
+#include "video_decoder.h"
+#include "audio_decoder.h"
+
+/* debugging purposes only */
+uint32_t xine_debug;
+
+/*
+#define TEST_FILE
+*/
+#ifdef TEST_FILE
+int gTestFile=-1;
+#endif
+
+/*
+ * xine global variables
+ */
+
+void xine_notify_stream_finished (xine_t *this) {
+ printf ("xine_notify_stream_finished\n");
+
+ xine_stop (this);
+
+ this->status_callback (this->status);
+}
+
+/*
+ *
+ */
+void *xine_spu_loop (xine_t *this, void *dummy) {
+
+ buf_element_t *pBuf;
+ int bRunning = 1;
+
+ while (bRunning) {
+
+ pBuf = this->fifo_funcs->fifo_buffer_get (this->spu_fifo);
+
+ switch (pBuf->nType) {
+ case BUF_QUIT:
+ bRunning = 0;
+ break;
+ case BUF_RESET:
+ spudec_reset ();
+ break;
+ case BUF_SPU:
+ spudec_decode(pBuf->pContent, pBuf->nSize, pBuf->nPTS);
+ break;
+ }
+ this->fifo_funcs->buffer_pool_free (pBuf);
+ }
+
+ return NULL;
+}
+
+/*
+ *
+ */
+void xine_stop (xine_t *this) {
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ if (!this->cur_input_plugin)
+ return;
+
+ this->mnStatus = XINE_STOP;
+
+ if(this->cur_demuxer_plugin) {
+ this->cur_demuxer_plugin->demux_stop ();
+ this->cur_demuxer_plugin = NULL;
+ }
+
+ // FIXME
+ this->fifo_funcs->fifo_buffer_clear(this->mBufVideo);
+ this->fifo_funcs->fifo_buffer_clear(this->mBufAudio);
+ this->fifo_funcs->fifo_buffer_clear(this->spu_fifo);
+
+ if (gAudioOut)
+ gAudioOut->close ();
+
+ metronom_reset();
+ metronom_stop_clock ();
+
+ vo_reset();
+
+ this->cur_input_plugin->close();
+ this->cur_input_plugin = NULL;
+
+ pthread_mutex_unlock (&this->xine_lock);
+}
+
+/*
+ * *****
+ * Demuxers probing stuff
+ */
+static int try_demux_with_stages(xine_t *this, const char *MRL,
+ int stage1, int stage2) {
+ int s = 0, i;
+ int stages[3] = {
+ stage1, stage2, -1
+ };
+
+ if(stages[0] == -1) {
+ fprintf(stderr, "%s(%d) wrong first stage = %d !!\n",
+ __FUNCTION__, __LINE__, stage1);
+ return 0;
+ }
+
+ while(stages[s] != -1) {
+ for(i = 0; i < this->num_demuxer_plugins; i++) {
+ if(this->demuxer_plugins[i].open(this->cur_input_plugin,
+ MRL, stages[s]) == DEMUX_CAN_HANDLE) {
+
+ this->cur_demuxer_plugin = &this->demux_plugins[i];
+
+ xprintf(VERBOSE|DEMUX,"demuxer '%s' handle in stage '%s'.\n",
+ this->demux_plugins[i].get_identifier(),
+ (stages[s] == STAGE_BY_CONTENT) ? "STAGE_BY_CONTENT"
+ : ((stages[s] == STAGE_BY_EXTENSION) ? "STAGE_BY_EXTENSION"
+ : "UNKNOWN"));
+ return 1;
+ }
+#ifdef DEBUG
+ else
+ xprintf(VERBOSE|DEMUX, "demuxer '%s' cannot handle in stage '%s'.\n",
+ this->demuxer_plugins[i].get_identifier(),
+ (stages[s] == STAGE_BY_CONTENT) ? "STAGE_BY_CONTENT"
+ : ((stages[s] == STAGE_BY_EXTENSION) ? "STAGE_BY_EXTENSION"
+ : "UNKNOWN"));
+#endif
+ }
+ s++;
+ }
+
+ return 0;
+}
+/*
+ * Try to find a demuxer which handle the MRL stream
+ */
+static int find_demuxer(xine_t *this, const char *MRL) {
+
+ this->cur_demuxer_plugin = NULL;
+
+ switch(this->demux_strategy) {
+
+ case DEMUX_DEFAULT_STRATEGY:
+ if(try_demux_with_stages(this, MRL, STAGE_BY_CONTENT, STAGE_BY_EXTENSION))
+ return 1;
+ break;
+
+ case DEMUX_REVERT_STRATEGY:
+ if(try_demux_with_stages(this, MRL, STAGE_BY_EXTENSION, STAGE_BY_CONTENT))
+ return 1;
+ break;
+
+ case DEMUX_CONTENT_STRATEGY:
+ if(try_demux_with_stages(this, MRL, STAGE_BY_CONTENT, -1))
+ return 1;
+ break;
+
+ case DEMUX_EXTENSION_STRATEGY:
+ if(try_demux_with_stages(this, MRL, STAGE_BY_EXTENSION, -1))
+ return 1;
+ break;
+
+ }
+
+ return 0;
+}
+
+/*
+ *
+ */
+static void xine_play_internal (xine_t *this, char *MRL,
+ int spos, off_t pos) {
+
+ double share ;
+ off_t len;
+ int i;
+
+ xprintf (VERBOSE|LOOP, "xine open %s, start pos = %d\n",MRL, spos);
+
+ if (this->status == XINE_PAUSE) {
+ xine_pause();
+ return;
+ }
+
+ if (this->status != XINE_STOP) {
+ xine_stop ();
+ }
+
+ /*
+ * find input plugin
+ */
+
+ this->cur_input_plugin = NULL;
+
+ for (i = 0; i < this->num_input_plugins; i++) {
+ if (this->input_plugins[i].open(MRL)) {
+ this->cur_input_plugin = &this->input_plugins[i];
+ break;
+ }
+ }
+
+ if (!this->cur_input_plugin) {
+ perror ("open input source");
+ this->cur_demuxer_plugin = NULL;
+ return;
+ }
+
+ /*
+ * find demuxer plugin
+ */
+
+ if(!find_demuxer(this, MRL)) {
+ printf ("error: couldn't find demuxer for >%s<\n", MRL);
+ return;
+ }
+
+ vo_set_logo_mode (0);
+
+ /*
+ * Init SPU decoder with colour lookup table.
+ */
+
+ if(this->cur_input_plugin->get_clut)
+ spudec_init(this->cur_input_plugin->get_clut());
+ else
+ spudec_init(NULL);
+
+ /*
+ * metronom
+ */
+
+ metronom_reset();
+
+ /*
+ * start demuxer
+ */
+
+ if (spos) {
+ len = this->cur_input_plugin->get_length ();
+ share = (double) spos / 65535;
+ pos = (off_t) (share * len) ;
+ }
+
+ this->cur_demuxer_plugin->demux_select_audio_channel (this->audio_channel);
+ this->cur_demuxer_plugin->demux_select_spu_channel (this->spu_channel);
+ this->cur_demuxer_plugin->demux_start (this->cur_input_plugin,
+ this->mBufVideo, //FIXME
+ this->mBufAudio,
+ this->spu_fifo, pos);
+
+ this->status = XINE_PLAY;
+ this->cur_input_pos = pos;
+
+ /*
+ * remember MRL
+ */
+
+ strncpy (this->cur_mrl, MRL, 1024);
+
+ /*
+ * start clock
+ */
+
+ metronom_start_clock (0);
+}
+
+/*
+ *
+ */
+void xine_play (xine_t *this, char *MRL, int spos) {
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ if (this->status != XINE_PLAY)
+ xine_play_internal (this, MRL, spos, (off_t) 0);
+
+ pthread_mutex_unlock (&this->xine_lock);
+}
+
+/*
+ *
+ */
+static int xine_eject (xine_t *this, char *MRL) {
+ int i;
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ if(this->cur_input_plugin == NULL) {
+
+ for (i = 0; i < this->num_input_plugins; i++) {
+ if (this->input_pluginss[i].open(MRL)) {
+ this->cur_input_plugin = &this->input_plugins[i];
+ this->cur_input_plugin->close();
+ break;
+ }
+ }
+ }
+
+ if (this->status == XINE_STOP
+ && this->cur_input_plugin && this->cur_input_plugin->eject_media) {
+
+ pthread_mutex_unlock (&this->xine_lock);
+
+ return this->cur_input_plugin->eject_media ();
+ }
+
+ pthread_mutex_unlock (&this->xine_lock);
+ return 0;
+}
+
+/*
+ *
+ */
+void xine_exit (xine_t *this) {
+
+ void *p;
+ buf_element_t *pBuf;
+
+ /*
+ * stop decoder threads
+ */
+
+ if (this->cur_input_plugin)
+ this->cur_input_plugin->demux_stop ();
+
+ this->fifo_funcs->fifo_buffer_clear(this->spu_fifo);
+
+ audio_decoder_shutdown ();
+ video_decoder_shutdown ();
+
+ this->status = XINE_QUIT;
+
+ config_file_save ();
+}
+
+/*
+ *
+ */
+static void xine_pause (xine_t *this) {
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ if (this->status == XINE_PAUSE) {
+
+ xprintf (VERBOSE, "xine play %s from %Ld\n",
+ this->cur_mrl, this->cur_input_pos);
+
+ this->status = XINE_STOP;
+
+ xine_play_internal (this, this->cur_mrl, 0, this->cur_input_pos);
+ /* this->mnPausePos = 0; */
+
+ } else if (this->status == XINE_PLAY) {
+
+ if (!this->cur_input_plugin) {
+ pthread_mutex_unlock (&this->xine_lock);
+ return;
+ }
+
+ this->status = XINE_PAUSE;
+
+ this->cur_demuxer_plugin->demux_stop ();
+ this->cur_demuxer_plugin = NULL;
+
+ //FIXME
+ this->fifo_funcs->fifo_buffer_clear(this->mBufVideo);
+ this->fifo_funcs->fifo_buffer_clear(this->mBufAudio);
+ this->fifo_funcs->fifo_buffer_clear(this->spu_fifo);
+
+ if (gAudioOut)
+ gAudioOut->close ();
+
+ metronom_reset();
+ metronom_stop_clock ();
+
+ vo_reset ();
+
+ this->cur_input_plugin->close();
+ }
+
+ pthread_mutex_unlock (&this->xine_lock);
+}
+
+/*
+ *
+ */
+xine_t *xine_init (vo_instance_t *vo, ao_instance_t *ao,
+ gui_status_callback_func_t gui_status_callback,
+ int demux_strategy, uint32_t debug_lvl) {
+
+ xine_t *this = xmalloc (sizeof (xine_t));
+ int err;
+
+ this->status_callback = gui_status_callback;
+ this->demux_strategy = demux_strategy;
+ xine_debug = debug_lvl;
+
+#ifdef TEST_FILE
+ gTestFile = open ("/tmp/test.mp3", O_WRONLY | O_CREAT, 0644);
+#endif
+
+ /*
+ * init lock
+ */
+
+ pthread_mutex_init (&this->xine_lock, NULL);
+
+ /*
+ * Init buffers
+ */
+
+ this->fifo_funcs = buffer_pool_init (2000, 4096);
+ this->spu_fifo = this->fifo_funcs->fifo_buffer_new ();
+
+ /*
+ * init demuxer
+ */
+
+ xine_load_demux_plugins();
+
+ this->audio_channel = 0;
+ this->spu_channel = -1;
+ this->cur_input_pos = 0;
+
+ printf ("xine_init: demuxer initialized\n");
+
+ /*
+ * init and start decoder threads
+ */
+
+ this->mBufVideo = video_decoder_init (vo);
+
+ this->mBufAudio = audio_decoder_init (ao);
+
+ /*
+ * init SPU decoder, start SPU thread
+ */
+
+ spudec_init(NULL);
+
+ if((err = pthread_create (&this->spu_thread, NULL,
+ xine_spu_loop, NULL)) != 0) {
+ fprintf(stderr, "pthread_create failed: return code %d.\n", err);
+ exit(1);
+ }
+ else
+ printf ("xine_init: SPU thread created\n");
+
+ /*
+ * load input plugins
+ */
+
+ xine_load_input_plugins ();
+
+ printf ("xine_init: plugins loaded\n");
+
+ return this;
+}
+
+/*
+ *
+ */
+int xine_get_audio_channel (xine_t *this) {
+
+ return this->audio_channel;
+}
+
+/*
+ *
+ */
+void xine_select_audio_channel (xine_t *this, int nChannel) {
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ this->audio_channel = nChannel;
+
+ if (this->cur_demuxer_plugin) {
+ this->cur_demuxer_plugin->demux_select_audio_channel (this->audio_channel);
+ }
+
+ pthread_mutex_unlock (&this->xine_lock);
+}
+
+/*
+ *
+ */
+int xine_get_spu_channel (xine_t *this) {
+
+ return this->spu_channel;
+}
+
+/*
+ *
+ */
+void xine_select_spu_channel (xine_t *this, int nChannel) {
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ this->spu_channel = (nChannel >= -1 ? nChannel : -1);
+
+ if (this->cur_demuxer_plugin)
+ this->cur_demuxer_plugin->demux_select_spu_channel (this->spu_channel);
+
+ pthread_mutex_unlock (&this->xine_lock);
+}
+
+/*
+ *
+ */
+input_plugin_t* xine_get_input_plugin_list (xine_t *this, int *nInputPlugins) {
+
+ *nInputPlugins = this->num_input_plugins;
+ return this->input_plugins;
+}
+
+/*
+ *
+ */
+int xine_get_current_position (xine_t *this) {
+
+ off_t len;
+ double share;
+
+ pthread_mutex_lock (&this->xine_lock);
+
+ if (!this->cur_input_plugin) {
+ xprintf (VERBOSE|INPUT, "xine_get_current_position: no input source\n");
+ pthread_mutex_unlock (&this->xine_lock);
+ return 0;
+ }
+
+ /* pos = this->mCurInput->seek (0, SEEK_CUR); */
+ len = this->cur_input_plugin->get_length ();
+
+ share = (double) this->cur_input_pos / (double) len * 65535;
+
+ pthread_mutex_unlock (&this->xine_lock);
+
+ return (int) share;
+}
+
+/*
+ *
+ */
+int xine_get_status(xine_t *this) {
+
+ return this->status;
+}
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
new file mode 100644
index 000000000..c097158af
--- /dev/null
+++ b/src/xine-engine/xine_internal.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: xine_internal.h,v 1.1 2001/04/18 22:36:09 f1rmb Exp $
+ *
+ */
+
+#ifndef HAVE_XINE_INTERNAL_H
+#define HAVE_XINE_INTERNAL_H
+
+#include <inttypes.h>
+#include "xine.h"
+#include "input/input_plugin.h"
+#include "demuxers/demux.h"
+#include "video_out.h"
+#include "audio_out.h"
+#include "metronom.h"
+
+#define INPUT_PLUGIN_MAX 50
+#define DEMUXER_PLUGIN_MAX 50
+
+typedef struct xine_s {
+
+ /* private : */
+
+ metronom_t *metronom;
+
+ input_plugin_t input_plugins[INPUT_PLUGIN_MAX];
+ int num_input_plugins;
+ input_plugin_t *cur_input_plugin;
+
+ demux_plugin_t demuxer_plugins[DEMUXER_PLUGIN_MAX];
+ int num_demuxer_plugins;
+ demux_plugin_t *cur_demuxer_plugin;
+ int demux_stragegy;
+
+ int status;
+ off_t cur_input_pos;
+ char cur_mrl[1024];
+
+ fifo_buffer_t *spu_fifo;
+
+ int audio_channel;
+ int spu_channel;
+
+ gui_status_callback_func_t status_callback;
+
+ /* Lock for xine player functions */
+ pthread_mutex_t xine_lock;
+
+} xine_t;
+
+/*
+ * Load input/demux/audio_out/video_out plugins
+ * prototypes of load_plugins.c functions.
+ */
+void xine_load_demux_plugins (xine_t *this);
+void xine_load_input_plugins (xine_t *this);
+
+#endif