From db6b7c2e1c52c536a7f9690a410bf69817e0b2c5 Mon Sep 17 00:00:00 2001 From: Daniel Caujolle-Bert Date: Wed, 18 Apr 2001 22:33:39 +0000 Subject: Initial revision CVS patchset: 1 CVS date: 2001/04/18 22:33:39 --- AUTHORS | 86 ++ COPYING | 340 +++++ ChangeLog | 145 ++ INSTALL | 182 +++ Makefile.am | 37 + NEWS | 2 + README | 2 + TODO | 19 + acconfig.h | 32 + configure.in | 381 +++++ cvscompile | 25 + doc/FAQ.in | 450 ++++++ doc/MRL.txt | 13 + doc/Makefile.am | 41 + doc/README | 335 +++++ doc/README.freebsd | 66 + doc/README.syncfb | 144 ++ doc/bug_report_form | 62 + doc/dataflow.dia | Bin 0 -> 2799 bytes doc/man/Makefile.am | 9 + doc/man/en/Makefile.am | 11 + doc/man/en/xine.1.in | 173 +++ doc/man/fr/Makefile.am | 46 + doc/man/fr/xine.1.in | 165 +++ include/Makefile.am | 47 + include/audio_out.h | 97 ++ include/video_out.h | 327 +++++ include/xine.h.tmpl.in | 171 +++ m4/Makefile.am | 19 + m4/_xine.m4 | 106 ++ m4/xine.m4 | 201 +++ misc/Makefile.am | 20 + misc/SlackBuild.in | 191 +++ misc/autogen.sh | 74 + misc/build_rpms.sh.in | 93 ++ misc/debian/changelog | 25 + misc/debian/control | 52 + misc/debian/copyright | 32 + misc/debian/menu | 2 + misc/debian/rules | 75 + misc/debian/xine.docs | 3 + misc/upload.pl | 131 ++ misc/xine-config.in | 81 ++ misc/xine-lib.spec.in | 80 ++ misc/xine_logo.png | Bin 0 -> 41894 bytes src/Makefile.am | 19 + src/demuxers/Makefile.am | 48 + src/demuxers/demux.h | 125 ++ src/demuxers/demux_avi.c | 982 +++++++++++++ src/demuxers/demux_elem.c | 284 ++++ src/demuxers/demux_mpeg.c | 626 +++++++++ src/demuxers/demux_mpeg_block.c | 519 +++++++ src/demuxers/demux_mpgaudio.c | 440 ++++++ src/input/Makefile.am | 72 + src/input/dvd_udf.c | 661 +++++++++ src/input/dvd_udf.h | 39 + src/input/input_dvd.c | 438 ++++++ src/input/input_file.c | 191 +++ src/input/input_net.c | 224 +++ src/input/input_plugin.h | 178 +++ src/input/input_rtp.c | 384 +++++ src/input/input_stdin_fifo.c | 219 +++ src/input/input_vcd.c | 586 ++++++++ src/libac3/Makefile.am | 47 + src/libac3/ac3.h | 54 + src/libac3/ac3_internal.h | 359 +++++ src/libac3/bit_allocate.c | 509 +++++++ src/libac3/bit_allocate.h | 24 + src/libac3/bitstream.c | 79 ++ src/libac3/bitstream.h | 46 + src/libac3/bswap.h | 60 + src/libac3/cmplx.h | 9 + src/libac3/coeff.c | 437 ++++++ src/libac3/coeff.h | 24 + src/libac3/crc.c | 100 ++ src/libac3/crc.h | 27 + src/libac3/decode.c | 314 +++++ src/libac3/decode.h | 22 + src/libac3/dither.c | 117 ++ src/libac3/dither.h | 37 + src/libac3/downmix.c | 158 +++ src/libac3/downmix.h | 43 + src/libac3/exponent.c | 138 ++ src/libac3/exponent.h | 28 + src/libac3/imdct.c | 661 +++++++++ src/libac3/imdct.h | 36 + src/libac3/parse.c | 484 +++++++ src/libac3/parse.h | 26 + src/libac3/rematrix.c | 95 ++ src/libac3/rematrix.h | 25 + src/libac3/sanity_check.c | 128 ++ src/libac3/sanity_check.h | 27 + src/libac3/srfft.c | 309 +++++ src/libac3/srfft.h | 39 + src/libac3/srfftp.h | 305 ++++ src/libmpeg2/Makefile.am | 23 + src/libmpeg2/decode.c | 323 +++++ src/libmpeg2/header.c | 235 ++++ src/libmpeg2/idct.c | 290 ++++ src/libmpeg2/idct_mlib.c | 47 + src/libmpeg2/idct_mlib.h | 25 + src/libmpeg2/idct_mmx.c | 705 ++++++++++ src/libmpeg2/motion_comp.c | 125 ++ src/libmpeg2/motion_comp_mlib.c | 180 +++ src/libmpeg2/motion_comp_mmx.c | 1017 ++++++++++++++ src/libmpeg2/mpeg2.h | 67 + src/libmpeg2/mpeg2_internal.h | 194 +++ src/libmpeg2/slice.c | 1799 ++++++++++++++++++++++++ src/libmpeg2/stats.c | 315 +++++ src/libmpeg2/vlc.h | 425 ++++++ src/libmpg123/Makefile.am | 22 + src/libmpg123/README | 39 + src/libmpg123/TODO | 2 + src/libmpg123/common.c | 181 +++ src/libmpg123/dct64_i386.c | 315 +++++ src/libmpg123/decode_i386.c | 151 ++ src/libmpg123/huffman.h | 332 +++++ src/libmpg123/interface.c | 157 +++ src/libmpg123/l2tables.h | 160 +++ src/libmpg123/layer1.c | 159 +++ src/libmpg123/layer2.c | 300 ++++ src/libmpg123/layer3.c | 1608 +++++++++++++++++++++ src/libmpg123/main.c | 29 + src/libmpg123/mpg123.h | 194 +++ src/libmpg123/mpglib.h | 68 + src/libmpg123/tabinit.c | 80 ++ src/libspudec/Makefile.am | 20 + src/libspudec/spudec.c | 688 +++++++++ src/libspudec/spudec.h | 67 + src/libw32dll/Makefile.am | 38 + src/libw32dll/afl.c | 765 ++++++++++ src/libw32dll/driver.c | 182 +++ src/libw32dll/elfdll.c | 305 ++++ src/libw32dll/ext.c | 565 ++++++++ src/libw32dll/loader.h | 286 ++++ src/libw32dll/module.c | 618 +++++++++ src/libw32dll/pe_image.c | 936 +++++++++++++ src/libw32dll/pe_resource.c | 391 ++++++ src/libw32dll/registry.c | 421 ++++++ src/libw32dll/registry.h | 24 + src/libw32dll/resource.c | 479 +++++++ src/libw32dll/stubs.s | 36 + src/libw32dll/vfl.c | 330 +++++ src/libw32dll/w32codec.c | 426 ++++++ src/libw32dll/w32codec.h | 41 + src/libw32dll/win32.c | 1706 +++++++++++++++++++++++ src/libw32dll/win32.h | 1 + src/libw32dll/wine/Makefile.am | 16 + src/libw32dll/wine/avifmt.h | 244 ++++ src/libw32dll/wine/basetsd.h | 145 ++ src/libw32dll/wine/config.h | 442 ++++++ src/libw32dll/wine/debugtools.h | 92 ++ src/libw32dll/wine/driver.h | 112 ++ src/libw32dll/wine/elfdll.h | 14 + src/libw32dll/wine/heap.h | 56 + src/libw32dll/wine/ldt.h | 98 ++ src/libw32dll/wine/mmreg.h | 104 ++ src/libw32dll/wine/module.h | 198 +++ src/libw32dll/wine/msacm.h | 942 +++++++++++++ src/libw32dll/wine/msacmdrv.h | 203 +++ src/libw32dll/wine/ntdef.h | 101 ++ src/libw32dll/wine/pe_image.h | 81 ++ src/libw32dll/wine/poppack.h | 15 + src/libw32dll/wine/pshpack1.h | 13 + src/libw32dll/wine/pshpack2.h | 12 + src/libw32dll/wine/pshpack4.h | 15 + src/libw32dll/wine/pshpack8.h | 12 + src/libw32dll/wine/vfw.h | 654 +++++++++ src/libw32dll/wine/winbase.h | 1792 ++++++++++++++++++++++++ src/libw32dll/wine/windef.h | 656 +++++++++ src/libw32dll/wine/windows.h | 38 + src/libw32dll/wine/winerror.h | 1658 ++++++++++++++++++++++ src/libw32dll/wine/winestring.h | 13 + src/libw32dll/wine/winnt.h | 2665 +++++++++++++++++++++++++++++++++++ src/libw32dll/wine/winreg.h | 57 + src/libw32dll/wine/winuser.h | 2929 +++++++++++++++++++++++++++++++++++++++ src/libw32dll/wineacm.h | 55 + src/xine-engine/Makefile.am | 82 ++ src/xine-engine/attributes.h | 27 + src/xine-engine/audio_decoder.c | 194 +++ src/xine-engine/audio_decoder.h | 66 + src/xine-engine/buffer.c | 225 +++ src/xine-engine/buffer.h | 147 ++ src/xine-engine/configfile.c | 293 ++++ src/xine-engine/configfile.h | 101 ++ src/xine-engine/cpu_accel.c | 110 ++ src/xine-engine/cpu_accel.h | 514 +++++++ src/xine-engine/load_plugins.c | 200 +++ src/xine-engine/metronom.c | 298 ++++ src/xine-engine/metronom.h | 179 +++ src/xine-engine/monitor.c | 84 ++ src/xine-engine/monitor.h | 89 ++ src/xine-engine/utils.c | 125 ++ src/xine-engine/utils.h | 39 + src/xine-engine/video_decoder.c | 180 +++ src/xine-engine/video_decoder.h | 73 + src/xine-engine/xine.c | 607 ++++++++ src/xine-engine/xine_internal.h | 76 + 198 files changed, 50428 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100644 TODO create mode 100644 acconfig.h create mode 100644 configure.in create mode 100755 cvscompile create mode 100644 doc/FAQ.in create mode 100644 doc/MRL.txt create mode 100644 doc/Makefile.am create mode 100644 doc/README create mode 100644 doc/README.freebsd create mode 100644 doc/README.syncfb create mode 100644 doc/bug_report_form create mode 100644 doc/dataflow.dia create mode 100644 doc/man/Makefile.am create mode 100644 doc/man/en/Makefile.am create mode 100644 doc/man/en/xine.1.in create mode 100644 doc/man/fr/Makefile.am create mode 100644 doc/man/fr/xine.1.in create mode 100644 include/Makefile.am create mode 100644 include/audio_out.h create mode 100644 include/video_out.h create mode 100644 include/xine.h.tmpl.in create mode 100644 m4/Makefile.am create mode 100644 m4/_xine.m4 create mode 100644 m4/xine.m4 create mode 100644 misc/Makefile.am create mode 100644 misc/SlackBuild.in create mode 100755 misc/autogen.sh create mode 100644 misc/build_rpms.sh.in create mode 100644 misc/debian/changelog create mode 100644 misc/debian/control create mode 100644 misc/debian/copyright create mode 100644 misc/debian/menu create mode 100755 misc/debian/rules create mode 100644 misc/debian/xine.docs create mode 100755 misc/upload.pl create mode 100644 misc/xine-config.in create mode 100644 misc/xine-lib.spec.in create mode 100644 misc/xine_logo.png create mode 100644 src/Makefile.am create mode 100644 src/demuxers/Makefile.am create mode 100644 src/demuxers/demux.h create mode 100644 src/demuxers/demux_avi.c create mode 100644 src/demuxers/demux_elem.c create mode 100644 src/demuxers/demux_mpeg.c create mode 100644 src/demuxers/demux_mpeg_block.c create mode 100644 src/demuxers/demux_mpgaudio.c create mode 100644 src/input/Makefile.am create mode 100644 src/input/dvd_udf.c create mode 100644 src/input/dvd_udf.h create mode 100644 src/input/input_dvd.c create mode 100644 src/input/input_file.c create mode 100644 src/input/input_net.c create mode 100644 src/input/input_plugin.h create mode 100644 src/input/input_rtp.c create mode 100644 src/input/input_stdin_fifo.c create mode 100644 src/input/input_vcd.c create mode 100644 src/libac3/Makefile.am create mode 100644 src/libac3/ac3.h create mode 100644 src/libac3/ac3_internal.h create mode 100644 src/libac3/bit_allocate.c create mode 100644 src/libac3/bit_allocate.h create mode 100644 src/libac3/bitstream.c create mode 100644 src/libac3/bitstream.h create mode 100644 src/libac3/bswap.h create mode 100644 src/libac3/cmplx.h create mode 100644 src/libac3/coeff.c create mode 100644 src/libac3/coeff.h create mode 100644 src/libac3/crc.c create mode 100644 src/libac3/crc.h create mode 100644 src/libac3/decode.c create mode 100644 src/libac3/decode.h create mode 100644 src/libac3/dither.c create mode 100644 src/libac3/dither.h create mode 100644 src/libac3/downmix.c create mode 100644 src/libac3/downmix.h create mode 100644 src/libac3/exponent.c create mode 100644 src/libac3/exponent.h create mode 100644 src/libac3/imdct.c create mode 100644 src/libac3/imdct.h create mode 100644 src/libac3/parse.c create mode 100644 src/libac3/parse.h create mode 100644 src/libac3/rematrix.c create mode 100644 src/libac3/rematrix.h create mode 100644 src/libac3/sanity_check.c create mode 100644 src/libac3/sanity_check.h create mode 100644 src/libac3/srfft.c create mode 100644 src/libac3/srfft.h create mode 100644 src/libac3/srfftp.h create mode 100644 src/libmpeg2/Makefile.am create mode 100644 src/libmpeg2/decode.c create mode 100644 src/libmpeg2/header.c create mode 100644 src/libmpeg2/idct.c create mode 100644 src/libmpeg2/idct_mlib.c create mode 100644 src/libmpeg2/idct_mlib.h create mode 100644 src/libmpeg2/idct_mmx.c create mode 100644 src/libmpeg2/motion_comp.c create mode 100644 src/libmpeg2/motion_comp_mlib.c create mode 100644 src/libmpeg2/motion_comp_mmx.c create mode 100644 src/libmpeg2/mpeg2.h create mode 100644 src/libmpeg2/mpeg2_internal.h create mode 100644 src/libmpeg2/slice.c create mode 100644 src/libmpeg2/stats.c create mode 100644 src/libmpeg2/vlc.h create mode 100644 src/libmpg123/Makefile.am create mode 100644 src/libmpg123/README create mode 100644 src/libmpg123/TODO create mode 100644 src/libmpg123/common.c create mode 100644 src/libmpg123/dct64_i386.c create mode 100644 src/libmpg123/decode_i386.c create mode 100644 src/libmpg123/huffman.h create mode 100644 src/libmpg123/interface.c create mode 100644 src/libmpg123/l2tables.h create mode 100644 src/libmpg123/layer1.c create mode 100644 src/libmpg123/layer2.c create mode 100644 src/libmpg123/layer3.c create mode 100644 src/libmpg123/main.c create mode 100644 src/libmpg123/mpg123.h create mode 100644 src/libmpg123/mpglib.h create mode 100644 src/libmpg123/tabinit.c create mode 100644 src/libspudec/Makefile.am create mode 100644 src/libspudec/spudec.c create mode 100644 src/libspudec/spudec.h create mode 100644 src/libw32dll/Makefile.am create mode 100644 src/libw32dll/afl.c create mode 100644 src/libw32dll/driver.c create mode 100644 src/libw32dll/elfdll.c create mode 100644 src/libw32dll/ext.c create mode 100644 src/libw32dll/loader.h create mode 100644 src/libw32dll/module.c create mode 100644 src/libw32dll/pe_image.c create mode 100644 src/libw32dll/pe_resource.c create mode 100644 src/libw32dll/registry.c create mode 100644 src/libw32dll/registry.h create mode 100644 src/libw32dll/resource.c create mode 100644 src/libw32dll/stubs.s create mode 100644 src/libw32dll/vfl.c create mode 100644 src/libw32dll/w32codec.c create mode 100644 src/libw32dll/w32codec.h create mode 100644 src/libw32dll/win32.c create mode 100644 src/libw32dll/win32.h create mode 100644 src/libw32dll/wine/Makefile.am create mode 100644 src/libw32dll/wine/avifmt.h create mode 100644 src/libw32dll/wine/basetsd.h create mode 100644 src/libw32dll/wine/config.h create mode 100644 src/libw32dll/wine/debugtools.h create mode 100644 src/libw32dll/wine/driver.h create mode 100644 src/libw32dll/wine/elfdll.h create mode 100644 src/libw32dll/wine/heap.h create mode 100644 src/libw32dll/wine/ldt.h create mode 100644 src/libw32dll/wine/mmreg.h create mode 100644 src/libw32dll/wine/module.h create mode 100644 src/libw32dll/wine/msacm.h create mode 100644 src/libw32dll/wine/msacmdrv.h create mode 100644 src/libw32dll/wine/ntdef.h create mode 100644 src/libw32dll/wine/pe_image.h create mode 100644 src/libw32dll/wine/poppack.h create mode 100644 src/libw32dll/wine/pshpack1.h create mode 100644 src/libw32dll/wine/pshpack2.h create mode 100644 src/libw32dll/wine/pshpack4.h create mode 100644 src/libw32dll/wine/pshpack8.h create mode 100644 src/libw32dll/wine/vfw.h create mode 100644 src/libw32dll/wine/winbase.h create mode 100644 src/libw32dll/wine/windef.h create mode 100644 src/libw32dll/wine/windows.h create mode 100644 src/libw32dll/wine/winerror.h create mode 100644 src/libw32dll/wine/winestring.h create mode 100644 src/libw32dll/wine/winnt.h create mode 100644 src/libw32dll/wine/winreg.h create mode 100644 src/libw32dll/wine/winuser.h create mode 100644 src/libw32dll/wineacm.h create mode 100644 src/xine-engine/Makefile.am create mode 100644 src/xine-engine/attributes.h create mode 100644 src/xine-engine/audio_decoder.c create mode 100644 src/xine-engine/audio_decoder.h create mode 100644 src/xine-engine/buffer.c create mode 100644 src/xine-engine/buffer.h create mode 100644 src/xine-engine/configfile.c create mode 100644 src/xine-engine/configfile.h create mode 100644 src/xine-engine/cpu_accel.c create mode 100644 src/xine-engine/cpu_accel.h create mode 100644 src/xine-engine/load_plugins.c create mode 100644 src/xine-engine/metronom.c create mode 100644 src/xine-engine/metronom.h create mode 100644 src/xine-engine/monitor.c create mode 100644 src/xine-engine/monitor.h create mode 100644 src/xine-engine/utils.c create mode 100644 src/xine-engine/utils.h create mode 100644 src/xine-engine/video_decoder.c create mode 100644 src/xine-engine/video_decoder.h create mode 100644 src/xine-engine/xine.c create mode 100644 src/xine-engine/xine_internal.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..8dd3578ec --- /dev/null +++ b/AUTHORS @@ -0,0 +1,86 @@ +xine programming + + Guenter Bartsch + +various suggestions, bug and build fixes, alsa plugin, gui + + Daniel Caujolle-Bert + +Debian package, audio programming + + Siegfried Langauf + +xine is using + + mpeg2dec - a free MPEG-2 video stream decoder + libac3 - a free AC3 audio stream decoder + Written by Aaron Holtzman + + libmpg123 - a free MPEG audio decoder + Written by Michael Hipp + +Contributions + + many thanks to the Linux Video and DVD Project "LiViD" + (http://www.linuxvideo.org/), where the original ideas for the xine + video player came from. + + Michael Lespinasse + great libmpeg2 hacks + + Alan Cox + bug fixes, net-input-plugin + + many thanks for those great skins to + Alexander G. Rubio + + Steffen Lorscheider + gui programming + + Heiko Schaefer + FreeBSD support, project administration, testing, ideas + + Marc Bufe + web design + + Paul Flinders + stdin/net plugin testing/bugfixes, audio downsampling + + Hugo Trippaers + Xinerama support + + Roland Barmettler + NTSC aspect ratio patches + + nakamura + Liner PCM patch + + Joachim Koenig + teletux/syncfb video output module, various bugfixes/reviews, alsa + + w32codec support is based on work from: + MPlayer http://banki1.banki.hu/~arpi/MPlayer.html + wine http://www.winehq.com + + Christian Bauer + gui bugfixes (wm support, clean exit) + + Bruno Schwander and + Soren Schmidt + input_vcd code for FreeBSD + + Rich Wareham + subtitle support + + Christoph Pittracher + pitt skin + + Dave Gilbert + alpha support + + Bastien Nocera + powerpc patch + + (let us know if we've forgotten anyone) + + diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..d60c31a97 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..cbb6379b2 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,145 @@ +xine (0.4.0) unstable; urgency=low + + * new multithreaded architecture - xine becomes idle + * notable performance improvements + * lots of portability patches (alpha, powerpc...) + * dynamic loading of demuxers + + * added support for ESD audio output + * new CORBA interface (optional) + + -- Siggi Langauf Sat, 3 Mar 2001 01:36:39 +0100 + +xine (0.3.7) unstable; urgency=low + + * subpicture/subtitle support + * experimental AC3 digital output with some ALSA drivers + * restricted Debian build architecture to i386 + (closes:Bug#83138,Bug#83541,Bug#83373) + * added Setup dialog for brightness and contrast controls + + -- Siggi Langauf Sun, 4 Feb 2001 14:44:23 +0100 + +xine (0.3.6) unstable; urgency=low + + * support for field pictures + * added autoprobing for audio driver + * fixed autoconf paths for architecture independant files + * VCD support for FreeBSD + * raw device support fixed + * libmpg123 update and bugfixes + * mpeg audio (mp3) demuxer + * video window resizing for Xv available + * updated Debian control and copyright (closes:Bug#82817,Bug#83044,Bug#83047) + + -- Siggi Langauf Mon, 22 Jan 2001 02:06:08 +0100 + +xine (0.3.5) unstable; urgency=low + + * (hopefully) fixed autoconf for Athlon processors + * fixed aspect ratio calculation (=> SVCD support) + * fixed demuxer bug (xine crashed aftera few minutes w/ some streams) + * teletux support for YUY2 video format + + * added fixed build architecture for Debian package + * Debian packages are now using /usr/lib/win32 for Windows Codecs + * using English man page instead of French one, both to come... + + -- Siggi Langauf Wed, 10 Jan 2001 11:10:57 +0100 + +xine (0.3.4) unstable; urgency=low + + * re-debianized package using debhelper (much cleaner debian packages) + + * rudimentary support for win32 codecs + * added Teletux support patch from Joachim Koenig + * 3Dnow! support + * build improvements on K6/K7 processors + + -- Siggi Langauf Mon, 8 Jan 2001 04:03:11 +0100 + + +xine (0.3.3) unstable; urgency=low + + * playlist, autoplay function + * seamless branching + * lpcm support + * sigint handling + * fixed shared memory release + * fixed NTSC aspect ratio + + -- Siggi Langauf Thu, 04 Jan 2001 01:37:42 +0100 + + +xine (0.3.2) unstable; urgency=low + + * audio rate up/downsampling + * new yuv2rgb routines + * anamorphic scaling for Xshm output + * gui improvements (audio channel selection, fullscreen, + skinfiles, slider, transparency, a new theme) + * ac3dec performance improved + * improved debugging/logging functions + * improved dabian packages + * RedHat 7 / gcc "2.96" build fixes + + -- Siggi Langauf Wed, 13 Dec 2000 02:44:18 +0100 + + +xine (0.3.1p1) unstable; urgency=high + + * Bugfix for Debian package: 0.3.1 always segfaulted. This release should + work... + + -- Siggi Langauf Tue, 21 Nov 2000 21:43:18 +0100 + + +xine (0.3.1) unstable; urgency=low + + * Initial release of Debian package. + + * xine should run on kde now + * better audio driver detection + * fixed aspect ratio bug + * fixed pause function (restart pos) + * fixed playlist-next bug + + -- Siggi Langauf Sun, 19 Nov 2000 15:33:28 +0100 + +xine (0.3.0+older) unstable; urgency=low + + 0.3.0 + - NULL audio driver (ability to run without sound card) + - ALSA audio driver + - pause function + - simple playlist function + - massive performance improvements for xshm + through subslice output + - gui/skin improvements + - improved build process + - improved internal architecture + - many minor updates/bugfixes + + 0.2.4 + this is a maintenance/bugfix + release, just wanted to release all the small little changes + before we go for the next big architecture update that will + be in the 0.3.x series + + + 0.2.3 + - included patches by Alan Cox: + net_plugin, bug fixes (i.e. VCD ...) + - xshm video output module fixed for bpp>16 + (but don't use that for speed reasons!) + - new iDCT_mmx code from walken + => picture quality massively improved :)) + - FAQ update + - speed improvements due to new compiler switches + - minor Makefile fixes for FreeBSD ports + + -- Siggi Langauf Sun, 7 Jan 2001 23:59:12 +0100 + +Local variables: +mode: debian-changelog +End: diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..b42a17ac4 --- /dev/null +++ b/INSTALL @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..6e5f0ee4a --- /dev/null +++ b/Makefile.am @@ -0,0 +1,37 @@ +## +## Process this file with automake to produce Makefile.in +## + +AUTOMAKE_OPTIONS = 1.3 + +SUBDIRS = doc m4 src misc include + +EXTRA_DIST = cvscompile + +noinst_HEADERS = config.h + + +debug: + list='$(SUBDIRS)'; for subdir in $$list; do \ + (cd $$subdir && $(MAKE) $@) \ + done; + + +prune-cache: + -rm -f config.cache + + +mostlyclean-generic: + -rm -f *~ \#* .*~ .\#* + -rm -f $(PACKAGE)_$(VERSION).tar.gz + -rm -f $(distdir).tar.gz $(PACKAGE).tgz package_descriptions + -rm -rf $(distdir) + + +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 configure acinclude.m4 aclocal.m4 + -rm -f config.h.in stamp-h.in ltconfig ltmain.sh + -rm -f config.guess config.sub install-sh missing mkinstalldirs + -rm -f libtool-nofpic diff --git a/NEWS b/NEWS new file mode 100644 index 000000000..7aa22b154 --- /dev/null +++ b/NEWS @@ -0,0 +1,2 @@ +This file is unused. +The ChangeLog file lists changes for new versions. diff --git a/README b/README new file mode 100644 index 000000000..8c30c831c --- /dev/null +++ b/README @@ -0,0 +1,2 @@ + +*** see doc directory. *** diff --git a/TODO b/TODO new file mode 100644 index 000000000..751ebbccf --- /dev/null +++ b/TODO @@ -0,0 +1,19 @@ +- skip packages if CPU very slow + +- MPEG-4 support in source + +- 4-channel surround sound + +- sp/div direct ac3 output + +- use docbook for FAQ/manpage/README... + +- ability to play back video over remote X11 connection + +- BUG: avi demuxer segfaults if frames are big + +- check XLock/Thread support + +- check GOP timestamp decoding for mpeg-2 + +- BUG: xshm video output crashes if aspect ratio is changed while playing diff --git a/acconfig.h b/acconfig.h new file mode 100644 index 000000000..bf01ee913 --- /dev/null +++ b/acconfig.h @@ -0,0 +1,32 @@ +/* Define this if you're running x86 architecture */ +#undef __i386__ + +/* Define this if you're running x86 architecture */ +#undef ARCH_X86 + +/* Define this if you're running Alpha architecture */ +#undef __alpha__ + +/* Define this if you're running PowerPC architecture */ +#undef __ppc__ + +/* Define this if you're running Sparc architecture */ +#undef __sparc__ + +/* Define this if you have mlib installed */ +#undef HAVE_MLIB + +/* Define this if you have mlib installed */ +#undef LIBMPEG2_MLIB + +/* Define this if you have getpwuid_r() function */ +#undef HAVE_GETPWUID_R + +/* Define this to plugins directory location */ +#undef XINE_PLUGINDIR + +/* Define this to demuxers plugins directory location */ +#undef XINE_DEMUXDIR + +/* Define this to skins directory location */ +#undef XINE_SKINDIR diff --git a/configure.in b/configure.in new file mode 100644 index 000000000..3f624c03c --- /dev/null +++ b/configure.in @@ -0,0 +1,381 @@ +dnl +dnl Configure.in for xine +dnl + +AC_INIT(src/xine-engine/xine.c) + +dnl +dnl Required Autoconf Version 2.13 +dnl +AC_PREREQ(2.13) + + +XINE_MAJOR=0 +XINE_MINOR=5 +XINE_SUB=0 +XINE_PRE=".alpha1" +TAR_NAME="xine-lib-"$XINE_MAJOR.$XINE_MINOR.$XINE_SUB$XINE_PRE +SPEC_VERSION=$XINE_MAJOR.$XINE_MINOR.$XINE_SUB$XINE_PRE +AC_SUBST(XINE_MAJOR) +AC_SUBST(XINE_MINOR) +AC_SUBST(XINE_SUB) +AC_SUBST(TAR_NAME) +AC_SUBST(SPEC_VERSION) + +AM_INIT_AUTOMAKE("xine-lib", $XINE_MAJOR.$XINE_MINOR.$XINE_SUB$XINE_PRE) + + +dnl +dnl Made possible to build for another arch. +dnl +if test x$XINE_BUILD != "x"; then + AC_MSG_RESULT(*** build forced to $XINE_BUILD ***) + build=$XINE_BUILD + host=$XINE_BUILD +else + check_athlon=yes +fi + +AC_CANONICAL_HOST +AM_CONFIG_HEADER(config.h) + + +dnl +dnl Check for programs. +dnl +AC_ISC_POSIX +AC_PROG_CC +AC_STDC_HEADERS +AC_PROG_MAKE_SET +AC_PROG_INSTALL +dnl obsolete AC_PROG_RANLIB +AC_PROG_LN_S + + +dnl +dnl Libtool +dnl +AC_LIBTOOL_DLOPEN +AM_DISABLE_STATIC +AM_PROG_LIBTOOL +AC_SUBST(LIBTOOL_DEPS) +if ${CONFIG_SHELL} ./libtool --features | grep "enable static" >/dev/null; then + STATIC="-static" +else + STATIC= +fi +AC_SUBST(STATIC) + + +dnl +dnl Build all libs as static +dnl +BUILD_LIB_STATIC="-static" +AC_SUBST(BUILD_LIB_STATIC) + + +dnl +dnl Checks for typedefs, structures, and compiler characteristics. +dnl +AC_C_CONST +AC_C_INLINE +AC_TYPE_OFF_T +AC_TYPE_SIZE_T +AM_TYPE_PTRDIFF_T +dnl AC_C_BIGENDIAN + +AC_SUBST(DEBUG_CFLAGS) +AC_SUBST(GLOBAL_CFLAGS) + + +dnl +dnl threads +dnl +case $host in + *-*-freebsd*) + THREAD_LIBS="-pthread" + ;; + *) + AC_CHECK_LIB(pthread, pthread_create, + THREAD_LIBS="-lpthread", + AC_MSG_ERROR(pthread needed)) + ;; +esac +AC_SUBST(THREAD_LIBS) + + +dnl +dnl dynamic linker +dnl +AC_CHECK_LIB(c, dlopen, + DYNAMIC_LD_LIBS="", + AC_CHECK_LIB(dl, dlopen, + DYNAMIC_LD_LIBS="-ldl", + AC_MSG_ERROR(dynamic linker needed))) +AC_SUBST(DYNAMIC_LD_LIBS) + + +dnl +dnl mpeg2lib stuff +dnl +AC_SUBST(LIBMPEG2_CFLAGS) +AC_SUBST(LIBMPEG2_CONFIG_OBJS) + +LIBMPEG2_CFLAGS="" dnl default include path removed, no more needed. + +if test x$enable_mlib = x; then +AC_ARG_ENABLE(mlib, + [ --disable-mlib make a version not using mediaLib], + enable_mlib=no, enable_mlib=yes) +fi +if test x$enable_mlib = xyes; then + AC_CHECK_LIB(mlib, main, + [ LIBS="$LIBS -L/opt/SUNWmlib/lib -lmlib" + LIBMPEG2_CONFIG_OBJS="$LIBMPEG2_CONFIG_OBJS idct_mlib.lo motion_comp_mlib.lo" + LIBMPEG2_CFLAGS="$LIBMPEG2_CFLAGS -I/opt/SUNWmlib/include" + AC_DEFINE(HAVE_MLIB) + AC_DEFINE(LIBMPEG2_MLIB)], + , -L/opt/SUNWmlib/lib) +fi + + +dnl +dnl +dnl +AC_CHECK_FUNC(getpwuid_r,AC_DEFINE(HAVE_GETPWUID_R)) + + +dnl +dnl check cflags not supported by all gcc versions +dnl eg: -mpreferred-stack-boundary=2 and 2.91.66, +dnl and gcc-2.7.2.3 support a bit less options +dnl +AC_TRY_CFLAGS("-mpreferred-stack-boundary=2", + m_psb="-mpreferred-stack-boundary=2", m_psb="") +AC_TRY_CFLAGS("-fno-strict-aliasing", f_nsa="-fno-strict-aliasing", f_nsa="") +AC_TRY_CFLAGS("-fschedule-insns2", f_si="-fschedule-insns2", f_si="") +AC_TRY_CFLAGS("-mwide-multiply", m_wm="-mwide-multiply", m_wm="") + +dnl Common cflags for all platforms +COMMON_CFLAGS="-Wall -D_FILE_OFFSET_BITS=64 -DXINE_COMPILE" + +enable_w32dll="no" + +case $host in + i386-*-freebsd*) + GLOBAL_CFLAGS="$GLOBAL_CFLAGS -pipe -fomit-frame-pointer -malign-functions=4 -malign-loops=4 -malign-jumps=4 -malign-functions=4 $m_wm $m_psb -fexpensive-optimizations $f_si $f_nsa -ffast-math -funroll-loops -finline-functions" + GLOBAL_CFLAGS="$GLOBAL_CFLAGS $CFLAGS $COMMON_CFLAGS $ALSA_CFLAGS $ESD_CFLAGS -D_REENTRANT" + DEBUG_CFLAGS="$X_CFLAGS $DEBUG_CFLAGS $CFLAGS $COMMON_CFLAGS $ALSA_CFLAGS $ESD_CFLAGS -D_REENTRANT -DDEBUG" + AC_DEFINE(__i386__) + AC_DEFINE([ARCH_X86],,[x86 architecture]) + + enable_w32dll="yes" + ;; + *) + dnl Set the appropriate architecture define + case "$host_alias" in + i?86-* | k?-* | athlon-*) dnl catch i386,i486,i586,i686,k6,k7 + + dnl Check for gcc cpu optimization support + AC_TRY_CFLAGS("-mcpu=i386", + sarchopt="-mcpu", + AC_TRY_CFLAGS("-march=i386", + sarchopt="-march", + [ AC_MSG_RESULT(** no cpu optimization supports **) + sarchopt=no ])) + dnl special check for k7 cpu CC support + AC_TRY_CFLAGS("$sarchopt=k7", k7cpu="k7", k7cpu="i686") + + AC_DEFINE(__i386__) + AC_DEFINE([ARCH_X86],,[x86 architecture]) + + dnl add x86 specific CFLAGS + GLOBAL_CFLAGS="$GLOBAL_CFLAGS -O3 -pipe -fomit-frame-pointer -malign-functions=4 -malign-loops=4 -malign-jumps=4 -malign-functions=4 $m_wm $m_psb -fexpensive-optimizations $f_si $f_nsa -ffast-math -funroll-loops -funroll-all-loops -finline-functions" + DEBUG_CFLAGS="$DEBUG_CFLAGS -O3" + + dnl enable x86 specific parts of the code + enable_w32dll="yes" + + if test x"$sarchopt" != "xno"; then + [case "$host_alias" in + i386-*) dnl *BSD return this even on a P III #-)) + GLOBAL_CFLAGS="$GLOBAL_CFLAGS $sarchopt=i386" + DEBUG_CFLAGS="$DEBUG_CFLAGS $sarchopt=i386" + ;; + i486-*) dnl oh dear! + GLOBAL_CFLAGS="$GLOBAL_CFLAGS $sarchopt=i486" + DEBUG_CFLAGS="$DEBUG_CFLAGS $sarchopt=i486" + ;; + i586-*) + GLOBAL_CFLAGS="$GLOBAL_CFLAGS $sarchopt=pentium" + DEBUG_CFLAGS="$DEBUG_CFLAGS $sarchopt=pentium" + ;; + i686-*) + if test x"$check_athlon" = "xyes"; then + if test -f /proc/cpuinfo; then + modelname=`cat /proc/cpuinfo | grep "model\ name\ :" | sed -e 's/ //g' | cut -d':' -f2` + case $modelname in + *Athlon* | *Duron* | *K7*) + GLOBAL_CFLAGS="$GLOBAL_CFLAGS $sarchopt=$k7cpu" + DEBUG_CFLAGS="$DEBUG_CFLAGS $sarchopt=$k7cpu" + ;; + *) + GLOBAL_CFLAGS="$GLOBAL_CFLAGS $sarchopt=pentiumpro" + DEBUG_CFLAGS="$DEBUG_CFLAGS $X_CFLAGS $sarchopt=pentiumpro" + ;; + esac + fi + else + GLOBAL_CFLAGS="$GLOBAL_CFLAGS $sarchopt=pentiumpro" + DEBUG_CFLAGS="$DEBUG_CFLAGS $sarchopt=pentiumpro" + fi + ;; + k6-*) + GLOBAL_CFLAGS="$GLOBAL_CFLAGS $sarchopt=k6" + DEBUG_CFLAGS="$DEBUG_CFLAGS $sarchopt=k6" + ;; + k7-* | athlon-*) + GLOBAL_CFLAGS="$GLOBAL_CFLAGS $sarchopt=k7" + DEBUG_CFLAGS="$DEBUG_CFLAGS $sarchopt=k7" + esac] + fi + ;; + + alphaev56-*) + GLOBAL_CFLAGS="$GLOBAL_CFLAGS -O3 -mcpu=ev56 -mieee" + DEBUG_CFLAGS="$DEBUG_CFLAGS -O3 -mcpu=ev56 -mieee" + ;; + alpha*) + GLOBAL_CFLAGS="$GLOBAL_CFLAGS -O3 -mieee" + DEBUG_CFLAGS="$DEBUG_CFLAGS -O3 -mieee" + ;; + powerpc-*) + GLOBAL_CFLAGS="$GLOBAL_CFLAGS -O3 -pipe -fomit-frame-pointer $m_wm $m_psb -fexpensive-optimizations $f_si $f_nsa -ffast-math -funroll-loops -funroll-all-loops -finline-functions" + DEBUG_CFLAGS="$DEBUG_CFLAGS -O3" + ;; + sparc-*) + GLOBAL_CFLAGS="$GLOBAL_CFLAGS -O3" + DEBUG_CFLAGS="$DEBUG_CFLAGS -O3" + ;; + *) echo "$host is not currently supported by xine"; exit 1;; + esac + + GLOBAL_CFLAGS="$GLOBAL_CFLAGS $COMMON_CFLAGS $ALSA_CFLAGS $ESD_CFLAGS" + DEBUG_CFLAGS="$DEBUG_CFLAGS $COMMON_CFLAGS $ALSA_CFLAGS $ESD_CFLAGS -g -DDEBUG" + ;; +esac + +AM_CONDITIONAL(HAVE_W32DLL, test x"$enable_w32dll" = "xyes") +if test x"$enable_w32dll" = "xyes"; then + W32DLL_DEP="" +else + W32DLL_DEP="#" +fi +AC_SUBST(W32DLL_DEP) + + +dnl +dnl gcc __attribute__ ((aligned ())) +dnl +AC_C_ATTRIBUTE_ALIGNED + + +dnl +dnl XINE_ROOTDIR does not work if architecture independent files are +dnl installed to another place than architecture dependent files !!! +dnl +if test "x$prefix" = xNONE; then + prefix="${ac_default_prefix}" +fi +if test "x$exec_prefix" = xNONE; then + exec_prefix='${prefix}' +fi +XINE_PLUGINDIR="$libdir/xine/plugins" +eval XINE_PLUGINPATH=`eval echo "$XINE_PLUGINDIR"` +AC_DEFINE_UNQUOTED(XINE_PLUGINDIR,"$XINE_PLUGINPATH") + + +XINE_DEMUXDIR="$libdir/xine/plugins" +eval XINE_DEMUXPATH=`eval echo "$XINE_DEMUXDIR"` +AC_DEFINE_UNQUOTED(XINE_DEMUXDIR,"$XINE_DEMUXPATH") + +XINE_SKINDIR="${datadir}/xine/skins" +eval XINE_SKINPATH="$XINE_SKINDIR" +AC_DEFINE_UNQUOTED(XINE_SKINDIR,"$XINE_SKINPATH") + +AC_SUBST(XINE_PLUGINDIR) +AC_SUBST(XINE_DEMUXDIR) +AC_SUBST(XINE_SKINDIR) + + +dnl +dnl For win32 libraries location, needed by libw32dll. +dnl +AC_ARG_WITH(w32-path,[ --with-w32-path=path Location of WIN32 libraries], + w32_path="$withval", w32_path="/usr/lib/win32") +AC_SUBST(w32_path) + + +dnl +dnl Some include paths ( !!! DO NOT REMOVE !!! ) +dnl +INCLUDES='-I$(top_srcdir) -I$(top_builddir) -I$(top_srcdir)/src -I$(top_builddir)/src -I$(top_srcdir)/src/xine-engine -I$(top_builddir)/src/xine-engine -I$(top_srcdir)/include -I$(top_builddir/)/include' +AC_SUBST(INCLUDES) + + +dnl +dnl Get where .m4 should be installed. +dnl +AC_MSG_CHECKING(for aclocal directory) +if(aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL_DIR=`$ACLOCAL --print-ac-dir` + AC_MSG_RESULT($ACLOCAL_DIR) +else + ACLOCAL_DIR="/usr/local/share/aclocal" + AC_MSG_RESULT(none - will be installed in $ACLOCAL_DIR) +fi +AC_SUBST(ACLOCAL_DIR) + + +dnl +dnl Output configuration files +dnl +AC_OUTPUT([ +Makefile +include/Makefile +include/xine.h.tmpl +src/Makefile +src/demuxers/Makefile +src/libmpeg2/Makefile +src/libac3/Makefile +src/libmpg123/Makefile +src/libw32dll/Makefile +src/libw32dll/wine/Makefile +src/libspudec/Makefile +src/input/Makefile +src/xine-engine/Makefile +misc/Makefile +misc/xine-config +m4/Makefile +doc/Makefile +doc/FAQ +doc/man/Makefile +doc/man/en/Makefile +doc/man/en/xine.1 +doc/man/fr/Makefile +doc/man/fr/xine.1 +misc/xine-lib.spec +misc/SlackBuild +misc/build_rpms.sh], +[rm -f include/xine.h; echo '/* !! DO NO EDIT THIS FILE, it is automatically generated */' > include/xine.h && cat include/xine.h.tmpl >> include/xine.h]) + +dnl +dnl Change attribute. +dnl +chmod +x ./misc/SlackBuild ./misc/build_rpms.sh + +dnl +dnl Hack the libtool script. +dnl +cat libtool | sed -e 's/^pic_flag=/#pic_flag=/' > libtool-nofpic +chmod +x libtool-nofpic diff --git a/cvscompile b/cvscompile new file mode 100755 index 000000000..3ac246e01 --- /dev/null +++ b/cvscompile @@ -0,0 +1,25 @@ +#!/bin/sh +# Run this to generate all the initial Makefiles, etc. + +m4_files="_xine.m4" +if test -d m4; then + rm -f acinclude.m4 + for m4f in $m4_files; do + cat m4/$m4f >> acinclude.m4 + done +else + echo "Directory 'm4' is missing." + exit 1 +fi + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +(test -f $srcdir/configure.in) || { + echo -n "*** Error ***: Directory "\`$srcdir\'" does not look like the" + echo " top-level directory" + exit 1 +} + +. $srcdir/misc/autogen.sh + diff --git a/doc/FAQ.in b/doc/FAQ.in new file mode 100644 index 000000000..66966a82d --- /dev/null +++ b/doc/FAQ.in @@ -0,0 +1,450 @@ + + ---------------------- + xine FAQ + ---------------------- + + +how do I build this beast? +-------------------------- + +first make sure you use a stable, official release of gcc to compile. +You can try patched gcc versions, but these are not supported and will +probably not work (pgcc for example is known to make libmpeg break). + +./autogen.sh <--- only neccessary if you checked xine out of CVS +./configure +make +make install + + +how can I supply additional CFLAGS for the compilation ? +-------------------------------------------------------- + +you can do so by setting the GLOBAL_CFLAGS variable and then run +configure again. + +This can be usefull to specify additional include paths or library +paths to the compiler. Example: + +export GLOBAL_CFLAGS="-I/usr/include -L/home/guenter/xine_libs" + + +Are there binaries for my K7 available? Can I build them? +--------------------------------------------------------- + +At the moment we do not provide K7 binaries, since the latest +stable gcc version (2.92.2 at the time of this writing) doesn't +have K7 support. Use the 686 binaries instead. These binaries +should run ok and will use 3DNow! + +If you have a newer gcc you can try to compile "more" k7 support +in (esp. better instruction sheduling). If the configure script +should fail to detect your processor/gcc correctly, try setting the +XINE_BUILD envvar explicitly to a valid description string for +your configuration, e.g. + +export XINE_BUILD=k7-pc-linux-gnu +rm -f config.cache +./autogen.sh +make +make install + + +xine fails with "no video port found" +------------------------------------- + +you got the Xv extension, but your video card driver doesn't +support it. First try to find a driver that does support Xv on +your hardware (check your graphics card vendor). If your driver +has Xv support but you can't get it working, try at a lower +resultion (1024x768 is still enough even for anamorphic mpeg-2). + +If all that fails, supply the "-s" option so xine will be forced +to use Xshm output (remember to switch to 16bpp for speed) + +xine -s foo.vob + + +xine fails complaining about audio drivers/devices +-------------------------------------------------- + +You can select the audio driver using the -A option. So try + +xine -A null + +If you have ALSA drivers installed, try + +xine -A alsa + +If you run ESD, try + +xine -A esd + + +xine displays it's logo but I don't see my video? +------------------------------------------------- + +use the play button of the gui or press RETURN for PLAY. + + +xine plays audio but I don't see a picture +------------------------------------------ + +If you see lot's of "rejected" messages, your hardware isn't +set up right for xine. It might be your sound card doesn't +support the "realtime" feature (xine tests that on startup +so you might want to look at the messages again). Try to +find better drivers then. + +Perhaps your hardware is simply to slow - see "xine drops a +lot of frames" below for speed tips. + +If you're using Xv and the video output stays blank, try +moving the window around or toggling fullscreen ("F" key). +There is a bug in overlay setup [FIXME]. + + +Where should I put the windows codec dlls for xine? +--------------------------------------------------- + +store them in + +@w32_path@ + + +xine crashes when I try to play AVI files +----------------------------------------- + +win32codec support is still experimental. It should work ok if +your system meets these requirements: + +- Xv driver is working +- the AVI file contains mpeg audio +- you've got the right codecs installed correctly in + @w32_path@ + + +I get this message: demux error! 00 00 00 (should be 0x000001) +-------------------------------------------------------------- + +Probably xine can't access your input source. Most commonly this happens +when you're trying to play locked/encrypted DVDs. Remember that xine +can't play such DVDs out-of-the box (for legal reasons). + +You could use an css-enabled DVD input plugin to avoid this. + +Another reason could be that your (RPC-2) DVD drive isn't set up +for the right region. + + +I get messages such as "Ouch! lastPTS : 100657583 current pts : 100652798" +-------------------------------------------------------------------------- + +Looks like your sond card / driver fails to provide exact timing +information. Try to find better drivers (oss <-> alsa). + +If you're using alsa, make sure xine is using the native alsa API and +_not_ the oss emulation. Use + +xine -A alsa + +I get lots of "200 frames delivered, 200 frames skipped, 0 frames discarded" +---------------------------------------------------------------------------- + +looks like you've selected the wrong audio channel or you're trying to +play a stream that uses features xine doesn't support (yet). + + +when I play this stream, xine shows some pictures but there's no audio +---------------------------------------------------------------------- + +Try another audio channel: + +xine -a channel stream.vob + +some .vob files have audio on strange channels (e.g. 3, 7, 10) + + +can xine play SVCDs ? +--------------------- + +Yes, but you'll have to experiment with the audio channels + +xine -a channel VCD:// + +Normally, you should find an audio track #8 and, for bilingual SVCDs #9, so + +xine -a 8 + +shoud allow you to press the "vcd" button and play your SVCDs + + +xine drops a lot of frames +-------------------------- + +Your hardware is too slow for xine. Make sure you turn on all +speed optimizing options. A few point you should check: + +- use a recent kernel optimized for your hardware + +- use the latest gas/gcc + +- close other applications (use a tool like "top" to find out + what applications are using up CPU power) + +- if you are not using Xv, make sure your display is set up + to 16bpp, not 24 or higher (reduces memory bandwith) + +- make sure the hard drive which supplies the video data + is in DMA mode (if supported) + Under linux, you can use hdparm to check this, for example + + hdparm /dev/hda + + => + ... + using_dma = 1 (on) + + more information about this may be found here: + + http://oreilly.linux.com/pub/a/linux/2000/06/29/hdparm.html + +- xine needs high speed memory access which depends on your chip set. + Make sure you enable all speed-improving options. + + especially the via apollo pro chipset is known to be quite weird, + (most of all on my gigabyte board). If you can't configure the ram + access thoroughly using the bios you might want to try some really + nasty tricks, as explained on (for example) + http://www.overclockers.com/tips105/index03.asp + this website centers around a windows-tool to tweak the chipset, + you can do the same on FreeBSD with pciconf. On some linux + distributions there are similar tools. + + please contact heiko if you have any problems or tips about via + apollo pro chipset tweaking. + +- a nice performance tuning tool can be found here: + + http://powertweak.sourceforge.net + +- enable MTRR support in your kernel. If you are still using XFree 3.x, + you'll have to tell the kernel yourself where the graphics memory is. + You'll find details about that in the linux dvd howto. + + If you're using XFree 4.x enabling MTRR support should be enough. + + Try a cat /proc/mtrr - if the file exists and you find an entry + corresponding to the amount of graphics memory you have, everything + should be fine. + +- set up and use raw devices for dvd access + + raw devices should be available in linux kernel 2.4.x and there + are patches for older kernels available from + + ftp://ftp.kernel.org/pub/linux/kernel/people/sct/raw-io/ + + to use raw devices, first connect a free raw device to your dvd + device, use something like + + raw /dev/raw1 /dev/hdc + + then create a link named "rdvd" pointing to that raw device + + ln -s /dev/raw1 /dev/rdvd + + +Now how do I get this Xv extension to work? +------------------------------------------- + +First you need to install/use XFree 4.x. Once you got that you have to +make sure the XFree drivers you're using are supporting Xv on your +hardware. Here are some locations to look for suitable drivers: + +g200/g400 : xfree 4.x supports these out-of-the-box +nvidia cards : www.nvidia.com (the've got binary drivers) +ATI cards : GATOS www.linuxvideo.org/gatos/ +i815 : the latest xfree 4.x code supports these +3dfx (voodoo): the latest xfree 4.x code supports these + + +The AC3 via S/PDIF does not work with my soundcard +--------------------------------------------------- + +The AC3 via S/PDIF is supported by ALSA only for soundcards +with Trident 4DWaveNX and YMF chips. So if you have a +soundcard with one of these chips use + +xine -S -A alsa + +The -S switch disables the internal AC3 decoder. For very +slow machines you could improve video playback (without +sound) when you start xine as + +xine -S -A null + + + +where and how do I get the latest development version? +------------------------------------------------------ + +check it out of our CVS: + +cvs -d :pserver:anonymous@cvs.xine.sourceforge.net:/cvsroot/xine login + + + +cvs -d :pserver:anonymous@cvs.xine.sourceforge.net:/cvsroot/xine co xine + + + +How do I use the dvd plugin? +---------------------------- + +First of all: +The dvd plugin delivered with xine currently does not support playback +of locked and/or encrypted dvds. You will need external programs +or something like an "improved" xine_dvd_plugin to view these +DVDs with xine directly. Of course you could +play back the decrypted mpeg2 stream (technically speaking) that is the +movie on the dvd with xine with the help of additional programs. +Due to the uncertain legal situation regarding css encryption we do +not include anything of that nature in the xine distribution, nor do +we generally endorse the use of such software (you should check if +the use of such software is legal where you live). +We hope that this situation will change soon. + +For unlocked/unencrypted dvds it is a good idea first to check what +files are on the dvd by mounting it. The files are called something +like .../VIDEO_TS/VTS_xx_x.VOB, where x are numbers. +If you look for the big .VOB files on a dvd these are probably where the +movie is in. Currently we don't support seamless playback of complete +movies - you will have to play back all of its individual parts. + +To play that VOB file use something like + +xine dvd://VTS_xx_x.VOB + +make sure you do not supply any path name (no VIDEO_TS/) and use +capital letters for the file name. + +xine tries to open the dvd using /dev/cdrom. On freebsd this will only +work if you create a symlink to your dvd-devicenode for the time being. + + +unable to open dvd drive (/dev/dvd) +----------------------------------- + +You probalby don't have /dev/dvd (check that). If so, simply +create a link /dev/dvd that points to your DVD device. +Something like + +cd /dev +ln -s hdc dvd + +should do the job. + + +The aspect ratio is wrong! +-------------------------- + +Try pressing "A" (preferable when xine is stopped, otherwise +you may experience a segfault). + + +How do I play streams from STDIN ? +---------------------------------- + +use something like + +cat stream.mpg | xine stdin://mpeg1 + +or, if you've got an mpeg-2 stream use + +cat stream.vob | xine stdin://mpeg2 + + +How do I change the skin? +------------------------- + +Run xine at least once - it should write it's config file +.xinerc to your home directory. Now edit that file and change +the line "skin:default" to mach the skin you would like to use. + + +How can I change color/brightness/contrast? +------------------------------------------- + +At the moment this is only supported on some Xv drivers. You'll find +three entries like these in our ~/.xinerc: + +brightness:0 +saturation:0 +contrast:128 + +the values and possible ranges depend on your Xv driver so you'll have +to experiment a bit to get a good picture. + + +Some parts of my X Desktop get transparent when xine plays the video! +--------------------------------------------------------------------- + +Looks like some colors on your GUI match the colorkey Xv uses. You can +change the colorkey value to avoid this. There should be a line like + +colorkey:2110 + +to your ~/.xinerc where you can change the color that's used by xine +for the video overlay. + + +I get no sound, but "audio driver 'oss' failed, using null driver instead." +--------------------------------------------------------------------------- + +First of all, make sure that your OSS Audio drivers are working (ie you can +play music with other software). + +The most common reason for this is that some other program is accesing your +audio device. If you're using linux, the command "fuser /dev/dsp" should give +you the PID of the process. + +If you are using GNOME, chances are, that this is caused by ESD. Now you +have two possibilities. Either deactivate ESD (temporarily) by right +clicking on the sound monitor applet and selecting "Place Esound in +standby". Then xine will use OSS audio output. The other method is to make +xine use ESD for audio output with + +xine -A esd + +This may result in more jerkier playback, so the first method is the +preferred one. + + +after running xine several times it fail's to allocated shared memory! +---------------------------------------------------------------------- + +This should be fixed in xine 0.3.3 or later. However, this can only work if +you exit xine the "correct" way (e.g. using the panel or pressing "q"). +Do _not_ simply close the video output window using your window manager - +xine won't release shared memory in this case (!). + + +i have problems when using xine on FreeBSD +------------------------------------------ + +check if you find what you are looking for in the file README.freebsd + + +I think I found a bug! +---------------------- + +xine is in it's early developement stages. Please be patient. +If you got time, please contact us and send us a full bug report. +Please include all xine console output and some details about +your hardware and operating system. + +You can reach us via email: + + Xine Mailing List + diff --git a/doc/MRL.txt b/doc/MRL.txt new file mode 100644 index 000000000..fa084c3b3 --- /dev/null +++ b/doc/MRL.txt @@ -0,0 +1,13 @@ + MRL - Media Resource Locator + ============================ + + +File : path/foo.vob + /path/foo.vob + file://path/foo.vob + +DVD : dvd://VTS_01_2.VOB + +VCD : vcd://1 + + diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 000000000..a463f1b98 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,41 @@ + +SUBDIRS = man + +EXTRA_DIST = $(docs_DOCS) MRL.txt dataflow.dia + +docdir = $(prefix)/share/doc/xine +docs_DOCS = README README.syncfb README.freebsd FAQ bug_report_form + + +install-data-local: + @documentations='$(docs_DOCS)'; \ + for doc in $$documentations; do \ + destdir=$(docdir); \ + name=`echo $$doc` \ + dir=$$destdir; \ + $(mkinstalldirs) $$dir; \ + $(INSTALL_DATA) $$doc $$dir/$$name; \ + echo "installing $$doc as $$dir/$$name"; \ + done + + +uninstall-local: + @documentations='$(docs_DOCS)'; \ + for doc in $$documentations; do \ + destdir=$(docdir); \ + name=`echo $$doc` \ + dir=$$destdir; \ + rm -f $$dir/$$name; \ + echo "removing $$dir/$$name" ; \ + done + + +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/doc/README b/doc/README new file mode 100644 index 000000000..ff41e9421 --- /dev/null +++ b/doc/README @@ -0,0 +1,335 @@ + + ---------------------- + xine + ---------------------- + + a unix video player + + + +about xine: +----------- + +xine is a free gpl-licensed video player for unix-like systems. +We support mpeg-2 and mpeg-1 system (audio + video multiplexed) streams, +mpg audio files and AVI files (using win32 codec dlls). + +xine plays the video and audio data of the stream and synchronizes +the playback of both. Depending on the properties of the stream, +playback will need more or less processor power, full frame rate +for mpeg-2 has been seen on a 400 MHz P II system. + +xine can play Video CDs, SVCDs and DVDs directly. Unfortunately the legal +status of encrypted/locked DVD playback is uncertain in some countries +so we cannot include any DVD unlock/decrypt code with xine. To play back +such DVDs you'll need external programs or something like a +xine_dvd_plugin that can handle DVD authentification/descrambling. + +xine tries to be straightforward and effective. ...no bells and +whistles are being developed at this time ;-) first we want to achieve +good playback of video. + + +supported platforms / requirements: +---------------------------------- + +- xine needs a locally attached graphics device and monitor (playback over + x is not supported at the moment and will probably never be really useful + because of the enormous bandwidth of decoded video streams). +- xine needs either MIT-SHM (The MIT Shared Memory Extension), which is + supported in XFree86 for quite some time (3.3.x will be fine), + or X-Video Extension (Xv) which is faster and supports fullscreen + operation but is only provided by some XFree86 4.x drivers. + nVidia chips and Matrox G200 and G400 are known to work. +- if you can't get Xv to run on your platform you should use 16bpp + colordepth for speed. Xv seems to work nicely for 16 and 24bpp. +- if you have a mga 200 / 400 graphics adaptor you can optionally + use the sybcfb/teletux video ouput driver. See README.syncfb for + details. +- you need a sound driver that is realtime capable (not all + OSS/ALSA drivers support that feature) or ESD + +xine has so far been sucessfully used on the following systems: + +- Linux on a Pentium III 667 + using XFree86 4.01 on a nVidia Riva TNT 2 +- Linux on a Pentium II 400 + using XFree86 3.3.6, 4.0, 4.01 and 4.02 on a nVidia Riva TNT +- FreeBSD 4.1-Release on a Celeron 400 + using XFree86 3.3.6 and 4.0.1 on a Matrox G400 +- Linux on a Pentium 120 (no MMX) + using XFree86 3.3.5 on a Trident 9660 +- Linux on an AMD K6-266 + using XFree86 3.3.5 on a ATI AIW M64-8Mb PCI +- Linux on an AMD K6-III 450 + using XFree86 3.3.6 on a ATI RageII 8MB +- Linux on a Celeron 633 + using XFree86 4.0.1 on a ATI AIW Rage128-16MB +- Linux on a Amd K7@550 + using Xfree 4.0.1 on a Ati Rage 128 16 Mb + (Xv is working on this configuration with drivers from GATOS project) +- Linux on a Celeron 667 + using XFree86 4.0.2 on a Riva TNT 16Mb + (Xv is working on this configuration with closed-sources drivers + version 0.9.5 from NVidia). + +Work for non-Intel platforms has started but has not yet reached a +working state. + +usage: +------ + +You can start xine without any command line parameters or you can +specify one or more input streams directly. Xine tries to detect wheter +it can use the Xv extension and will fall back to XShm, but that +detection might fail. +If you don't see any video, first check your X11 drivers (for example +only the binary drivers from nVidia have Xv support for their chips). +If you can't get Xv to work, use the "-s" option and xine will be +forced to use Xshm. +If you get very sloppy video ouput your sound driver may not be +realtime capable. Try to use ALSA instead or, if you're already using +ALSA you might want to give OSS a try. +If you want to send the sound over a network with ESD, set the ESPEAKER +environment variable before starting xine. + +The input stream can be a filename or something we call +"MediaResourceLocator" MRL, which looks similar to a URL. First you +specify an input source which is followed by "://" and an input-source +specific identifier. What input sources you can use depends on the +input plugins you have (for plain files you can omit the input-source +identifier). Try + +$ xine --help + +to get the complete usage. + +Unfortunately the gui does not yet support the MRL concept to any +great extend, so to use any other input source than plain files you'll +have to use the command line at the moment. That will change soon :-) + +Example usage: + +$ xine + +$ xine /path/foo.vob + +$ xine -s /foo/test.mpg + +xine supports the xdnd protocol (Version 3) so if you have a file browser +application supporting that protocol (e.g. gmc) you can drop video files +on xine for playback. + +Playing track 3 from a VCD: + +$ xine vcd://3 + +Example for direct DVD access: + +$ xine dvd://VTS_01_1.VOB + +Keyboard shortcuts: +------------------- + +Key action + +RETURN play +F toggle fullscreen mode +Q quit +0 jump start of current stream +1-9 jump to 10-90% of current stream +SPACE pause +PgUp/Prior jump to previous playlist entry +PgDown/Next jump to next playlist entry +A toggle aspect ratio (AUTO/16:9/4:3/DVB) +Ctrl show/hide mouse cursor + +more to come. + +Click right on the video window to toggle panel visibility. + +selecting audio channels: +------------------------- + +Supply the -a option to select the desired audio track: + +xine -a 3 test.mpg + +plays the third mpg audio track (and the video, of course). + +For mpeg-1, only mpeg audio (layer 1, 2 and 3) is supported. + +Mpeg-2 streams can have different types of audio streams, though. +Xine supports ac3 (dolby digital), mpeg and LPCM sound. These +are mapped to the following tracks: + +Track selected audio stream + + 0- 7 ac3 stream 0-7 + 8-15 mpg audio stream 0-7 +16-23 pcm audio stram 0-7 + +example: to play pcm stream 0 use + +xine -a 16 file.vob + +selecting subtitles: +-------------------- + +Subtitles are embedded in different tracks like audio. In general, +track 0 is the default language subtitle. Use the -u option to +select the desired subtitle track: + +xine -u 0 test.vob + +displays the subtitles from stream 0. + +controlling xine via CORBA: +--------------------------- + +Xine implements a CORBA server interface to enable remote control and +scripting. For this, you need ORBit which should already be installed if +you are using GNOME. Otherwise you can get it from + + http://orbit-resource.sourceforge.net/ + +Any version of ORBit >= 0.4.0 should work fine. + +To enable the CORBA interface, you need to supply the "--enable-corba" +argument to the ./configure script and recompile xine. + +The xine server interface definition can be found in "corba/xine.idl" which +gets installed to "/usr/share/idl/xine.idl" by default. + +To communicate with xine via CORBA, you need to get its IOR (Interoperable +Object Reference). Upon startup, xine writes it to the file ~/.xine.ior +where you can read it from. If the ORBit name service is running, xine +also registers itself there under the name "Xine". Unfortunately, the +ORBit name server is usually not activated by default. You have to run +it manually like this: + + orbit-name-server >/tmp/name-service-ior & + +See the ORBit docs for more information. + +Two example client programs are provided: + 1. "xine-remote" is an example client written in C which can be used to + send play/stop/pause commands to a running instance of xine + 2. "example.py" is a small Python script that demonstrates how to easily + control xine from a scripting language + +using LIRC with xine: +--------------------- + +Xine can be remotly controlled with by IR. For this, you should have +LIRC installed (http://www.lirc.org), you should get latest CVS snapshot +if you're running latest Linux kernels (2.2 or 2.4 series). + +You should add some entries in your ~/.lircrc, like this: +begin + remote = SAMSUNG + button = Button_Play + prog = xine + repeat = 0 + config = PLAY +end +begin + remote = SAMSUNG + button = Button_Src + prog = xine + repeat = 0 + config = DVD +end +begin + remote = SAMSUNG + button = Button_1 + prog = xine + repeat = 0 + config = 10% +end +... + +All valids strings orders are: + + - for quiting: + quit + - for set the current position in current stream playback: + 0%, 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90% + - for play or stop: + play + - for pausing: + pause + - for eject: + eject + - for next/previous MRL in the playlist: + next, prev + - for next/previous audio track selection: + audio+, audio- + - for next/previous sub-title selection: + spu+, spu- + - to get the playlist from a DVD/VCD: + dvd, vcd + - to hide/show the GUI, the output video window: + hidegui, hideoutput + - to toggle the output video window<->fullscreen + fullscr + +All of orders are not case sensitive. + +used software: +-------------- + +xine uses software from the following free software projects: + +- libac3 by Aaron Holtzman +- libmpeg2 by Aaron Holtzman +- libmpg123 of the mpg123 project by Michael Hipp + (see http://www.mpg123.de/) + +...without these great pieces of software xine would of course not +be where it is now. + +also many thanks to the Linux Video and DVD Project "LiViD" +(http://www.linuxvideo.org/), where the original ideas for the xine +video player came from. + +developers of xine: +------------------- + + main xine developer: + Guenter Bartsch + + various suggestions, bug and build fixes, alsa plugin, gui + Daniel Caujolle-Bert + + audio programming + Siegfried Langauf + + contributes great libmpeg2 hacks: + Michael Lespinasse + + ...plus various other contributors, see the AUTHORS file + + +contacting the xine project: +---------------------------- + + the xine project website is + + http://xine.sourceforge.net + + feedback or offers for help are greatly appreciated, please contact + + + The Xine User Mailing List + ================================= + + + If, for some reason, you can't post to the list, you may contact the authors + directly: + + Guenter Bartsch + Daniel Caujolle-Bert + Siegfried Langauf + + $Id: README,v 1.1 2001/04/18 22:36:13 f1rmb Exp $ diff --git a/doc/README.freebsd b/doc/README.freebsd new file mode 100644 index 000000000..eec8c5bac --- /dev/null +++ b/doc/README.freebsd @@ -0,0 +1,66 @@ +xine fails when allocating images +--------------------------------- + +Make sure you have enough shared memory enabled. This is very +limited by default. + +Edit your /etc/sysctl.conf: + +kern.ipc.shmmax=67108864 +kern.ipc.shmall=32768 + + + +playing video cd on freebsd +--------------------------- + +currently (because of issues with the freebsd kernel) xine can only +play video cd from atapi cdrom drives. not for scsi drives! + +currently (Jan 2001), FreeBSD-stable (and thus the current releases also) +needs a patch to the kernel sources to make video cd work (please check +the freebsd documentation if you are unsure on how to build a custom +kernel with this patch included). + +the file you have to patch is /sys/dev/ata/atapi-cd.c: + +*** atapi-cd.c.orig Sun Jan 21 14:42:57 2001 +--- atapi-cd.c Sun Jan 21 14:47:13 2001 +*************** +*** 1163,1174 **** + return; + } + } +! if (blocksize == 2048) +! ccb[0] = ATAPI_READ_BIG; +! else { +! ccb[0] = ATAPI_READ_CD; +! ccb[9] = 0x10; +! } + } + else + ccb[0] = ATAPI_WRITE_BIG; +--- 1163,1182 ---- + return; + } + } +! switch (blocksize) { +! case 2048: +! ccb[0] = ATAPI_READ_BIG; +! break; +! +! case 2352: +! ccb[0] = ATAPI_READ_CD; +! ccb[9] = 0xf8; +! break; +! +! default: +! ccb[0] = ATAPI_READ_CD; +! ccb[9] = 0x10; +! } + } + else + ccb[0] = ATAPI_WRITE_BIG; + +------------------------------------------------------------------------ + diff --git a/doc/README.syncfb b/doc/README.syncfb new file mode 100644 index 000000000..092188eb3 --- /dev/null +++ b/doc/README.syncfb @@ -0,0 +1,144 @@ + + ===== ===== + XINE video output plugin for MATROX G400 / G200 cards *only* + ===== ===== + + + +* WHAT IS THIS PLUGIN ABOUT and WHY SHOULD I EVEN CONSIDER TO USE IT? :) + + This XINE video output plugin uses the so called Teletux driver which + provides special hardware features of the Matrox G400 and G200 cards + like deinterlacing, scaling and YUV data to RGB conversion --- just to + name a few. The plugin makes all those features available to XINE and + because all this tasks are done by the graphics card there is no need + for XINE to do them in software -- so you save precious CPU time which + you may gonna need for other things. :-) + + Another feature of this plugin is the synchronisation of the video + picture with the refresh of your screen. Before you ask why you would + need that - here the explanation... :) + + In order to have an optimal DVD playback the update of the image needs + to be syncronized with the refresh of the screen. Otherwise you will + sometimes see part of frame n and part of frame n+1 during an refresh. + This results in tearing artefacts on moving objects. + + When using this plugin the update of the screen is done in the V-SYNC + phase of your screen - and the tearing artefacts are gone forever. + + +* AND HOW DOES IT WORK? + + The Teletux driver is a module you will have to load that makes a + special device (/dev/syncfb) available which is opened by the plugin + and controlled with certain ioctl calls. Quite easy, isn't it? ;) + + That module is based on the mga_vid driver from Aaron Holzmann and was + advanced (and reworked) by Matthias Oelmann. + + +* OK I HEARD ENOUGH - HOW DO I INSTALL and USE IT? :) + + First of all you will need to get the Teletux driver itself. It's + available at http://teletux.sourceforge.net. Once you downloaded it, + unpack it to some directory of your choice, please read the README and + compile it (a normal "make" should work out-of-the-box). Now there are + only a few things left for you to do... + + 1) Become root. Hey now you can take over the world *evil laugh* :-))) + 2) Create a device called /dev/syncfb ===> mknod /dev/syncfb c 178 0 + 3) Copy the file "syncfb.o" to your modules directory (usually this is + /lib/modules/YOUR_KERNEL_VERSION/) and do a "depmod -a". + + This should be it. In order to use the Teletux driver you will have to + load it with the command "insmod syncfb.o" - please note that you will + have to load it every time you reboot if you wanna use the driver. + + XINE autodetects the driver and automaticly uses this plugin. + + It is possible now that the image during video playback is jerking. + This could be caused by the syncronisiation of the video image with + your screen refresh. You can easily fix that by switching your monitor + to the appropriate refresh rates (50 Hz for PAL, 60 Hz for NTSC). You + will need to add so called modelines to your XFree86 config to make + those 50 Hz/60 Hz modes available. + + Here is is a short listing of some sample modelines. Please add only + those two lines (for NTSC and PAL) which exactly fit the screensize + you are running your X Server with. You need to add those lines to the + monitor section of your XF86Config file as well as include their names + in the screen section (subsection display of the color depth your are + using). + + USE THE FOLLOWING MODELINES AT YOUR OWN RISK. THEY COULD DAMAGE YOUR + MONITOR PERMANTELY - PLEASE TAKE CAUTION AND DON'T BLAME US. YOU HAVE + BEEN WARNED. + + So much for the standard disclaimer. :) + + Note: If you want to be on the safe side, generate your very own + modelines with an application like kvideogen or use a service + like http://zaph.com/Modeline/ on the web. + + Also the modelines may need some fine tuning for your setup. You + can use xvidtune (comes with XFree86) to do that. + + # 1024x768 + + Modeline "1024x768pal" 64.94 1024 1040 1216 1328 768 768 775 802 + Modeline "1024x768ntsc" 54.32 1024 1040 1216 1328 768 768 774 802 + + # 1152x864 + + Modeline "1152x864pal" 68.82 1152 1168 1384 1496 864 864 871 902 + Modeline "1152x864ntsc" 80.93 1152 1168 1384 1496 864 864 872 902 + + # 1280x1024 + + none yet - will be added soon + + So before you run XINE please turn to the appropriate refresh rate and + the jerking should be gone. + + +* WHAT SCREENSIZE SHOULD I PREFER? + + Well. It is important that the screensize you choose for DVD playback + is exactly the same screensize you're starting up your X Server with. + So you shouldn't switch down to 1024x768 if you are running 1280x1024 + because that gives you a virtual screensize of 1280x1024 in a + resolution of 1024x768 - and the plugin cannot handle that yet. + + Now back to the question. A screensize of 1024x768 should be it. A DVD + is always 720x576 for pal and 720x480 for ntsc. If you've an anamorphe + DVD the image only has to be horizontally scaled to get back to the + original geometry of 16:9 which is easier to be done. + + +* WHERE IS THE WINDOW A VIDEO IS USUALLY DISPLAYED IN? + + The Teletux driver is writing directly to the video memory of the G400 + or G200 card and bypasses your X server. Getting that overlay into a + real window isn't as easy as you might think. + + For now a borderless window is being used which lays under the overlay + so you can click on the overlay (for the panel to appear) or issue any + command XINE supports by keyboard while you're over the overlay with + your mouse cursor. + + +* WHAT IS ON THE TODO LIST? + + The plugin does not yet activate the hardware deinterlacing. + The mouse cursor doesn't disappear yet when it should be disappearing. + Prevent the panel from hidding behind the overlay by moving it out of range. + Bug fixes, new features and optimizations. :-) + + +* CONTACTS and FEEDBACK + + Joachim Koening + Matthias Dahl + + or use the XINE User Mailinglist. (more infos see the general README) diff --git a/doc/bug_report_form b/doc/bug_report_form new file mode 100644 index 000000000..054071117 --- /dev/null +++ b/doc/bug_report_form @@ -0,0 +1,62 @@ +this is a generic bug report form that should help you making bug reports +(e.g. to post them on the xine-user mailing list at + ) + +Just use it as a checklist or copy/paste it into your bug report and replace +the quoted lines ("> ...") with the corresponding information! + + +> subject +> ------- +> +> _please_ give a meaningful subject! Something like "horizontal bars while +> playing" is good, something like "xine bug" is not. + + +bug description +--------------- + +> short, but complete, problem description + + +xine console output +------------------- + +> please _always_ include the complete console output xine produces. +> It contains important information about the hardware xine detected and +> what modules are used for audio/video output on your configuration. + +> you can produce a suitable log file with these command(s): +> xine [options] 2>&1 |tee /tmp/xine.log +> if the resulting /tmp/xine.log is very big, you may compress it with +> "gzip -9 /tmp/xine.log" before attaching it to your bug report. + + +xine version used +----------------- + +> release/CVS ? is it a debug version (did you a make debug?) +> Is the bug new with this release? +> If you don't use the current release: Why not?/Please recheck with the +> current version, first! + + +information about your operating system/software +------------------------------------------------ + +> operating system, e.g. linux, kernel 2.2.16 + +> X server, e.g. xfree 4.01, mga drivers + +> audio driver, e.g. alsa 0.5.9d + + +information about your hardware configuration +--------------------------------------------- + +> CPU, e.g. P II 400 + +> graphics card, e.g. Matrox G400, 32 MB RAM + +> sound card, e.g. SB Live + diff --git a/doc/dataflow.dia b/doc/dataflow.dia new file mode 100644 index 000000000..b4d470bf2 Binary files /dev/null and b/doc/dataflow.dia differ diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am new file mode 100644 index 000000000..de46beca4 --- /dev/null +++ b/doc/man/Makefile.am @@ -0,0 +1,9 @@ +SUBDIRS = fr en + +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/doc/man/en/Makefile.am b/doc/man/en/Makefile.am new file mode 100644 index 000000000..b70881881 --- /dev/null +++ b/doc/man/en/Makefile.am @@ -0,0 +1,11 @@ +man_MANS = xine.1 + +EXTRA_DIST = $(man_MANS) xine.1.in + +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 xine.1 diff --git a/doc/man/en/xine.1.in b/doc/man/en/xine.1.in new file mode 100644 index 000000000..2739c44c0 --- /dev/null +++ b/doc/man/en/xine.1.in @@ -0,0 +1,173 @@ +.\" -*-Nroff-*- +.\"" +.TH XINE 1x 2000-11-19 "The xine project" +.\" NAME should be all caps, SECTION should be 1-8, maybe w/ subsection +.\" other parms are allowed: see man(7), man(1) +.\"" +.SH NAME +xine \- MPEG2/MPEG1 audio/video player +.SH SYNOPSIS +.B xine +.I "[options] [MRL] ..." +.SH "DESCRIPTION" +This manual page documents briefly the +.BR xine +audio/video player. +.PP +.B xine +plays MPEG system streams, synchronizing audio and video substreams. It +can play streams from files, Video CDs, DVDs and other sources. +.SH OPTIONS +The programs follow the usual GNU command line syntax, with long +options starting with two dashes (`-'). +A summary of options are included below. +For a complete description, see the README and FAQ in @prefix@/share/doc/xine +or on the xine home page. +.TP +.B \-h, \-\-help +Show summary of options. +.TP +.B \-s, \-\-shared\-memory +Use X shared memory extension for output. +.br +This may be useful if you experience +problems using the Xv extension. Xv is used as default, if it is available. +Since Xv is hardware accelerated, it usually provides more features and +better performance. +.TP +.B \-a, \-\-audio\-channel +Select the given audio channel. is the audio channel number, default +is "0". +.br +For MPEG2-Streams, AC3 audio streams are numbered from 0 to 7, while MPEG +audio streams are numbered from 8 to 15 and lpcm audio streams are +numbered 16 to 23 (provided that there are this many audio substreams, +of course). Finding the right audio stream might needs some experimenting, +as some mp2-streams contain audio in strange tracks (track 0 and 1 may +be empty but track 2 contains valid audio, for example). +.TP +.B \-A, \-\-audio\-driver +Select audio driver. Valid drivers are "oss", "alsa", "esd" or "null". The +default is to use ESD when the "ESPEAKER" environment variable is set, +otherwise ALSA if present, otherwise OSS. The "null" driver may be used to +disable audio output, eg. if there are problems with your sound card. +.TP +.B \-u, \-\-spu\-channel +Select subpicture (subtitle) channel. is the subpicture channel +id, default is no subtitle (-1). +.TP +.B \-S, \-\-spdif +Enable AC3 output via SPDIF. Works only on some ALSA drivers that support +the AC3 passthrough feature. +.TP +.B \-p[f][h][q][d][v] +Start playing immediately after start. Can be followed by "f" to turn +on fullscreen mode and/or "h" to hide GUI, and/or by "q" for quitting +at the end. It is also possible to request the playlist from DVD 'd', +or VCD 'v'. +.TP +.B MRL (media resource locator) +.br +MRLs are similar to URLs in your web browser. They describe the media +to read from. valid MRLs may be plain file names or one of the following: +.BR file:// +.br +.BR fifo:// +.br +.BR stdin://mpeg1 +or +.BR "stdin://mpeg2" +.br +.BR dvd://VTS_xx_y.VOB +.br +.BR "vcd://" +.br +.BR "net://???" +.LP +Several MRLs may be specified in order to play a number of consecutive +streams. +.LP +If you don't specify any MRL, you'll have to select a file by drag'n-drop. +Dragging files from the GNOME Midnight Commander (gmc) is known to work. +.SH "SEE ALSO" +The programs are documented fully on the xine home page: +.IR "http://xine.sourceforge.net/" +.SH CONTROL KEYS +Many features can be controlled by pressing control keys. The Key bindings are: +.LP +.BR RETURN : +Play +.br +.BR SPACE +or +.BR P : +Pause +.br +.BR F : +Toggle fullscreen mode (Xv only) +.br +.BR G : +Hide/show the gui. +.br +.BR H : +Hide/show the video output window. +.br +.BR A : +Toggle aspect ratio (AUTO/16:9/4:3/DVB) +.br +.BR C : +Show/hide the video settings window. +.br +.BR E : +Eject the current media. +.br +.BR 0 : +Jump to start of current stream +.br +.BR 1..9 : +Jump to 10%..90% of current stream +.br +.BR PgUp : +Jump to previous stream in playlist +.br +.BR PgDown : +Jump to next stream in playlist +.br +.BR + : +Select next audio channel (may take up to a few seconds to take effect) +.br +.BR - : +Select prev audio channel +.br +.BR Ctrl +Show/hide mouse cursor (only when the GUI is hide) +.br +.BR > +or +.BR . : +Select next sub-title channel. +.br +.BR < +or +.BR , : +Select previous sub-title channel. +.br +.SH Synchronization fine tuning +Some streams have bad timestamps, so synchronization fails. This can be +tweaked using arrow keys: +.br +.BR Left : +press if video runs ahead of audio +.br +.BR Right : +press if video lags behind audio +.br +.BR Home : +press to reset audio/video offset to 0, so stream timestamps are unchanged. + +.SH AUTHOR +This manual page was written by Siggi Langauf , +for the xine project. Lots of additions by +Guenter Bartsch and +Daniel Caujolle-Bert + diff --git a/doc/man/fr/Makefile.am b/doc/man/fr/Makefile.am new file mode 100644 index 000000000..0335fd786 --- /dev/null +++ b/doc/man/fr/Makefile.am @@ -0,0 +1,46 @@ +mansubdir=/fr/man1 + +man_MANS = xine.1 + +EXTRA_DIST = $(man_MANS) xine.1.in + +install-man1: + $(mkinstalldirs) $(DESTDIR)$(mandir)$(mansubdir) + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ + else file=$$i; fi; \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " $(INSTALL_DATA) $$file $(DESTDIR)$(mandir)$(mansubdir)/$$inst"; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(mandir)$(mansubdir)/$$inst; \ + done + +uninstall-man1: + @list='$(man1_MANS)'; \ + l2='$(man_MANS)'; for i in $$l2; do \ + case "$$i" in \ + *.1*) list="$$list $$i" ;; \ + esac; \ + done; \ + for i in $$list; do \ + ext=`echo $$i | sed -e 's/^.*\\.//'`; \ + inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \ + inst=`echo $$inst | sed '$(transform)'`.$$ext; \ + echo " rm -f $(DESTDIR)$(mandir)$(mansubdir)/$$inst"; \ + rm -f $(DESTDIR)$(mandir)$(mansubdir)/$$inst; \ + 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 xine.1 diff --git a/doc/man/fr/xine.1.in b/doc/man/fr/xine.1.in new file mode 100644 index 000000000..708880d67 --- /dev/null +++ b/doc/man/fr/xine.1.in @@ -0,0 +1,165 @@ +.\" -*-Nroff-*- +.\"" +.TH XINE 1x 2000-11-19 "Le projet xine" +.SH NOM +xine \- Lecteur audio/vidéo MPEG2/MPEG1. +.SH SYNOPSIS +.B xine +.I "[options] [MRL] ..." +.SH DESCRIPTION +Cette page de manuel documente brièvement le lecteur audio/vidéo \fBxine\fP. +.PP +\fBxine\fP lis les flux système MPEG, synchronise les flux audio et vidèo. +Il peux lire les flux a partir de fichiers, CD Vidéo, DVD et d'autres sources. +.SH OPTIONS +Ce programme suis la syntaxe de ligne de commande GNU, avec les longues +options commençant par deux tirets ('-'). +Une list de ces options est incluse plus bas. +Pour une description complète, lisez les fichiers README et FAQ +dans @prefix@/share/doc/xine ou sur la homepage. +.TP +.B \-h, \-\-help +Affiche la liste des options. +.TP +.B \-s, \-\-shared\-memory +utilise l'extension 'X Shared Memory' pour la sortie. +.br +Cela peut être utile si vous rencontrez des problèmes en utilisant +l'extension 'Xv', Xv est utilisée par defaut, si elle est disponible. +Comme Xv est accélérée materiellement, elle offre plus de fonctionnalitées +et de meilleurs performances. +.TP +.B \-a, \-\-audio\-channel +Sélectionne le canal audio spécifié. est le numéro du canal, la valeur +par defaut est '0'. +.br +Pour les flux MPEG2, les flux audio AC3 sont numérotés de 0 à 7, tandis +que les flux MPEG sont numérotés de 8 à 39 (si il y a plusieurs sous +flux audio, bien entendu) +.TP +.B \-A, \-\-audio\-driver +Sélectionne le pilote audio. Les pilotes valides sont "oss" (defaut), +"alsa", "esd" ou "null". +Par defaut ESD est utilisé si la variable d'environnement "ESPEAKER" +est positionnée, sinon ALSA si présent, ou alors OSS. Le pilote "null" +peut être utilisé pour supprimer la sortie audio, par exemple, si il y +a des problemes avec la carte son. +.TP +.B \-u, \-\-spu\-channel +Sélectionne le canal de subpicture (sous-titres). est le numéro +du canal de subpicture, par défaut il n'y a pas de sous-titre (\-1) +.TP +.B \-S, \-\-spdif +Met en fonction la sortie AC3 via SPDIF. Ne fonctionne qu'avec +certains pilotes ALSA supportant la fonctionnalité AC3 taversante. +.TP +.B \-p[f][h][q][d][v], +Démarre la lecture immédiatement apres l'execution. Peut être suivi +par 'f' pour passer en mode plein écran, et/ou par 'h' pour +masquer le panneau de contrôle, et/ou par 'q' pour quitter +à la fin de la lecture. Il est possible d'obtenir automatiquement +les listes de lecture à partir d'un DVD 'd', ou d'un VCD 'v'. +.TP +.B MRL (media resource locator) +.br +Les MRLs sont similaires aux URLs de votre navigateur internet. Elles +définissent le média à utiliser comme source de lecture. +Les MRLs valides peuvent être les noms de fichiers ou un de ceux qui suis: +.br +.BR file:// +.br +.BR fifo:// +.br +.BR stdin://mpeg1 +or +.BR "stdin://mpeg2" +.br +.BR dvd://VTS_xx_y.VOB +.br +.BR "vcd://" +.br +.BR "net://???" +.LP +Plusieurs MRLs peuvent être spécifiées pour lire un nombre consecutif +de flux. +.LP +Si vous ne spécifiez aucune MRL, vous pourrez sélectionner un fichier +par glisser-lacher. +Glisser des fichiers depuis GNOME Midnight Commander (gmc) est connu +pour fonctionner. +.SH "VOIR AUSSI" +Le programme est complement documenté sur la homepage de xine: +.IR "http://xine.sourceforge.net/" +.SH TOUCHES DE CONTROLE +Beaucoup de fonctions peuvent êtres contrôlées en pressant certaines touches. +La liste de ces touches sont: +.LP +.BR ENTREE : +Lecture +.br +.BR ESPACE +ou +.BR P : +Pause +.br +.BR F : +Bascule plein écran (Xv seulement). +.br +.BR G : +Affiche/masque le panneau de contrôle. +.br +.BR H : +Affiche/masque la fenêtre de sortie. +.br +.BR A : +Bascule du ratio d'aspect (AUTO/16:9/4:3/DVB) +.br +.BR C : +Affiche/masque la fenêtre des réglages vidéo. +.br +.BR E : +Ejecte le média courant. +.br +.BR 0 : +Saute au début du flux courant. +.br +.BR 1..9 : +Saute à 10%..90% du flux courant. +.br +.BR PgUp : +Saute au flux precédent dans la liste de lecture. +.br +.BR PgDown : +Saute au flux suivant dans la liste de lecture. +.br +.BR + : +Sélectionne le canal audio suivant (peux prendre quelques secondes +avant effet). +.br +.BR - : +Sélectionne le canal audio precédent. +.br +.BR Ctrl +Affiche/masque le pointeur de souris (uniquement quand le panneau de +contrôle est masqué). +.br +.BR > +ou +.BR . : +Sélectionne le canal de sous-titres suivant. +.br +.BR < +ou +.BR , : +Sélectionne le canal de sous-titres precédant. +.br +.BR Gauche : +Change négativement la synchronisation A/V. +.br +.BR Droit : +Change positivement la synchronisation A/V. +.br +.BR Début : +Remise à zéro de la synchronisation A/V. +.SH AUTEURS +Cette page de manuel a été écrite par Siggi Langauf , traduite par Daniel Caujolle-Bert , pour le projet xine. diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 000000000..bdf7dcca3 --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,47 @@ +## +## Process this file with automake to produce Makefile.in +## + +EXTRA_DIST = xine.h.tmpl.in + +include_HEADERS = audio_out.h video_out.h xine.h + + +xine.h: xine.h.tmpl + @echo "creating xine.h"; \ + rm -f xine.h && \ + echo '/* !! DO NO EDIT THIS FILE, it is automatically generated */' \ + > xine.h && \ + cat xine.h.tmpl >> xine.h + + +debug: + +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 xine.h diff --git a/include/audio_out.h b/include/audio_out.h new file mode 100644 index 000000000..3e0118325 --- /dev/null +++ b/include/audio_out.h @@ -0,0 +1,97 @@ +/* + * 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_out.h,v 1.1 2001/04/18 22:36:42 f1rmb Exp $ + */ +#ifndef HAVE_AUDIO_OUT_H +#define HAVE_AUDIO_OUT_H + +#include + +/* + * audio output modes Used as Bitfield in AC3 decoder + */ + +#define AO_MODE_AC3 1 +#define AO_MODE_MONO 2 /* 1 sample == 2 bytes */ +#define AO_MODE_STEREO 4 /* 1 sample == 4 bytes */ +#define AO_MODE_4CHANNEL 8 /* 1 sample == 8 bytes */ +#define AO_MODE_5CHANNEL 16 /* 1 sample == 10 bytes */ + +typedef struct ao_functions_s +{ + + /* + * find out if desired output mode is supported by + * this driver + */ + + int (*is_mode_supported) (int mode); + + /* + * init device - buffer will be flushed(!) + * return value: <=0 : failure, 1 : ok + */ + + int (*open)(uint32_t bits, uint32_t rate, int mode); + + /* + * write audio data to output buffer - may block + * audio driver must sync sample playback with metronom + */ + + void (*write_audio_data)(int16_t* audio_data, uint32_t num_samples, + uint32_t pts); + + /* + * close the audio driver + */ + + void (*close)(void); + +} ao_functions_t; + +/* + * available drivers: + */ + +#define AO_DRIVER_UNSET -1 +#define AO_DRIVER_NULL 0 +#define AO_DRIVER_OSS 1 +#if defined(HAVE_ALSA) +# define AO_DRIVER_ALSA 2 +# if defined(HAVE_ESD) +# define AO_DRIVER_ESD 3 +# endif +#else /* no ALSA */ +# if defined(HAVE_ESD) +# define AO_DRIVER_ESD 2 +# endif +#endif + +/* + * find right device driver, init it + */ + +ao_functions_t *ao_init(char *driver_name) ; + +char *ao_get_available_drivers (); + +#endif + diff --git a/include/video_out.h b/include/video_out.h new file mode 100644 index 000000000..3a4ba0b72 --- /dev/null +++ b/include/video_out.h @@ -0,0 +1,327 @@ +/* + * 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_out.h,v 1.1 2001/04/18 22:36:44 f1rmb Exp $ + * + * + * xine version of video_out.h + * + */ + +#ifndef HAVE_VIDEO_OUT_H + +#define HAVE_VIDEO_OUT_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#if defined(XINE_COMPILE) +#include "configfile.h" +#include "metronom.h" +#else +#include "xine/configfile.h" +#include "xine/metronom.h" +#endif + +typedef struct vo_frame_s vo_frame_t; +typedef struct vo_driver_s vo_driver_t ; +typedef struct vo_instance_s vo_instance_t; +typedef struct img_buf_fifo_s img_buf_fifo_t; + +/* public part, video drivers may add private fields */ +struct vo_frame_s { + struct vo_frame_s *next; + + uint32_t PTS; + int bFrameBad; /* e.g. frame skipped or based on skipped frame */ + uint8_t *base[3]; + int nType; /* I, B or P frame */ + + int bDisplayLock, bDecoderLock, bDriverLock; + pthread_mutex_t mutex; /* so the various locks will be serialized */ + + int nID; /* debugging purposes only */ + + vo_instance_t *instance; + + /* + * member functions + */ + + /* this frame is no longer used by decoder */ + void (*free) (vo_frame_t *vo_img); + + /* tell video driver to copy/convert a slice of this frame */ + void (*copy) (vo_frame_t *vo_img, uint8_t **src); + + /* tell video driver that the decoder starts a new field */ + void (*field) (vo_frame_t *vo_img, int which_field); + + /* append this frame to the display queue, + returns number of frames to skip if decoder is late */ + int (*draw) (vo_frame_t *vo_img); + + /* this frame is no longer used by the video driver */ + void (*displayed) (vo_frame_t *vo_img); + + /* free memory/resources for this frame */ + void (*dispose) (vo_frame_t *vo_img); +}; + + +struct vo_instance_s { + + uint32_t (*get_capabilities) (vo_instance_t *this); /* for constants see below */ + + /* open display driver for video output */ + void (*open) (vo_instance_t *this); + + /* + * get_frame - allocate an image buffer from display driver + * + * params : width == width of video to display. + * height == height of video to display. + * ratio == aspect ration information + * format == FOURCC descriptor of image format + * duration == frame duration in 1/90000 sec + */ + vo_frame_t* (*get_frame) (vo_instance_t *this, uint32_t width, + uint32_t height, int ratio_code, + int format, uint32_t duration); + + /* video driver is no longer used by decoder => close */ + void (*close) (vo_instance_t *this); + + /* called on xine exit */ + void (*exit) (vo_instance_t *this); + + /* get/set driver properties, flags see below */ + int (*get_property) (vo_instance_t *this, int nProperty); + + /* set a property - returns value on succ, ~value otherwise*/ + int (*set_property) (vo_instance_t *this, + int nProperty, int value); + void (*get_property_min_max) (vo_instance_t *this, + int nProperty, int *min, int *max); + + /* + * handle events for video window (e.g. expose) + * parameter will typically be something like a pointer + * to an XEvent structure for X11 drivers, but + * may be something different for, say, fb drivers + */ + void (*handle_event) (vo_instance_t *this, void *event) ; + + /* + * get whatever is usefull to contact the window/video output + * (mostly usefull for the gui if it wants to access + * the video output window) + */ + void* (*get_window) (vo_instance_t *this); + + /* private stuff */ + + vo_driver_t *driver; + metronom_t *metronom; + + img_buf_fifo_t *free_img_buf_queue; + img_buf_fifo_t *display_img_buf_queue; + + int video_loop_running; + pthread_t video_thread; + + uint32_t pts_per_half_frame; + uint32_t pts_per_frame; + + int num_frames_delivered; + int num_frames_skipped; + int num_frames_discarded; + +} ; + +/* constants for the get/set property functions */ + +#define VO_PROP_WINDOW_VISIBLE 0 +#define VO_PROP_CURSOR_VISIBLE 1 +#define VO_PROP_FULLSCREEN 2 +#define VO_PROP_INTERLACED 3 +#define VO_PROP_ASPECT_RATIO 4 +#define VO_PROP_HUE 5 +#define VO_PROP_SATURATION 6 +#define VO_PROP_CONTRAST 7 +#define VO_PROP_BRIGHTNESS 8 +#define VO_PROP_COLORKEY 9 +#define VO_NUM_PROPERTIES 10 + +/* image formats that can be supported by display drivers: */ + +#define IMGFMT_YV12 0x32315659 +#define IMGFMT_YUY2 (('2'<<24)|('Y'<<16)|('U'<<8)|'Y') +#define IMGFMT_RGB (('R'<<24)|('G'<<16)|('B'<<8)) + +/* possible ratios for the VO_PROP_ASPECT_RATIO call */ + +#define ASPECT_AUTO 0 +#define ASPECT_ANAMORPHIC 1 /* 16:9 */ +#define ASPECT_FULL 2 /* 4:3 */ +#define ASPECT_DVB 3 /* 1:2 */ + +/* video driver capabilities */ + +/* driver copies image (i.e. converts it to + rgb buffers in the private fields of image buffer) */ +#define VO_CAP_COPIES_IMAGE 0x00000001 + +#define VO_CAP_RGB 0x00000002 /* driver can handle 24bit rgb pictures */ +#define VO_CAP_YV12 0x00000004 /* driver can handle YUV 4:2:0 pictures */ +#define VO_CAP_YUY2 0x00000008 /* driver can handle YUY2 pictures */ + +#define VO_CAP_HUE 0x00000010 /* driver can set HUE value */ +#define VO_CAP_SATURATION 0x00000020 /* driver can set SATURATION value */ +#define VO_CAP_BRIGHTNESS 0x00000040 /* driver can set BRIGHTNESS value */ +#define VO_CAP_CONTRAST 0x00000080 /* driver can set CONTRAST value */ +#define VO_CAP_COLORKEY 0x00000100 /* driver can set COLORKEY value */ + +/* + * vo_driver_s contains the function every display driver + * has to implement. The vo_new_instance function (see below) + * should then be used to construct a vo_instance using this + * driver. Some of the function pointers will be copied + * directly into vo_instance_s, others will be called + * from generic vo functions. + */ + + +struct vo_driver_s { + + uint32_t (*get_capabilities) (vo_driver_t *this); /* for constants see below */ + + /* + * allocate an vo_frame_t struct, + * the driver must supply the copy, field and dispose functions + */ + vo_frame_t* (*alloc_frame) (vo_driver_t *this); + + + /* + * check if the given image fullfills the format specified + * (re-)allocate memory if necessary + */ + void (*update_frame_format) (vo_driver_t *this, vo_frame_t *img, + uint32_t width, uint32_t height, + int ratio_code, int format); + + /* display a given frame */ + void (*display_frame) (vo_driver_t *this, vo_frame_t *vo_img); + + int (*get_property) (vo_driver_t *this, int property); + int (*set_property) (vo_driver_t *this, + int property, int value); + void (*get_property_min_max) (vo_driver_t *this, + int property, int *min, int *max); + + void (*handle_event) (vo_driver_t *this, void *event) ; + void* (*get_window) (vo_driver_t *this); + + /* set logo visibility */ + void (*set_logo_mode) (vo_driver_t *this, int show_logo); + + void (*exit) (vo_driver_t *this); +}; + + +/* + * build a video_out_instance from + * a given video driver + */ + +vo_instance_t *vo_new_instance (vo_driver_t *driver, metronom_t *metronom) ; + +/* + * init a video driver. The driver is selected either + * by auto-detection or (if given) by the driver_name + */ + +vo_instance_t *vo_init (char *driver_name); + +/* returns a list of available drivers */ + +char *vo_get_available_drivers (); + +/* + * driver-specific stuff starts here + */ + + +vo_driver_t *init_video_out_xv (Display *display, config_values_t *config) ; + +/* FIXME + vo_driver_t *init_video_out_mga () ; + vo_driver_t *init_video_out_xshm () ; + vo_functions_t *init_video_out_x11 () ; + FIXME +*/ + + +#warning "FIXME" +#ifndef VIDEOOUT_COMPILE +static inline int vo_setup (vo_instance_t * instance, int width, int height) +{ + // return instance->setup (instance, width, height); + return 1; +} + +static inline void vo_close (vo_instance_t * instance) +{ + if (instance->close) + instance->close (instance); +} + +#define VO_TOP_FIELD 1 +#define VO_BOTTOM_FIELD 2 +#define VO_BOTH_FIELDS (VO_TOP_FIELD | VO_BOTTOM_FIELD) +#define VO_PREDICTION_FLAG 4 + +static inline vo_frame_t * vo_get_frame (vo_instance_t * instance, int flags) +{ + //return instance->get_frame (instance, flags); + return instance->get_frame (instance, 0, 0, 0, 0, 0); +} + +static inline void vo_field (vo_frame_t * frame, int flags) +{ + if (frame->field) + frame->field (frame, flags); +} + +static inline void vo_draw (vo_frame_t * frame) +{ + frame->draw (frame); +} +#endif +#warning "FIXME" +#endif + + + diff --git a/include/xine.h.tmpl.in b/include/xine.h.tmpl.in new file mode 100644 index 000000000..9f468cdd2 --- /dev/null +++ b/include/xine.h.tmpl.in @@ -0,0 +1,171 @@ +/* + * 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.h.tmpl.in,v 1.1 2001/04/18 22:36:42 f1rmb Exp $ + * + */ + +#ifndef HAVE_XINE_H +#define HAVE_XINE_H + +#if !defined(XINE_COMPILE) + +#include +#include "input_plugin.h" +#include "audio_out.h" +#include "video_out.h" +#include "configfile.h" +#include "demux.h" + +#define XINE_MAJOR_VERSION @XINE_MAJOR@ +#define XINE_MINOR_VERSION @XINE_MINOR@ +#define XINE_SUB_VERSION @XINE_SUB@ + + +typedef void xine_t; + +#endif + + +/* nStatus : current xine status */ +typedef void (*gui_status_callback_func_t)(int nStatus); + +/* + * player status constants: + */ + +#define XINE_STOP 0 +#define XINE_PLAY 1 +#define XINE_PAUSE 2 +#define XINE_QUIT 3 + +#if !defined(XINE_COMPILE) +/* + * init xine - call once at startup + * + */ + +xine_t *xine_init (vo_instance_t *vo, + ao_functions_t *ao, + gui_status_callback_func_t gui_status_callback, + config_values_t *config, int demux_strategy, uint32_t debug_lvl) ; + +/* + * open a stream and play it + * + * name : mrl to open + * pos : start position 0..65535 + * + */ +void xine_play (xine_t *this, char *MRL, int pos); + + +/* + * toggle pause mode + */ +void xine_pause (xine_t *this); + + +/* + * stop playing + */ +void xine_stop (xine_t *this); + +/* + * tell current input plugin to eject media. + */ +int xine_eject(xine_t *this); + +/* + * return current status (XINE_PLAY/XINE_STOP...) + */ +int xine_get_status (xine_t *this); + +/* + * get current position in stream + * returns position (range : 0 - 65535) + */ +int xine_get_current_position (xine_t *this); + +/* + * return the current audio channel + */ +int xine_get_audio_channel (xine_t *this); + +/* + * set desired audio channel + */ +void xine_select_audio_channel (xine_t *this, int channel); + +/* + * return the current SPU channel + */ +int xine_get_spu_channel (xine_t *this); + +/* + * set desired SPU channel + */ +void xine_select_spu_channel (xine_t *this, int channel); + +/* + * exit xine + */ +void xine_exit (xine_t *this); + +/* + * browsing support + */ + +/* + * some input plugins are browseable + * returns a list of ids of these plugins + */ +char **xine_get_browsable_input_plugin_ids (xine_t *this) ; + +/* + * browse function + * asks input plugin named to return + * a list of available MRLs in domain/directory + * + * start_mrl may be NULL indicating the toplevel domain/dir + * returns start_mrl if start_mrl is a valid MRL, not a directory + * returns NULL if start_mrl is an invalid MRL, not even a directory + */ + +char **xine_get_browse_mrls (xine_t *this, char *plugin_id, + char *start_mrl); + +/* + * autoplay support + */ + +/* + * some input plugins can generate autoplay lists + * returns a list of ids of these plugins + */ +char **xine_get_autoplay_input_plugin_ids (xine_t *this) ; + +/* + * get autoplay MRL list for input plugin named + */ +char **xine_get_autoplay_mrls (xine_t *this, char *plugin_id); + +#endif + +#endif diff --git a/m4/Makefile.am b/m4/Makefile.am new file mode 100644 index 000000000..a06ac6530 --- /dev/null +++ b/m4/Makefile.am @@ -0,0 +1,19 @@ +## +## Process this file with automake to produce Makefile.in +## +m4datadir = @ACLOCAL_DIR@ +m4data_DATA = xine.m4 + +EXTRA_DIST = _xine.m4 $(m4data_DATA) + +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/m4/_xine.m4 b/m4/_xine.m4 new file mode 100644 index 000000000..e59117a22 --- /dev/null +++ b/m4/_xine.m4 @@ -0,0 +1,106 @@ +dnl +AC_DEFUN([AC_CHECK_LIRC], + [AC_ARG_ENABLE(lirc, + [ --disable-lirc Turn off LIRC support.], + , enable_lirc=yes) + + if test x"$enable_lirc" = xyes; then + have_lirc=yes + AC_REQUIRE_CPP + AC_CHECK_LIB(lirc_client,lirc_init, + AC_CHECK_HEADER(lirc/lirc_client.h, true, have_lirc=no), have_lirc=no) + if test "$have_lirc" = "yes"; then + + if test x"$LIRC_PREFIX" != "x"; then + lirc_libprefix="$LIRC_PREFIX/lib" + LIRC_INCLUDE="-I$LIRC_PREFIX/include" + fi + for llirc in $lirc_libprefix /lib /usr/lib /usr/local/lib; do + AC_CHECK_FILE("$llirc/liblirc_client.a", + LIRC_LIBS="$llirc/liblirc_client.a" + AC_DEFINE(HAVE_LIRC),,) + done + else + AC_MSG_RESULT([*** LIRC client support not available, LIRC support will be disabled ***]); + fi + fi + + AC_SUBST(LIRC_LIBS) + AC_SUBST(LIRC_INCLUDE) +]) + + +dnl AC_C_ATTRIBUTE_ALIGNED +dnl define ATTRIBUTE_ALIGNED_MAX to the maximum alignment if this is supported +AC_DEFUN([AC_C_ATTRIBUTE_ALIGNED], + [AC_CACHE_CHECK([__attribute__ ((aligned ())) support], + [ac_cv_c_attribute_aligned], + [ac_cv_c_attribute_aligned=0 + for ac_cv_c_attr_align_try in 2 4 8 16 32 64; do + AC_TRY_COMPILE([], + [static char c __attribute__ ((aligned($ac_cv_c_attr_align_try))) = 0 +; return c;], + [ac_cv_c_attribute_aligned=$ac_cv_c_attr_align_try]) + done]) + if test x"$ac_cv_c_attribute_aligned" != x"0"; then + AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], + [$ac_cv_c_attribute_aligned],[maximum supported data alignment]) + fi]) + +dnl AC_TRY_CFLAGS (CFLAGS, [ACTION-IF-WORKS], [ACTION-IF-FAILS]) +dnl check if $CC supports a given set of cflags +AC_DEFUN([AC_TRY_CFLAGS], + [AC_MSG_CHECKING([if $CC supports $1 flags]) + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$1" + AC_TRY_COMPILE([],[],[ac_cv_try_cflags_ok=yes],[ac_cv_try_cflags_ok=no]) + CFLAGS="$SAVE_CFLAGS" + AC_MSG_RESULT([$ac_cv_try_cflags_ok]) + if test x"$ac_cv_try_cflags_ok" = x"yes"; then + ifelse([$2],[],[:],[$2]) + else + ifelse([$3],[],[:],[$3]) + fi]) + + +dnl AC_CHECK_GENERATE_INTTYPES_H (INCLUDE-DIRECTORY) +dnl generate a default inttypes.h if the header file does not exist already +AC_DEFUN([AC_CHECK_GENERATE_INTTYPES], + [AC_CHECK_HEADER([inttypes.h],[], + [AC_COMPILE_CHECK_SIZEOF([char],[1]) + AC_COMPILE_CHECK_SIZEOF([short],[2]) + AC_COMPILE_CHECK_SIZEOF([int],[4]) + AC_COMPILE_CHECK_SIZEOF([long long],[8]) + cat >$1/inttypes.h << EOF +#ifndef _INTTYPES_H +#define _INTTYPES_H +/* default inttypes.h for people who do not have it on their system */ +#if (!defined __int8_t_defined) && (!defined __BIT_TYPES_DEFINED__) +#define __int8_t_defined +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +#ifdef ARCH_X86 +typedef signed long long int64_t; +#endif +#endif +#if (!defined _LINUX_TYPES_H) +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +#ifdef ARCH_X86 +typedef unsigned long long uint64_t; +#endif +#endif +#endif +EOF + ])]) + + +dnl AC_COMPILE_CHECK_SIZEOF (TYPE SUPPOSED-SIZE) +dnl abort if the given type does not have the supposed size +AC_DEFUN([AC_COMPILE_CHECK_SIZEOF], + [AC_MSG_CHECKING(that size of $1 is $2) + AC_TRY_COMPILE([],[switch (0) case 0: case (sizeof ($1) == $2):;],[], + [AC_MSG_ERROR([can not build a default inttypes.h])]) + AC_MSG_RESULT([yes])]) diff --git a/m4/xine.m4 b/m4/xine.m4 new file mode 100644 index 000000000..3f30959ea --- /dev/null +++ b/m4/xine.m4 @@ -0,0 +1,201 @@ +dnl Configure paths for XINE +dnl +dnl Copyright (C) 2001 Daniel Caujolle-Bert +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +dnl +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a configuration +dnl script generated by Autoconf, you may include it under the same +dnl distribution terms that you use for the rest of that program. +dnl + +dnl AM_PATH_XINE([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) +dnl Test for XINE, and define XINE_CFLAGS and XINE_LIBS +dnl +AC_DEFUN(AM_PATH_XINE, +[dnl +dnl Get the cflags and libraries from the xine-config script +dnl +AC_ARG_WITH(xine-prefix, + [ --with-xine-prefix=PFX Prefix where XINE is installed (optional)], + xine_config_prefix="$withval", xine_config_prefix="") +AC_ARG_WITH(xine-exec-prefix, + [ --with-xine-exec-prefix=PFX Exec prefix where XINE is installed (optional)], + xine_config_exec_prefix="$withval", xine_config_exec_prefix="") +AC_ARG_ENABLE(xinetest, + [ --disable-xinetest Do not try to compile and run a test XINE program],, enable_xinetest=yes) + + if test x$xine_config_exec_prefix != x ; then + xine_config_args="$xine_config_args --exec-prefix=$xine_config_exec_prefix" + if test x${XINE_CONFIG+set} != xset ; then + XINE_CONFIG=$xine_config_exec_prefix/bin/xine-config + fi + fi + if test x$xine_config_prefix != x ; then + xine_config_args="$xine_config_args --prefix=$xine_config_prefix" + if test x${XINE_CONFIG+set} != xset ; then + XINE_CONFIG=$xine_config_prefix/bin/xine-config + fi + fi + + min_xine_version=ifelse([$1], ,0.5.0,$1) + if test "x$enable_xinetest" != "xyes" ; then + AC_MSG_CHECKING(for XINE version >= $min_xine_version) + else + AC_PATH_PROG(XINE_CONFIG, xine-config, no) + AC_MSG_CHECKING(for XINE version >= $min_xine_version) + no_xine="" + if test "$XINE_CONFIG" = "no" ; then + no_xine=yes + else + XINE_CFLAGS=`$XINE_CONFIG $xine_config_args --cflags` + XINE_LIBS=`$XINE_CONFIG $xine_config_args --libs` + xine_config_major_version=`$XINE_CONFIG $xine_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + xine_config_minor_version=`$XINE_CONFIG $xine_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + xine_config_sub_version=`$XINE_CONFIG $xine_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + dnl if test "x$enable_xinetest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $XINE_CFLAGS" + LIBS="$XINE_LIBS $LIBS" +dnl +dnl Now check if the installed XINE is sufficiently new. (Also sanity +dnl checks the results of xine-config to some extent +dnl + AC_LANG_SAVE() + AC_LANG_C() + rm -f conf.xinetest + AC_TRY_RUN([ +#include +#include +#include + +int +main () +{ + int major, minor, sub; + char *tmp_version; + + system ("touch conf.xinetest"); + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = (char *) strdup("$min_xine_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, &sub) != 3) { + printf("%s, bad version string\n", "$min_xine_version"); + exit(1); + } + + if ((XINE_MAJOR_VERSION != $xine_config_major_version) || + (XINE_MINOR_VERSION != $xine_config_minor_version) || + (XINE_SUB_VERSION != $xine_config_sub_version)) + { + printf("\n*** 'xine-config --version' returned %d.%d.%d, but XINE (%d.%d.%d)\n", + $xine_config_major_version, $xine_config_minor_version, $xine_config_sub_version, + XINE_MAJOR_VERSION, XINE_MINOR_VERSION, XINE_SUB_VERSION); + printf ("*** was found! If xine-config was correct, then it is best\n"); + printf ("*** to remove the old version of XINE. You may also be able to fix the error\n"); + printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"); + printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); + printf("*** required on your system.\n"); + printf("*** If xine-config was wrong, set the environment variable XINE_CONFIG\n"); + printf("*** to point to the correct copy of xine-config, and remove the file config.cache\n"); + printf("*** before re-running configure\n"); + } + else + { + if ((XINE_MAJOR_VERSION > major) || + ((XINE_MAJOR_VERSION == major) && (XINE_MINOR_VERSION > minor)) || + ((XINE_MAJOR_VERSION == major) && (XINE_MINOR_VERSION == minor) && (XINE_SUB_VERSION >= sub))) + { + return 0; + } + else + { + printf("\n*** An old version of XINE (%d.%d.%d) was found.\n", + XINE_MAJOR_VERSION, XINE_MINOR_VERSION, XINE_SUB_VERSION); + printf("*** You need a version of XINE newer than %d.%d.%d. The latest version of\n", + major, minor, sub); + printf("*** XINE is always available from:\n"); + printf("*** http://xine.sourceforge.net\n"); + printf("***\n"); + printf("*** If you have already installed a sufficiently new version, this error\n"); + printf("*** probably means that the wrong copy of the xine-config shell script is\n"); + printf("*** being found. The easiest way to fix this is to remove the old version\n"); + printf("*** of XINE, but you can also set the XINE_CONFIG environment to point to the\n"); + printf("*** correct copy of xine-config. (In this case, you will have to\n"); + printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); + printf("*** so that the correct libraries are found at run-time))\n"); + } + } + return 1; +} +],, no_xine=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_xine" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$XINE_CONFIG" = "no" ; then + echo "*** The xine-config script installed by XINE could not be found" + echo "*** If XINE was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the XINE_CONFIG environment variable to the" + echo "*** full path to xine-config." + else + if test -f conf.xinetest ; then + : + else + echo "*** Could not run XINE test program, checking why..." + CFLAGS="$CFLAGS $XINE_CFLAGS" + LIBS="$LIBS $XINE_LIBS" + AC_TRY_LINK([ +#include +#include +], [ return ((XINE_MAJOR_VERSION) || (XINE_MINOR_VERSION) || (XINE_SUB_VERSION)); ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding XINE or finding the wrong" + echo "*** version of XINE. If it is not finding XINE, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" + echo "***"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means XINE was incorrectly installed" + echo "*** or that you have moved XINE since it was installed. In the latter case, you" + echo "*** may want to edit the xine-config script: $XINE_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + XINE_CFLAGS="" + XINE_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(XINE_CFLAGS) + AC_SUBST(XINE_LIBS) + AC_LANG_RESTORE() + rm -f conf.xinetest +]) diff --git a/misc/Makefile.am b/misc/Makefile.am new file mode 100644 index 000000000..14efe45d9 --- /dev/null +++ b/misc/Makefile.am @@ -0,0 +1,20 @@ +EXTRA_DIST = autogen.sh upload.pl SlackBuild.in SlackBuild build_rpms.sh \ + xine-lib.spec.in xine-lib.spec \ + debian/control debian/copyright debian/menu \ + debian/rules debian/changelog debian/xine.docs + +bin_SCRIPTS = xine-config + +datadir = $(XINE_SKINDIR) +data_DATA = xine_logo.png + +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/misc/SlackBuild.in b/misc/SlackBuild.in new file mode 100644 index 000000000..5db360cda --- /dev/null +++ b/misc/SlackBuild.in @@ -0,0 +1,191 @@ +#!/bin/sh +# +# This script generate some valid Slackware packages +# +# +# Some variables. +# +CWD=`pwd` +PACKAGE=@PACKAGE@.tgz +SLCK=$CWD/slack +PREFIX=@prefix@ +PKG=$CWD/slktmp +TMPBUILD=$CWD/tmpbuild +#DOINSTDIR=/install + +# +# Create package description for pkgtool. +# +do_descr() { +cat > package_descriptions << EOF +@PACKAGE@: @PACKAGE@ @SPEC_VERSION@. +@PACKAGE@: +@PACKAGE@: xine is a free gpl-licensed video player for unix-like systems. +@PACKAGE@: We support mpeg-2 and mpeg-1 system (audio + video multiplexed) streams, +@PACKAGE@: eventually mpeg-4 and other formats might be added. + +@PACKAGE@: xine plays the video and audio data of mpeg-2 videos and synchronizes +@PACKAGE@: the playback of both. Depending on the properties of the mpeg stream, +@PACKAGE@: playback will need more or less processor power, 100% frame rate +@PACKAGE@: has been seen on a 400 MHz P II system. +EOF +} + +# +# Building binaries process, then install and move package in right place +# +do_build() { + cd $CWD + rm -rf $TMPBUILD + mkdir -p $TMPBUILD + cd $TMPBUILD && tar -xzf $CWD/@TAR_NAME@.tar.gz + cd @TAR_NAME@ + DIE=1 + ./configure --prefix=$PREFIX && make && make install-strip prefix=$PKG/$PREFIX && \ + cd $PKG && \ + echo "n" | makepkg $PACKAGE && \ + mv $PACKAGE $SLCK && \ + cd $SLCK && DIE=0 + do_descr +} + +# +# Cleaning building directory +# +do_clean() { + rm -rf $TMPBUILD + rm -f $PACKAGE package_descriptions + rm -rf $PKG + cd $CWD +} + +# +# Build for PPro +# +build_pentiumpro() { + echo "*****************************************************" + echo + echo "building slack for @PACKAGE@ @VERSION@" + echo + echo "current architecture:pentiumpro" + echo "slackware package will be copied to ./slack directory" + echo + echo "*****************************************************" + rm -rf $PKG + export XINE_BUILD=i686-pc-linux-gnu + do_build + if test "$DIE" -eq 0; then + tar -czvf @PACKAGE@-@VERSION@-i686.tar.gz $PACKAGE package_descriptions + fi + do_clean +} + +# +# Build for Pentium +# +build_pentium() { + echo "*****************************************************" + echo + echo "building slack for @PACKAGE@ @VERSION@" + echo + echo "current architecture:pentium" + echo "slackware package will be copied to ./slack directory" + echo + echo "*****************************************************" + rm -rf $PKG + export XINE_BUILD=i586-pc-linux-gnu + do_build + if test "$DIE" -eq 0; then + tar -czvf @PACKAGE@-@VERSION@-i586.tar.gz $PACKAGE package_descriptions + fi + do_clean +} + +# +# Build for K6 +# +build_k6() { + echo "*****************************************************" + echo + echo "building slack for @PACKAGE@ @VERSION@" + echo + echo "current architecture:k6" + echo "slackware package will be copied to ./slack directory" + echo + echo "*****************************************************" + rm -rf $PKG + export XINE_BUILD=k6-pc-linux-gnu + do_build + if test "$DIE" -eq 0; then + tar -czvf @PACKAGE@-@VERSION@-k6.tar.gz $PACKAGE package_descriptions + fi + do_clean +} + +# +# Build for K7 +# +build_k7() { + echo "*****************************************************" + echo + echo "building slack for @PACKAGE@ @VERSION@" + echo + echo "current architecture:k7" + echo "slackware package will be copied to ./slack directory" + echo + echo "*****************************************************" + rm -rf $PKG + export XINE_BUILD=athlon-pc-linux-gnu + do_build + if test "$DIE" -eq 0; then + tar -czvf @PACKAGE@-@VERSION@-k7.tar.gz $PACKAGE package_descriptions + fi + do_clean +} + +# +# Main function +# +main() { + rm -rf $SLCK + mkdir -p $SLCK + rm -f config.cache && ./autogen.sh && make dist + build_pentiumpro + build_pentium + build_k6 + build_k7 + mv -f $CWD/@TAR_NAME@.tar.gz $SLCK +} + + +# +# Handle arguments if available. +# +build_arch() { + rm -rf $SLCK + mkdir -p $SLCK + rm -f config.cache && ./autogen.sh && make dist + $barch + mv -f $CWD/@TAR_NAME@.tar.gz $SLCK +} +case "$1" in + pentiumpro | ppro | i686 | 686) + barch=build_pentiumpro + build_arch + ;; + pentium | i586 | 586) + barch=build_pentium + build_arch + ;; + k6) + barch=build_k6 + build_arch + ;; + k7 | athlon) + barch=build_k7 + build_arch + ;; + *) + main + ;; +esac \ No newline at end of file diff --git a/misc/autogen.sh b/misc/autogen.sh new file mode 100755 index 000000000..2d347ee18 --- /dev/null +++ b/misc/autogen.sh @@ -0,0 +1,74 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. +# This was lifted from the Gimp, and adapted slightly by +# Raph Levien, slightly hacked for xine by Daniel Caujolle-Bert. + +DIE=0 + +PROG=xine-lib + +(autoconf --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have autoconf installed to compile $PROG." + echo "Download the appropriate package for your distribution," + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1 +} + +(libtool --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have libtool installed to compile $PROG." + echo "Get ftp://ftp.gnu.org/pub/gnu/libtool-1.2.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 +} + +(automake --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "You must have automake installed to compile $PROG." + echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 +} + +(aclocal --version) < /dev/null > /dev/null 2>&1 || { + echo + echo "**Error**: Missing aclocal. The version of automake" + echo "installed doesn't appear recent enough." + echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" + echo "(or a newer version if it is available)" + DIE=1 +} + +if [ "$DIE" -eq 1 ]; then + exit 1 +fi + +aclocalinclude="$ACLOCAL_FLAGS"; \ +(echo -n " + Running aclocal: "; \ + aclocal $aclocalinclude; \ + echo "done.") && \ +(echo -n " + Running libtoolize: "; \ + libtoolize --force; \ + echo "done.") && \ +(echo -n " + Running autoheader: "; \ + autoheader; \ + echo "done.") && \ +(echo -n " + Running automake: "; \ + automake --gnu --add-missing; \ + echo "done.") && \ +(echo -n " + Running autoconf: "; \ + autoconf; \ + echo "done.") + +rm -f config.cache + +if [ x"$NO_CONFIGURE" = "x" ]; then + echo " + Running 'configure $@':" + if [ -z "$*" ]; then + echo " ** If you wish to pass arguments to ./configure, please" + echo " ** specify them on the command line." + fi + ./configure "$@" && \ + echo "Now type 'make' to compile $PKG_NAME" || exit 1 +fi diff --git a/misc/build_rpms.sh.in b/misc/build_rpms.sh.in new file mode 100644 index 000000000..22630b35b --- /dev/null +++ b/misc/build_rpms.sh.in @@ -0,0 +1,93 @@ +#!/bin/sh + +#if [ $# -ne 1 ] ; then +# echo "usage: $0 version number" +# exit 1 +#fi + +# Some rpm checks +RPMVERSION=`rpm --version | tr [A-Z] [a-z] | sed -e 's/[a-z]//g' -e 's/\.//g' -e 's/ //g'` + +# rpm version 4 return 40 +if [ `expr $RPMVERSION` -lt 100 ]; then + RPMVERSION=`expr $RPMVERSION \* 10` +fi + +if [ `expr $RPMVERSION` -lt 400 ]; then + RPM_BA="rpm -ba -ta ./@PACKAGE@_@VERSION@.tar.gz" + RPM_BB="rpm -bb -ta ./@PACKAGE@_@VERSION@.tar.gz" +else + RPM_BA="rpm -ta ./@PACKAGE@_@VERSION@.tar.gz -ba" + RPM_BB="rpm -ta ./@PACKAGE@_@VERSION@.tar.gz -bb" +fi + +##VERSION="@XINE_MAJOR@.@XINE_MINOR@.@XINE_SUB@" + +echo "Creating tarball..." +rm -f config.cache && ./autogen.sh && make dist +mv -f @TAR_NAME@.tar.gz @PACKAGE@_@VERSION@.tar.gz +rm -rf rpms +mkdir rpms + +echo "*****************************************************" +echo +echo "building rpm for @PACKAGE@ @VERSION@" +echo +echo "current architecture:pentiumpro" +echo "rpms will be copied to ./rpms directory" +echo +echo "*****************************************************" + +export XINE_BUILD=i686-pc-linux-gnu + +eval $RPM_BA + +cp '/usr/src/redhat/SRPMS/@PACKAGE@-@SPEC_VERSION@-0.src.rpm' ./rpms/ +mv '/usr/src/redhat/RPMS/i386/@PACKAGE@-@SPEC_VERSION@-0.i386.rpm' './rpms/@PACKAGE@-@SPEC_VERSION@-0.i686.rpm' + +echo "*****************************************************" +echo +echo "building rpm for @PACKAGE@ @VERSION@" +echo +echo "current architecture:k6" +echo "rpms will be copied to ./rpms directory" +echo +echo "*****************************************************" + +export XINE_BUILD=k6-pc-linux-gnu + +eval $RPM_BB + +mv '/usr/src/redhat/RPMS/i386/@PACKAGE@-@SPEC_VERSION@-0.i386.rpm' './rpms/@PACKAGE@-@SPEC_VERSION@-0.k6.rpm' + +echo "*****************************************************" +echo +echo "building rpm for @PACKAGE@ @VERSION@" +echo +echo "current architecture:pentium" +echo "rpms will be copied to ./rpms directory" +echo +echo "*****************************************************" + +export XINE_BUILD=i586-pc-linux-gnu + +eval $RPM_BB + +mv '/usr/src/redhat/RPMS/i386/@PACKAGE@-@SPEC_VERSION@-0.i386.rpm' './rpms/@PACKAGE@-@SPEC_VERSION@-0.i586.rpm' + +echo "*****************************************************" +echo +echo "building rpm for @PACKAGE@ @VERSION@" +echo +echo "current architecture:k7" +echo "rpms will be copied to ./rpms directory" +echo +echo "*****************************************************" + +export XINE_BUILD=athlon-pc-linux-gnu + +eval $RPM_BB + +mv '/usr/src/redhat/RPMS/i386/@PACKAGE@-@SPEC_VERSION@-0.i386.rpm' './rpms/@PACKAGE@-@SPEC_VERSION@-0.k7.rpm' + +echo "Done." diff --git a/misc/debian/changelog b/misc/debian/changelog new file mode 100644 index 000000000..83d7296aa --- /dev/null +++ b/misc/debian/changelog @@ -0,0 +1,25 @@ +xine (0.4.0-2) unstable; urgency=low + + * added upstream ChangeLog (closes: Bug#88402) + + -- Siggi Langauf Sun, 4 Mar 2001 13:04:42 +0100 + +xine (0.4.0-1) unstable; urgency=low + + * new upstream version with totally new architecture (refer to ChangeLog) + + * now using seperate binary packages for input plugins + * switched to non-native package format + * separate binary package for DVD plugin + + + -- Siggi Langauf Sat, 3 Mar 2001 01:35:01 +0100 + + +(old changelog entries are in upstream ChangeLog) + + + +Local variables: +mode: debian-changelog +End: diff --git a/misc/debian/control b/misc/debian/control new file mode 100644 index 000000000..2e4c2d4bb --- /dev/null +++ b/misc/debian/control @@ -0,0 +1,52 @@ +Source: xine +Section: graphics +Priority: optional +Maintainer: Siggi Langauf +Build-Depends: debhelper (>>2.0.0), imlib-dev (>=1.9.8.1), libasound1-dev (>=0.5.9), liborbit-dev (>=0.5.6-1) +Standards-Version: 3.1.1 + +Package: xine +Architecture: i386 +Depends: ${shlibs:Depends} +Suggests: xserver-xfree86 (>> 4.0) +Description: MPEG, VCD, DVD audio/video player for X11 + Xine plays MPEG system streams (ie. MPEG videos with sound). In contrast + to many other players, it does its best to synchronize audio and video. + . + MPEG streams can be read from plain files, pipes, network sockets, Video CDs + or DVDs. + . + For DVD playback, an input plugin is required. You can use xine-dvd, the + original plugin that comes with xine. If you want to play region locked or + encrypted DVDs, you'll need an enhanced DVD plugin, like xine-dvd-css. + . + Xine currently _cannot_ play pure MPEG video streams (without audio). + You will need another Player (like smpeg-xmms or the old smpeg-gtv) + for this. + . + For optimal performance (and full screen support), the Xvideo extension (Xv) + is reqired. Xv is supported by some XFree4 drivers. Of course, xine will also + run with XFree 3.x, using the MIT-shm extension, but you might experience + performance problems. For windows codecs, Xv is required. + (See the README for more info) + . + Rudimentary support for AVI files (DivX;-) is known to work) is included. + However, you'll need windows codec DLLs for that. Of course, xine will + happily work without those DLLs, playing only MPEG streams. + +Package: xine-dvd +Architecture: i386 +Depends: xine (>=0.4.0), ${shlibs:Depends} +Conflicts: xine (<<0.4.0) +Provides: xine-input-plugin +Description: DVD (non-CSS) input plugin for xine + This input plugin enables xine to play unencrypted, region-free + DVDs. It does NOT contain CSS decryption or IFO parsing, so most + DVDs will look quite poor: Chapters, subtitle colors, names for + subtitle or audio channels, multi-angle support are not supported by + this plugin. + . + This is the "official" DVD plugin from the xine project. There are some + unofficial plugins which support CSS descrambling or IFO parsing. However, + the legal status of these features is unclear... + diff --git a/misc/debian/copyright b/misc/debian/copyright new file mode 100644 index 000000000..ef4e6b87e --- /dev/null +++ b/misc/debian/copyright @@ -0,0 +1,32 @@ +Xine was written by Günter Bartsch +and the xine development team. (see AUTHORS file for more credits) + +This package is maintained by Siggi Langauf as part of +the upstream source, so the Debian source package is the upstream source. +The original source, including current CVS versions can also be found on +the xine homapage at + +http://xine.sourceforge.net/ + + + +Copyright (C) 2000 the xine project + +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 + +On Debian systems, the full text of the GPL can be found in +/usr/share/common-licenses/GPL + + diff --git a/misc/debian/menu b/misc/debian/menu new file mode 100644 index 000000000..c78fa7283 --- /dev/null +++ b/misc/debian/menu @@ -0,0 +1,2 @@ +?package(xine):needs=X11 section=Apps/Viewers\ + title="xine" command="/usr/bin/xine" diff --git a/misc/debian/rules b/misc/debian/rules new file mode 100755 index 000000000..dca6fd40d --- /dev/null +++ b/misc/debian/rules @@ -0,0 +1,75 @@ +#!/usr/bin/make -f +# +# debian/rules file for xine, the debhelper version. +# inspired by a sample debian/rules file from dh_make + +# to make debhelper verbose: +#export DH_VERBOSE=1 + +export DH_COMPAT=2 + +# Build architecture "i686-pc-linux-gnu" ensures that all optimizations +# are compiled in. They are checked at runtime, so this has no portability +# issues (on i386 arch...) +ifeq ($(strip $(XINE_BUILD)),) +export XINE_BUILD=i686-pc-linux-gnu +endif + +configure: configure-stamp +configure-stamp: + dh_testdir + ./configure --prefix=/usr --mandir=/usr/share/man + touch configure-stamp + +build: configure-stamp build-stamp +build-stamp: + dh_testdir + $(MAKE) + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + -$(MAKE) distclean + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + $(MAKE) install prefix=`pwd`/debian/xine/usr \ + mandir=`pwd`/debian/xine/usr/share/man + chmod a-x debian/xine/usr/lib/xine/plugins/* + mkdir -p debian/xine-dvd/usr/lib/xine/plugins + mv debian/xine/usr/lib/xine/plugins/input_dvd.so \ + debian/xine-dvd/usr/lib/xine/plugins/input_dvd.so + rm debian/xine/usr/lib/xine/plugins/*.la +# The freebsd README is not really interesting for Debian users + -rm debian/xine/usr/share/doc/xine/README.freebsd + + +binary-indep: build install +# no architecture independent files. + + +binary-arch: build install + dh_testdir + dh_testroot + dh_installdocs + dh_installmenu +# dh_installmanpages + dh_installchangelogs -k ChangeLog + dh_strip + dh_compress + dh_fixperms +# dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/misc/debian/xine.docs b/misc/debian/xine.docs new file mode 100644 index 000000000..2904d3e30 --- /dev/null +++ b/misc/debian/xine.docs @@ -0,0 +1,3 @@ +AUTHORS +TODO +doc/dataflow.dia diff --git a/misc/upload.pl b/misc/upload.pl new file mode 100755 index 000000000..8a87dea16 --- /dev/null +++ b/misc/upload.pl @@ -0,0 +1,131 @@ +#!/usr/bin/perl +# +# upload.pl - upload files to the xine "Download" page +# +# usage: upload.pl [-y] [-r] [-s
] [...] +# +# OPTIONS: release-version: the version number of this file. If omitted, the +# newest version on the page is used. +# Only the last -r option counts. +# +# section: the heading under which this file should appear. If +# omitted, we'll try to autodetect it from the file suffix: +# .rpm => "RPMs" +# .tar.gz => "source tarball" +# .deb => "Debian" +# .dsc => "Debian" +# +# -y: don't ask for upload confirmation +# +# EXAMPLE: +# ./upload.pl -r1.0 xine_1.0_i386.deb -sSlackware xine-1.0.tar.gz +# + +## begin configuration ###################################################### + +$UPLOAD_HOST = "xine.sourceforge.net"; +$UPLOAD_PATH = "/home/groups/xine/htdocs"; +$INDEX_FILE = "download.html"; +$FILE_SUBDIR = "files"; +$TMP_DIR = "/tmp/xine-upload.$$"; +$PROGRAM_NAME = "xine"; +$LINK_FONT = ''; +$END_FONT = ''; + +## end of configuration ##################################################### + +mkdir $TMP_DIR, 0755 || die "could not mkdir $TMP_DIR"; +mkdir "$TMP_DIR/$FILE_SUBDIR", 0755; + +print "fetching old Download page...\n"; +system ("scp $UPLOAD_HOST:$UPLOAD_PATH/$INDEX_FILE $TMP_DIR"); +open(IN, "$TMP_DIR/$INDEX_FILE") || die "unable to open $TMP_DIR/$INDEX_FILE"; +if (!read(IN, $thepage, 409600)) { + die "unable to read $TMP_DIR/$INDEX_FILE"; +} +close(IN); + +if ($thepage =~ /

\s*$PROGRAM_NAME\s+(\S+)\s*<\/h1>/si) { + $current_release=$1; + print "current release is $current_release.\n"; +} +else { + $current_release="(unknown version)"; + print "WARNING: could not find current release in download page.\n"; +} + +## parse command line +$section = "source tarball"; +$release = $current_release; +%files = (); +$yes = 0; + +foreach (@ARGV) { + if (/^\-r/) { + $release = $_; + $release =~ s/\-r//; + } + elsif (/^\-s/) { + $section = $_; + $section =~ s/\-s//; + } + elsif (/^\-y/) { + $yes = 1; + } + else { + die "$_: no such file" unless -f $_; + $filen = $_; + $filen =~ s/^.*?([^\/]*)$/\1/; + $files{$section} .= " $filen"; + print "will add $filen to section $section.\n"; + system("cp $_ '$TMP_DIR/$FILE_SUBDIR'"); + } +} +print "using release id $release.\n"; + +## add new files to the page +sub ensureSection() { #$section, $release + $rel = $thepage; + $rel =~ s/^.*

\s*$PROGRAM_NAME\s+$release\s*<\/h1>//si; + $rel =~ s/

.*$//si; + if ($rel =~ /

\s*$section\s*<\/h2>/si) { + return; + } + else { + print "creating new section \"$section\" for release $release.\n"; + unless ($thepage =~ /

\s*$PROGRAM_NAME\s+$release\s*<\/h1>/si) { + $thepage = "

$PROGRAM_NAME $release

\n" . $thepage; + } + $newSection = "

$section

\n\n$LINK_FONT\n$END_FONT\n\n\n"; + $thepage =~ /^(.*

\s*$PROGRAM_NAME\s+$release\s*<\/h1>.*?)(

.*)$/is; + $thepage = $1.$newSection.$2; + return; + } +} + +print "editing Download page...\n"; +foreach (keys(%files)) { + $section = $_; + ensureSection(); + $newLinks = $files{$section}; + print "file list for \"$section\": $newLinks\n"; + $newLinks =~ s/ (\S*)/\1<\/a>
\n/sg; + $thepage =~ /^(.*

\s*$PROGRAM_NAME\s+$release\s*<\/h1>.*?

\s*$section\s*<\/h2>.*?)($END_FONT.*)$/is; + $thepage = $1 . $newLinks . $2; +} + +open(OUT, ">$TMP_DIR/$INDEX_FILE"); +print OUT $thepage; +close(OUT); + +unless ($yes) { + print "\nAre you sure you want to upload files? [no] "; + $answer = ; + $yes = 1 if $answer =~ /^y/i; +} + +if ($yes) { + system("scp -r '$TMP_DIR/$INDEX_FILE' '$TMP_DIR/$FILE_SUBDIR' '$UPLOAD_HOST:$UPLOAD_PATH'"); +} + +system("rm -r $TMP_DIR"); diff --git a/misc/xine-config.in b/misc/xine-config.in new file mode 100644 index 000000000..4081407dd --- /dev/null +++ b/misc/xine-config.in @@ -0,0 +1,81 @@ +#!/bin/sh +# +# + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +exec_prefix_set=no + +usage() +{ + cat <&2 +fi + +while test $# -gt 0; do + case "$1" in + -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + case $1 in + --prefix=*) + prefix=$optarg + if test $exec_prefix_set = no ; then + exec_prefix=$optarg + fi + ;; + --prefix) + echo_prefix=yes + ;; + --exec-prefix=*) + exec_prefix=$optarg + exec_prefix_set=yes + ;; + --exec-prefix) + echo_exec_prefix=yes + ;; + --version) + echo @XINE_MAJOR@.@XINE_MINOR@.@XINE_SUB@ + ;; + --cflags) + echo_cflags=yes + ;; + --libs) + echo_libs=yes + ;; + *) + usage 1 1>&2 + ;; + esac + shift +done + +if test "$echo_prefix" = "yes"; then + echo $prefix +fi + +if test "$echo_exec_prefix" = "yes"; then + echo $exec_prefix +fi + +if test "$echo_cflags" = "yes"; then + echo -I@includedir@ +fi + +if test "$echo_libs" = "yes"; then + echo -L@libdir@ -lxine +fi + diff --git a/misc/xine-lib.spec.in b/misc/xine-lib.spec.in new file mode 100644 index 000000000..4cc2c019c --- /dev/null +++ b/misc/xine-lib.spec.in @@ -0,0 +1,80 @@ +# Note that this is NOT a relocatable package +%define ver @SPEC_VERSION@ +%define rel 0 +%define prefix @prefix@ +%define name @PACKAGE@ + +Name: %{name} +Summary: A Free Video Player. +Summary(ko): °ø°³ µ¿¿µ»ó Ç÷¹À̾î +Version: %{ver} +Release: %{rel} +Copyright: GPL +Group: Applications/X11 +Source: http://xine.sourceforge.net/files/@PACKAGE@_@VERSION@.tar.gz +URL: http://xine.sourceforge.net +Packager: Daniel Caujolle-Bert +BuildRoot: /tmp/%{name}-root + +%description +xine is a free gpl-licensed video player for unix-like systems. +We support mpeg-2 and mpeg-1 system (audio + video multiplexed) streams, +eventually mpeg-4 and other formats might be added. + +xine plays the video and audio data of mpeg-2 videos and synchronizes +the playback of both. Depending on the properties of the mpeg stream, +playback will need more or less processor power, 100% frame rate +has been seen on a 400 MHz P II system. + +%description -l fr +xine est un lecteur vidéo libre sous license GPL pour les systèmes de +type unix. Nous supportons les flux mpeg-2 et mpeg-1 (audio + vidéo +multiplexés), éventuellement le mpeg-4 et d'autres formats peuvent +êtres ajoutés. + +xine joue les données vidéo et audio de vidéo mpeg-2 et synchronise +la lecture des deux. En fonction des propriétes du flux mpeg, +la lecture aura besoin de plus ou moins de puissance du processeur, +100% de restitution de trame a été vus sur un système PII 400MHz. + +%description -l ko +xine ´Â GPL¶óÀ̼±½º¸¦ µû¸£´Â UNIX¿ë °ø°³ µ¿¿µ»ó Ç÷¹À̾îÀÔ´Ï´Ù. ÀÌ +Ç÷¹À̾î´Â mpeg-2 ¿Í mpeg 1 ½ºÆ®¸²À» Áö¿øÇϸç, ÇöÀç´Â Áö¿øÇÏÁö +¾ÊÁö¸¸ ³ªÁß¿¡´Â mpeg-4 ¿Í ´Ù¸¥ Çü½ÄÀÇ µ¿¿µ»óµµ Áö¿øÇÒ ¿¹Á¤ÀÔ´Ï´Ù. + +%prep +%setup -n @TAR_NAME@ + +%build +./configure --prefix=%{prefix} +make + +%install +if [ -d $RPM_BUILD_ROOT ]; then rm -rf $RPM_BUILD_ROOT; fi +#mkdir -p $RPM_BUILD_ROOT/usr/include/X11/pixmaps +make install-strip prefix=$RPM_BUILD_ROOT%{prefix} +#cp doc/*.xpm $RPM_BUILD_ROOT/usr/include/X11/pixmaps + +#%post +#/sbin/ldconfig + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%{prefix}/bin/xine +%{prefix}/man/man1/xine.* +%{prefix}/man/fr/man1/xine.* +%{prefix}/lib/xine/plugins/*.la +%{prefix}/lib/xine/plugins/*.so +%{prefix}/share/xine/skins/* +%{prefix}/share/doc/xine/* + +%changelog +* Thu Mar 28 2001 Daniel Caujolle-Bert +- add korean summary, patch from Louis JANG +* Thu Jan 11 2001 Daniel Caujolle-Bert +- patch from Sung-Hyun Nam applied. +* Fri Oct 17 2000 Daniel Caujolle-Bert +- first spec file. diff --git a/misc/xine_logo.png b/misc/xine_logo.png new file mode 100644 index 000000000..3aad01fc9 Binary files /dev/null and b/misc/xine_logo.png differ 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 + * + * 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 + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include + +#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;icompressor,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;in_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;in_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;in_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(n0audio_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(bytesaudio_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(bytesvideo_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 +#include +#include +#include +#include + +#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 +#include +#include +#include +#include + +#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 +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include + +#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 (pLength = 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 (pvalid=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%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 + +#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 +#include +#include +#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) +# include +#elif defined(__linux__) +# include +#else +# error "Need the DVD ioctls" +#endif +#include +#include +#include +#include +#include +#include + +#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%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 -1) { + int nFiles3, nFiles2; + + UDFListDir (fd, "/VIDEO_TS", MAX_DIR_ENTRIES, filelist, &nFiles3); + + nFiles2 = 0; + for (i=0; i +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include +#include +#include +#include +#if defined (__linux__) +#include +#elif defined (__FreeBSD__) +#include +#include +#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://\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) || (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 +#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 +#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 +#include +#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 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 +#include +#include + +#include +#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 + +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 +#else + +#include + +#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 +#include +#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;icplendmant;) { + 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 +#include +#include "ac3.h" +#include "ac3_internal.h" + +#include + +#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 +#include +#include +#include +#include +#include + +#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 +#include +#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 +#include +#include + +#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 +#include +#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 +#include +#include +#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 +//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; infchans; 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 +#include +#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 +#include +#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 +#include +#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 - 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 . 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 + +#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 - 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 . 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 - 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 . 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 + * + * 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 +#include /* memcpy/memset, try to remove */ +#include +#include + +/* 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 + * + * 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 + +#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 + * + * 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 +#include + +#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 + * + * 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 +#include +#include +#include +#include + +#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 + * + * 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 + * + * 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 + +#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; + 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 + * + * 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 +#include + +#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 + * + * 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 +#include +#include +#include +#include + +#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 + * + * 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 + +#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 + * + * 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 + * + * 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 + * + * 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 +#include + +#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 + * + * 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 +#include +#include + +#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 + * + * 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 +#include +#include + +#include +#include +#include + +#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 +#include +#include + +#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 +#include + +#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->bsizeframesize) { + + 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;istereo) { + int jsbound = fr->jsbound; + register real *f0 = fraction[0]; + register real *f1 = fraction[1]; + ba = balloc; + for (sample=smpb,i=0;ifr; + 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= 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;jstereo-1; + int sblimit = fr->II_sblimit; + int jsbound = fr->jsbound; + int sblimit2 = fr->II_sblimit<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<bits); + *bita++ = (char) getbits(step); + } + for (i=sblimit-jsbound;i;i--,alloc1+=(1<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<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;ibits; + for (j=0;jbits; + 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;ibits; + 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;ilsf) + 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>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 +#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 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; chch[ch].gr[0].scfsi = -1; + si->ch[ch].gr[1].scfsi = getbits_fast(4); + } + + for (gr=0; gr<2; gr++) + { + for (ch=0; chch[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; chch[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;iscalefac_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 (; sbmaxb; 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 (; sbmaxb; 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(;sbfr; + 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;grlsf) + 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;ilsf); + + 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;imaxb;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;imaxb;i++) + *in0++ = *in1++; + } + break; + } + } + + for(ch=0;ch= 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 +#include +#include + +#ifndef WIN32 +#include +#include +#endif + +#include + +#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 +#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 + +#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 - 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 +#include +#include + +#include +#include + +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 - 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 +#include + +#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 + +#ifdef HAVE_MALLOC_H +#include +#else +#include +#endif + +#include "wine/driver.h" +#include "wine/pe_image.h" +#include "wine/winreg.h" +#include "wine/vfw.h" +#include "registry.h" + +#ifdef __FreeBSD__ +#include +#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 +#include +#include + +#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 + +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 +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#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(moved0) + { + 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; iprev) + { + 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 +#include +#include +#include +#include +#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 +#include +#include +#include +#include +#include +#include + +#include +#include +/* +#ifdef __linux__ +#include +#include +#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 +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_MMAN_H +#include +#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;iNumberOfFunctions;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 = ""; + + + 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;iTypeOffset[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)addrImageBase+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 +#include +#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;iNumberOfNamedEntries+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;iNumberOfNamedEntries+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;iNumberOfNamedEntries+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;iNumberOfNamedEntries+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;iNumberOfNamedEntries+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;iNumberOfNamedEntries+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 +#include +#include +#include +#include +#include + +#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, ®_size, 4); + regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value)); + for(i=0; ipw_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, ®_size, 4); + for(i=0; iprev) + { + 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; iprev) + { + 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=""; + 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(*countlen) + { + *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 +#include +#include +#include +#include +#include +#include +#include +#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 +#include + +#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] 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 +#include +#include + +#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 +#include +#ifdef HAVE_MALLOC_H +#include +#else +#include +#endif +#include +#include +#include +#include + +#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 +#include +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(offset20000000) + { + 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 +#include +#include +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; icb=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; i150)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; i150){ +// 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() + * LIST ('strl' + * strh() + * strf() + * ... additional header data + * LIST('movi' + * { LIST('rec' + * SubChunk... + * ) + * | SubChunk } .... + * ) + * [ ] + * ) + * + * 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 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 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 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 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 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 */ +#define STATFS_DEFINED_BY_SYS_VFS 1 + +/* Define if the struct statfs is defined by */ +#define STATFS_DEFINED_BY_SYS_STATFS 1 + +/* Define if the struct statfs is defined by */ +/* #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 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 header file. */ +/* #undef HAVE_GL_GL_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_GL_GLX_H */ + +/* Define if you have the header file. */ +#define HAVE_X11_XLIB_H 1 + +/* Define if you have the header file. */ +#define HAVE_X11_EXTENSIONS_XSHM_H 1 + +/* Define if you have the header file. */ +#define HAVE_X11_EXTENSIONS_XF86DGA_H 1 + +/* Define if you have the header file. */ +#define HAVE_X11_EXTENSIONS_XF86VMODE_H 1 + +/* Define if you have the header file. */ +#define HAVE_X11_XPM_H 1 + +/* Define if you have the header file. */ +#define HAVE_A_OUT_H 1 + +/* Define if you have the header file. */ +#define HAVE_A_OUT_H 1 + +/* Define if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define if you have the header file. */ +#define HAVE_ARPA_NAMESER_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_CURSES_H */ + +/* Define if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define if you have the header file. */ +#define HAVE_ELF_H 1 + +/* Define if you have the header file. */ +#define HAVE_FLOAT_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIBIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINK_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINUX_CDROM_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINUX_JOYSTICK_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_LINUX_UCDROM_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_MACHINE_SOUNDCARD_H */ + +/* Define if you have the header file. */ +#define HAVE_NCURSES_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define if you have the header file. */ +#define HAVE_PTY_H 1 + +/* Define if you have the header file. */ +#define HAVE_RESOLV_H 1 + +/* Define if you have the header file. */ +#define HAVE_SCHED_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SOCKET_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SOUNDCARD_H */ + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_CDIO_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_ERRNO_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_FILIO_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_IPC_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_LWP_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_MMAN_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_MODEM_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_MOUNT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_MSG_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_REG_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SHM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SIGNAL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_SOCKIO_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_SOUNDCARD_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_STATFS_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_STRTIO_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_SYSCALL_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_V86_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_V86INTR_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_VFS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_VM86_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYSCALL_H 1 + +/* Define if you have the header file. */ +#define HAVE_UCONTEXT_H 1 + +/* Define if you have the 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 +#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 +#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)&~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 "!\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 +#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 + * + * 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; ififo_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 +#include +#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; ipMem = 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 +#include +#include + +/* + * 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 +#include +#include +#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 + +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 + * + * 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 + +#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 +#include +#include +#include +#include + +#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 +#include +#include +#include +#include + +#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 +#include + +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 + +#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 + +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 +#include +#include +#include +#include +#include +#include + +/* + * + */ +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; ififo_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 +#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 +#include +#include +#include +#if defined (__linux__) +#include +#elif defined (__FreeBSD__) +#include +#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 +#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 -- cgit v1.2.3