summaryrefslogtreecommitdiff
path: root/core
authorkergoth <kergoth>2002-01-25 22:14:26 (UTC)
committer kergoth <kergoth>2002-01-25 22:14:26 (UTC)
commit15318cad33835e4e2dc620d033e43cd930676cdd (patch) (side-by-side diff)
treec2fa0399a2c47fda8e2cd0092c73a809d17f68eb /core
downloadopie-15318cad33835e4e2dc620d033e43cd930676cdd.zip
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.gz
opie-15318cad33835e4e2dc620d033e43cd930676cdd.tar.bz2
Initial revision
Diffstat (limited to 'core') (more/less context) (ignore whitespace changes)
-rw-r--r--core/.cvsignore13
-rw-r--r--core/applets/batteryapplet/.cvsignore3
-rw-r--r--core/applets/batteryapplet/Makefile.in122
-rw-r--r--core/applets/batteryapplet/battery.cpp152
-rw-r--r--core/applets/batteryapplet/battery.h55
-rw-r--r--core/applets/batteryapplet/batteryapplet.pro12
-rw-r--r--core/applets/batteryapplet/batteryappletimpl.cpp63
-rw-r--r--core/applets/batteryapplet/batteryappletimpl.h44
-rw-r--r--core/applets/batteryapplet/batterystatus.cpp140
-rw-r--r--core/applets/batteryapplet/batterystatus.h45
-rw-r--r--core/applets/batteryapplet/qpe-batteryapplet.control9
-rwxr-xr-xcore/applets/batteryapplet/qpe-batteryapplet.postinst2
-rwxr-xr-xcore/applets/batteryapplet/qpe-batteryapplet.postrm2
-rw-r--r--core/applets/clipboardapplet/Makefile.in115
-rw-r--r--core/applets/clipboardapplet/clipboard.cpp80
-rw-r--r--core/applets/clipboardapplet/clipboard.h47
-rw-r--r--core/applets/clipboardapplet/clipboardapplet.pro10
-rw-r--r--core/applets/clipboardapplet/clipboardappletimpl.cpp64
-rw-r--r--core/applets/clipboardapplet/clipboardappletimpl.h44
-rw-r--r--core/applets/clipboardapplet/qpe-clipboardapplet.control9
-rw-r--r--core/applets/clipboardapplet/qpe-clipboardapplet.postinst2
-rw-r--r--core/applets/clipboardapplet/qpe-clipboardapplet.postrm2
-rw-r--r--core/applets/clockapplet/.cvsignore3
-rw-r--r--core/applets/clockapplet/Makefile.in115
-rw-r--r--core/applets/clockapplet/clock.cpp97
-rw-r--r--core/applets/clockapplet/clock.h46
-rw-r--r--core/applets/clockapplet/clockapplet.pro12
-rw-r--r--core/applets/clockapplet/clockappletimpl.cpp65
-rw-r--r--core/applets/clockapplet/clockappletimpl.h46
-rw-r--r--core/applets/clockapplet/qpe-clockapplet.control9
-rwxr-xr-xcore/applets/clockapplet/qpe-clockapplet.postinst2
-rwxr-xr-xcore/applets/clockapplet/qpe-clockapplet.postrm2
-rw-r--r--core/applets/volumeapplet/.cvsignore3
-rw-r--r--core/applets/volumeapplet/Makefile.in115
-rw-r--r--core/applets/volumeapplet/qpe-volumeapplet.control9
-rwxr-xr-xcore/applets/volumeapplet/qpe-volumeapplet.postinst2
-rwxr-xr-xcore/applets/volumeapplet/qpe-volumeapplet.postrm2
-rw-r--r--core/applets/volumeapplet/volume.cpp199
-rw-r--r--core/applets/volumeapplet/volume.h75
-rw-r--r--core/applets/volumeapplet/volumeapplet.pro12
-rw-r--r--core/applets/volumeapplet/volumeappletimpl.cpp64
-rw-r--r--core/applets/volumeapplet/volumeappletimpl.h44
-rw-r--r--core/apps/calibrate/.cvsignore3
-rw-r--r--core/apps/calibrate/calibrate.cpp243
-rw-r--r--core/apps/calibrate/calibrate.h67
-rw-r--r--core/apps/calibrate/calibrate.pro1
-rw-r--r--core/apps/embeddedkonsole/.cvsignore2
-rw-r--r--core/apps/embeddedkonsole/Makefile.in285
-rw-r--r--core/apps/embeddedkonsole/MyPty.cpp279
-rw-r--r--core/apps/embeddedkonsole/MyPty.h88
-rw-r--r--core/apps/embeddedkonsole/TECommon.h114
-rw-r--r--core/apps/embeddedkonsole/TEHistory.cpp212
-rw-r--r--core/apps/embeddedkonsole/TEHistory.h75
-rw-r--r--core/apps/embeddedkonsole/TEScreen.cpp1197
-rw-r--r--core/apps/embeddedkonsole/TEScreen.h259
-rw-r--r--core/apps/embeddedkonsole/TEWidget.cpp1243
-rw-r--r--core/apps/embeddedkonsole/TEWidget.h202
-rw-r--r--core/apps/embeddedkonsole/TEmuVt102.cpp991
-rw-r--r--core/apps/embeddedkonsole/TEmuVt102.h135
-rw-r--r--core/apps/embeddedkonsole/TEmulation.cpp363
-rw-r--r--core/apps/embeddedkonsole/TEmulation.h117
-rw-r--r--core/apps/embeddedkonsole/default.keytab.h103
-rwxr-xr-xcore/apps/embeddedkonsole/embeddedkonsole.pro38
-rw-r--r--core/apps/embeddedkonsole/faded_bg.pngbin0 -> 1300 bytes
-rw-r--r--core/apps/embeddedkonsole/keytrans.cpp706
-rw-r--r--core/apps/embeddedkonsole/keytrans.h93
-rw-r--r--core/apps/embeddedkonsole/konsole.cpp512
-rw-r--r--core/apps/embeddedkonsole/konsole.h125
-rw-r--r--core/apps/embeddedkonsole/main.cpp60
-rw-r--r--core/apps/embeddedkonsole/qpe-embeddedkonsole.control9
-rw-r--r--core/apps/embeddedkonsole/session.cpp157
-rw-r--r--core/apps/embeddedkonsole/session.h93
-rw-r--r--core/apps/helpbrowser/.cvsignore2
-rw-r--r--core/apps/helpbrowser/Makefile.in119
-rw-r--r--core/apps/helpbrowser/helpbrowser.cpp227
-rw-r--r--core/apps/helpbrowser/helpbrowser.h69
-rw-r--r--core/apps/helpbrowser/helpbrowser.pro12
-rw-r--r--core/apps/helpbrowser/main.cpp34
-rw-r--r--core/apps/helpbrowser/qpe-helpbrowser.control10
-rw-r--r--core/apps/qcop/.cvsignore3
-rw-r--r--core/apps/qcop/Makefile.in102
-rw-r--r--core/apps/qcop/main.cpp85
-rw-r--r--core/apps/qcop/qcop.pro10
-rw-r--r--core/apps/qcop/qpe-qcop.control9
-rw-r--r--core/apps/textedit/.cvsignore3
-rw-r--r--core/apps/textedit/Makefile.in125
-rw-r--r--core/apps/textedit/inserttable.ui103
-rw-r--r--core/apps/textedit/main.cpp35
-rw-r--r--core/apps/textedit/qpe-textedit.control9
-rw-r--r--core/apps/textedit/qtextedit.h282
-rw-r--r--core/apps/textedit/textedit.cpp594
-rw-r--r--core/apps/textedit/textedit.h102
-rw-r--r--core/apps/textedit/textedit.po108
-rw-r--r--core/apps/textedit/textedit.pro16
-rw-r--r--core/launcher/.cvsignore7
-rw-r--r--core/launcher/Makefile.in867
-rw-r--r--core/launcher/appicons.cpp129
-rw-r--r--core/launcher/appicons.h51
-rw-r--r--core/launcher/apps.h83
-rw-r--r--core/launcher/background.cpp41
-rw-r--r--core/launcher/background.h40
-rw-r--r--core/launcher/desktop.cpp655
-rw-r--r--core/launcher/desktop.h129
-rw-r--r--core/launcher/info.cpp116
-rw-r--r--core/launcher/info.h55
-rw-r--r--core/launcher/inputmethods.cpp297
-rw-r--r--core/launcher/inputmethods.h76
-rw-r--r--core/launcher/irserver.cpp50
-rw-r--r--core/launcher/irserver.h20
-rw-r--r--core/launcher/launcher.cpp804
-rw-r--r--core/launcher/launcher.h136
-rw-r--r--core/launcher/launcher.pro110
-rw-r--r--core/launcher/launcherview.cpp596
-rw-r--r--core/launcher/launcherview.h81
-rw-r--r--core/launcher/main.cpp276
-rw-r--r--core/launcher/mrulist.cpp199
-rw-r--r--core/launcher/mrulist.h55
-rw-r--r--core/launcher/obexinterface.h40
-rw-r--r--core/launcher/packageslave.cpp97
-rw-r--r--core/launcher/packageslave.h52
-rw-r--r--core/launcher/qcopbridge.cpp416
-rw-r--r--core/launcher/qcopbridge.h95
-rw-r--r--core/launcher/qpe-taskbar.control9
-rw-r--r--core/launcher/quicklauncher.cpp49
-rw-r--r--core/launcher/quicklauncher.h40
-rw-r--r--core/launcher/shutdown.ui1323
-rw-r--r--core/launcher/shutdownimpl.cpp95
-rw-r--r--core/launcher/shutdownimpl.h50
-rw-r--r--core/launcher/sidething.cpp75
-rw-r--r--core/launcher/sidething.h43
-rw-r--r--core/launcher/stabmon.cpp92
-rw-r--r--core/launcher/stabmon.h34
-rw-r--r--core/launcher/startmenu.cpp171
-rw-r--r--core/launcher/startmenu.h76
-rw-r--r--core/launcher/syncdialog.ui228
-rw-r--r--core/launcher/systray.cpp107
-rw-r--r--core/launcher/systray.h58
-rw-r--r--core/launcher/taskbar.cpp314
-rw-r--r--core/launcher/taskbar.h86
-rw-r--r--core/launcher/transferserver.cpp1245
-rw-r--r--core/launcher/transferserver.h168
-rw-r--r--core/launcher/wait.cpp64
-rw-r--r--core/launcher/wait.h45
-rw-r--r--core/multimedia/opieplayer/.cvsignore2
-rw-r--r--core/multimedia/opieplayer/Makefile.in280
-rw-r--r--core/multimedia/opieplayer/audiodevice.cpp386
-rw-r--r--core/multimedia/opieplayer/audiodevice.h71
-rw-r--r--core/multimedia/opieplayer/audiowidget.cpp277
-rw-r--r--core/multimedia/opieplayer/audiowidget.h144
-rw-r--r--core/multimedia/opieplayer/libflash/Makefile.in644
-rw-r--r--core/multimedia/opieplayer/libflash/README191
-rw-r--r--core/multimedia/opieplayer/libflash/adpcm.cc235
-rw-r--r--core/multimedia/opieplayer/libflash/adpcm.h36
-rw-r--r--core/multimedia/opieplayer/libflash/bitmap.cc606
-rw-r--r--core/multimedia/opieplayer/libflash/bitmap.h72
-rw-r--r--core/multimedia/opieplayer/libflash/button.cc328
-rw-r--r--core/multimedia/opieplayer/libflash/button.h88
-rw-r--r--core/multimedia/opieplayer/libflash/character.cc233
-rw-r--r--core/multimedia/opieplayer/libflash/character.h90
-rw-r--r--core/multimedia/opieplayer/libflash/cxform.cc79
-rw-r--r--core/multimedia/opieplayer/libflash/cxform.h46
-rw-r--r--core/multimedia/opieplayer/libflash/displaylist.cc708
-rw-r--r--core/multimedia/opieplayer/libflash/displaylist.h80
-rw-r--r--core/multimedia/opieplayer/libflash/flash.cc275
-rw-r--r--core/multimedia/opieplayer/libflash/flash.h129
-rw-r--r--core/multimedia/opieplayer/libflash/font.cc105
-rw-r--r--core/multimedia/opieplayer/libflash/font.h56
-rw-r--r--core/multimedia/opieplayer/libflash/graphic.cc632
-rw-r--r--core/multimedia/opieplayer/libflash/graphic.h174
-rw-r--r--core/multimedia/opieplayer/libflash/graphic16.cc658
-rw-r--r--core/multimedia/opieplayer/libflash/graphic16.h39
-rw-r--r--core/multimedia/opieplayer/libflash/graphic24.cc648
-rw-r--r--core/multimedia/opieplayer/libflash/graphic24.h39
-rw-r--r--core/multimedia/opieplayer/libflash/graphic32.cc657
-rw-r--r--core/multimedia/opieplayer/libflash/graphic32.h39
-rw-r--r--core/multimedia/opieplayer/libflash/jconfig.h45
-rw-r--r--core/multimedia/opieplayer/libflash/jerror.h291
-rw-r--r--core/multimedia/opieplayer/libflash/jmorecfg.h363
-rw-r--r--core/multimedia/opieplayer/libflash/jpeglib.h1096
-rw-r--r--core/multimedia/opieplayer/libflash/libflash.pro15
-rw-r--r--core/multimedia/opieplayer/libflash/libflashplugin.cpp223
-rw-r--r--core/multimedia/opieplayer/libflash/libflashplugin.h96
-rw-r--r--core/multimedia/opieplayer/libflash/libflashpluginimpl.cpp70
-rw-r--r--core/multimedia/opieplayer/libflash/libflashpluginimpl.h53
-rw-r--r--core/multimedia/opieplayer/libflash/matrix.cc68
-rw-r--r--core/multimedia/opieplayer/libflash/matrix.h49
-rw-r--r--core/multimedia/opieplayer/libflash/movie.cc171
-rw-r--r--core/multimedia/opieplayer/libflash/movie.h68
-rw-r--r--core/multimedia/opieplayer/libflash/program.cc921
-rw-r--r--core/multimedia/opieplayer/libflash/program.h185
-rw-r--r--core/multimedia/opieplayer/libflash/rect.h55
-rw-r--r--core/multimedia/opieplayer/libflash/script.cc1988
-rw-r--r--core/multimedia/opieplayer/libflash/script.h144
-rw-r--r--core/multimedia/opieplayer/libflash/shape.cc1205
-rw-r--r--core/multimedia/opieplayer/libflash/shape.h181
-rw-r--r--core/multimedia/opieplayer/libflash/sound.cc439
-rw-r--r--core/multimedia/opieplayer/libflash/sound.h83
-rw-r--r--core/multimedia/opieplayer/libflash/sprite.cc91
-rw-r--r--core/multimedia/opieplayer/libflash/sprite.h38
-rw-r--r--core/multimedia/opieplayer/libflash/sqrt.cc4099
-rw-r--r--core/multimedia/opieplayer/libflash/swf.h229
-rw-r--r--core/multimedia/opieplayer/libflash/text.cc246
-rw-r--r--core/multimedia/opieplayer/libflash/text.h77
-rw-r--r--core/multimedia/opieplayer/libmad/.cvsignore2
-rw-r--r--core/multimedia/opieplayer/libmad/D.dat607
-rw-r--r--core/multimedia/opieplayer/libmad/Makefile.in226
-rw-r--r--core/multimedia/opieplayer/libmad/bit.c220
-rw-r--r--core/multimedia/opieplayer/libmad/bit.h47
-rw-r--r--core/multimedia/opieplayer/libmad/decoder.c554
-rw-r--r--core/multimedia/opieplayer/libmad/decoder.h87
-rwxr-xr-xcore/multimedia/opieplayer/libmad/fix_headers_problem25
-rw-r--r--core/multimedia/opieplayer/libmad/fixed.c37
-rw-r--r--core/multimedia/opieplayer/libmad/fixed.h413
-rw-r--r--core/multimedia/opieplayer/libmad/frame.c499
-rw-r--r--core/multimedia/opieplayer/libmad/frame.h115
-rw-r--r--core/multimedia/opieplayer/libmad/huffman.c3087
-rw-r--r--core/multimedia/opieplayer/libmad/huffman.h66
-rw-r--r--core/multimedia/opieplayer/libmad/imdct_l_arm.S1000
-rw-r--r--core/multimedia/opieplayer/libmad/imdct_s.dat62
-rw-r--r--core/multimedia/opieplayer/libmad/layer12.c496
-rw-r--r--core/multimedia/opieplayer/libmad/layer12.h31
-rw-r--r--core/multimedia/opieplayer/libmad/layer3.c2492
-rw-r--r--core/multimedia/opieplayer/libmad/layer3.h30
-rw-r--r--core/multimedia/opieplayer/libmad/libmad.pro12
-rw-r--r--core/multimedia/opieplayer/libmad/libmad_global.h45
-rw-r--r--core/multimedia/opieplayer/libmad/libmad_version.h47
-rw-r--r--core/multimedia/opieplayer/libmad/libmadplugin.cpp578
-rw-r--r--core/multimedia/opieplayer/libmad/libmadplugin.h101
-rw-r--r--core/multimedia/opieplayer/libmad/libmadpluginimpl.cpp70
-rw-r--r--core/multimedia/opieplayer/libmad/libmadpluginimpl.h53
-rw-r--r--core/multimedia/opieplayer/libmad/mad.h830
-rw-r--r--core/multimedia/opieplayer/libmad/qc_table.dat77
-rw-r--r--core/multimedia/opieplayer/libmad/qpe-libmadplugin.control9
-rw-r--r--core/multimedia/opieplayer/libmad/rq_table.dat8747
-rw-r--r--core/multimedia/opieplayer/libmad/sf_table.dat100
-rw-r--r--core/multimedia/opieplayer/libmad/stream.c123
-rw-r--r--core/multimedia/opieplayer/libmad/stream.h102
-rw-r--r--core/multimedia/opieplayer/libmad/synth.c855
-rw-r--r--core/multimedia/opieplayer/libmad/synth.h50
-rw-r--r--core/multimedia/opieplayer/libmad/timer.c480
-rw-r--r--core/multimedia/opieplayer/libmad/timer.h100
-rw-r--r--core/multimedia/opieplayer/libmad/version.c91
-rw-r--r--core/multimedia/opieplayer/libmpeg3/.cvsignore5
-rw-r--r--core/multimedia/opieplayer/libmpeg3/COPYING340
-rw-r--r--core/multimedia/opieplayer/libmpeg3/Makefile.in774
-rw-r--r--core/multimedia/opieplayer/libmpeg3/README35
-rw-r--r--core/multimedia/opieplayer/libmpeg3/VERSION1
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/Makefile35
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/ac3.c691
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/ac3.h308
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/bit_allocation.c586
-rwxr-xr-xcore/multimedia/opieplayer/libmpeg3/audio/c_flags1
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/dct.c1135
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/exponents.c141
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/fptables.h1556
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/header.c163
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/huffman.h355
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/layer1.c6
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/layer2.c418
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/layer3.c1254
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/mantissa.c387
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.c536
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.h144
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/mpeg3real.h232
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/pcm.c51
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/synthesizers.c174
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/tables.c554
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/tables.h88
-rw-r--r--core/multimedia/opieplayer/libmpeg3/audio/uncouple.c135
-rw-r--r--core/multimedia/opieplayer/libmpeg3/bitstream.c167
-rw-r--r--core/multimedia/opieplayer/libmpeg3/bitstream.h207
-rwxr-xr-xcore/multimedia/opieplayer/libmpeg3/c_flags4
-rwxr-xr-xcore/multimedia/opieplayer/libmpeg3/configure102
-rw-r--r--core/multimedia/opieplayer/libmpeg3/docs/index.html306
-rw-r--r--core/multimedia/opieplayer/libmpeg3/dump.c79
-rw-r--r--core/multimedia/opieplayer/libmpeg3/libmpeg3.c672
-rw-r--r--core/multimedia/opieplayer/libmpeg3/libmpeg3.h175
-rw-r--r--core/multimedia/opieplayer/libmpeg3/libmpeg3.pro42
-rw-r--r--core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.cpp105
-rw-r--r--core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.h113
-rw-r--r--core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.cpp70
-rw-r--r--core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.h53
-rwxr-xr-xcore/multimedia/opieplayer/libmpeg3/make_package10
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3atrack.c36
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3atrack.h36
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3cat.c225
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3css.c32
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3css.h29
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.c19
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.h29
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3demux.c1849
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3demux.h118
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3io.c127
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3io.h74
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3private.h62
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3private.inc110
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3protos.h278
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3title.c63
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3title.h47
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3toc.c81
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.c33
-rw-r--r--core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.h39
-rw-r--r--core/multimedia/opieplayer/libmpeg3/ronin_narrow.toc26
-rw-r--r--core/multimedia/opieplayer/libmpeg3/ronin_wide.toc47
-rw-r--r--core/multimedia/opieplayer/libmpeg3/timecode.h31
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/Makefile32
-rwxr-xr-xcore/multimedia/opieplayer/libmpeg3/video/c_flags1
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/getpicture.c767
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/headers.c492
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/idct.c160
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/idct.h24
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/layerdata.h35
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/macroblocks.c338
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/mmxidct.S675
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/mmxtest.c35
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/motion.c230
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/mpeg3video.c597
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/mpeg3video.h180
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/mpeg3videoprotos.h26
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/output.c993
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/reconmmx.s301
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/reconstruct.c1290
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/seek.c233
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/slice.c702
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/slice.h194
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/vlc.c421
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/vlc.h164
-rw-r--r--core/multimedia/opieplayer/libmpeg3/video/worksheet.c30
-rw-r--r--core/multimedia/opieplayer/loopcontrol.cpp464
-rw-r--r--core/multimedia/opieplayer/loopcontrol.h88
-rw-r--r--core/multimedia/opieplayer/loopcontrol_threaded.cpp626
-rw-r--r--core/multimedia/opieplayer/loopcontrol_threaded.h89
-rw-r--r--core/multimedia/opieplayer/main.cpp57
-rw-r--r--core/multimedia/opieplayer/mediaplayer.cpp182
-rw-r--r--core/multimedia/opieplayer/mediaplayer.h59
-rw-r--r--core/multimedia/opieplayer/mediaplayerplugininterface.h113
-rw-r--r--core/multimedia/opieplayer/mediaplayerstate.cpp185
-rw-r--r--core/multimedia/opieplayer/mediaplayerstate.h117
-rw-r--r--core/multimedia/opieplayer/mpegplayer.pro21
-rw-r--r--core/multimedia/opieplayer/playlistselection.cpp179
-rw-r--r--core/multimedia/opieplayer/playlistselection.h62
-rw-r--r--core/multimedia/opieplayer/playlistwidget.cpp448
-rw-r--r--core/multimedia/opieplayer/playlistwidget.h68
-rw-r--r--core/multimedia/opieplayer/qpe-mpegplayer.control9
-rw-r--r--core/multimedia/opieplayer/videowidget.cpp423
-rw-r--r--core/multimedia/opieplayer/videowidget.h88
-rw-r--r--core/multimedia/opieplayer/wavplugin/.cvsignore2
-rw-r--r--core/multimedia/opieplayer/wavplugin/Makefile.in112
-rw-r--r--core/multimedia/opieplayer/wavplugin/qpe-wavplugin.control9
-rw-r--r--core/multimedia/opieplayer/wavplugin/wavplugin.cpp334
-rw-r--r--core/multimedia/opieplayer/wavplugin/wavplugin.h97
-rw-r--r--core/multimedia/opieplayer/wavplugin/wavplugin.pro10
-rw-r--r--core/multimedia/opieplayer/wavplugin/wavpluginimpl.cpp70
-rw-r--r--core/multimedia/opieplayer/wavplugin/wavpluginimpl.h53
-rw-r--r--core/opie-login/.cvsignore3
-rw-r--r--core/opie-login/README78
-rw-r--r--core/opie-login/qdm_config.h30
-rw-r--r--core/opie-login/qdmdialog.ui856
-rw-r--r--core/opie-login/qdmdialogimpl.cpp535
-rw-r--r--core/opie-login/qdmdialogimpl.h90
-rw-r--r--core/pim/addressbook/.cvsignore16
-rw-r--r--core/pim/addressbook/Makefile.in244
-rw-r--r--core/pim/addressbook/abeditor.cpp619
-rw-r--r--core/pim/addressbook/abeditor.h79
-rw-r--r--core/pim/addressbook/ablabel.cpp53
-rw-r--r--core/pim/addressbook/ablabel.h50
-rw-r--r--core/pim/addressbook/abtable.cpp1091
-rw-r--r--core/pim/addressbook/abtable.h140
-rw-r--r--core/pim/addressbook/addressbook.cpp829
-rw-r--r--core/pim/addressbook/addressbook.cw26
-rw-r--r--core/pim/addressbook/addressbook.h99
-rw-r--r--core/pim/addressbook/addressbook.pro22
-rw-r--r--core/pim/addressbook/addresspicker.cpp52
-rw-r--r--core/pim/addressbook/addresspicker.h39
-rw-r--r--core/pim/addressbook/addresssettings.cpp136
-rw-r--r--core/pim/addressbook/addresssettings.h47
-rw-r--r--core/pim/addressbook/addresssettingsbase.ui170
-rw-r--r--core/pim/addressbook/main.cpp41
-rw-r--r--core/pim/addressbook/qpe-addressbook.control9
-rw-r--r--core/pim/datebook/.cvsignore12
-rw-r--r--core/pim/datebook/Makefile.in385
-rw-r--r--core/pim/datebook/datebook.cpp854
-rw-r--r--core/pim/datebook/datebook.h111
-rw-r--r--core/pim/datebook/datebook.pro36
-rw-r--r--core/pim/datebook/datebookday.cpp553
-rw-r--r--core/pim/datebook/datebookday.h138
-rw-r--r--core/pim/datebook/datebookdayheader.ui424
-rw-r--r--core/pim/datebook/datebookdayheaderimpl.cpp181
-rw-r--r--core/pim/datebook/datebookdayheaderimpl.h57
-rw-r--r--core/pim/datebook/datebooksettings.cpp135
-rw-r--r--core/pim/datebook/datebooksettings.h48
-rw-r--r--core/pim/datebook/datebooksettingsbase.ui232
-rw-r--r--core/pim/datebook/datebookweek.cpp687
-rw-r--r--core/pim/datebook/datebookweek.h152
-rw-r--r--core/pim/datebook/datebookweekheader.ui167
-rw-r--r--core/pim/datebook/datebookweekheaderimpl.cpp126
-rw-r--r--core/pim/datebook/datebookweekheaderimpl.h62
-rw-r--r--core/pim/datebook/dateentry.ui1095
-rw-r--r--core/pim/datebook/dateentryimpl.cpp474
-rw-r--r--core/pim/datebook/dateentryimpl.h71
-rw-r--r--core/pim/datebook/main.cpp38
-rw-r--r--core/pim/datebook/qpe-datebook.control9
-rw-r--r--core/pim/datebook/repeatentry.cpp595
-rw-r--r--core/pim/datebook/repeatentry.h98
-rw-r--r--core/pim/datebook/repeatentrybase.ui713
-rw-r--r--core/pim/todo/.cvsignore4
-rw-r--r--core/pim/todo/Makefile.in201
-rw-r--r--core/pim/todo/main.cpp36
-rw-r--r--core/pim/todo/mainwindow.cpp466
-rw-r--r--core/pim/todo/mainwindow.h73
-rw-r--r--core/pim/todo/qpe-todo.control9
-rw-r--r--core/pim/todo/todo.pro19
-rw-r--r--core/pim/todo/todoentry.ui266
-rw-r--r--core/pim/todo/todoentryimpl.cpp142
-rw-r--r--core/pim/todo/todoentryimpl.h61
-rw-r--r--core/pim/todo/todotable.cpp859
-rw-r--r--core/pim/todo/todotable.h207
-rw-r--r--core/settings/citytime/.cvsignore5
-rw-r--r--core/settings/citytime/Makefile.in184
-rw-r--r--core/settings/citytime/citytime.cpp272
-rw-r--r--core/settings/citytime/citytime.h66
-rw-r--r--core/settings/citytime/citytime.pro13
-rw-r--r--core/settings/citytime/citytimebase.ui1199
-rwxr-xr-xcore/settings/citytime/findvalidzones38
-rw-r--r--core/settings/citytime/light.pngbin0 -> 223 bytes
-rw-r--r--core/settings/citytime/mag.pngbin0 -> 193 bytes
-rw-r--r--core/settings/citytime/main.cpp30
-rw-r--r--core/settings/citytime/qpe-citytime.control9
-rw-r--r--core/settings/citytime/stylusnormalizer.cpp98
-rw-r--r--core/settings/citytime/stylusnormalizer.h70
-rw-r--r--core/settings/citytime/sun.c323
-rw-r--r--core/settings/citytime/sun.h57
-rw-r--r--core/settings/citytime/zonemap.cpp670
-rw-r--r--core/settings/citytime/zonemap.cw21
-rw-r--r--core/settings/citytime/zonemap.h157
-rw-r--r--core/settings/light-and-power/.cvsignore4
-rw-r--r--core/settings/light-and-power/Makefile.in135
-rw-r--r--core/settings/light-and-power/light-and-power.pro12
-rw-r--r--core/settings/light-and-power/light-off.xpm23
-rw-r--r--core/settings/light-and-power/light-on.xpm24
-rw-r--r--core/settings/light-and-power/light.cpp133
-rw-r--r--core/settings/light-and-power/lightsettingsbase.ui471
-rw-r--r--core/settings/light-and-power/main.cpp38
-rw-r--r--core/settings/light-and-power/qpe-light-and-power.control9
-rw-r--r--core/settings/light-and-power/settings.h50
-rw-r--r--core/settings/security/.cvsignore5
-rw-r--r--core/settings/security/Makefile.in135
-rw-r--r--core/settings/security/main.cpp38
-rw-r--r--core/settings/security/qpe-security.control9
-rw-r--r--core/settings/security/security.cpp234
-rw-r--r--core/settings/security/security.h64
-rw-r--r--core/settings/security/security.pro12
-rw-r--r--core/settings/security/securitybase.ui200
453 files changed, 112379 insertions, 0 deletions
diff --git a/core/.cvsignore b/core/.cvsignore
new file mode 100644
index 0000000..e3d8c4b
--- a/dev/null
+++ b/core/.cvsignore
@@ -0,0 +1,13 @@
+moc_*
+*.moc
+Makefile
+appearancesettingsbase.h
+soundsettingsbase.h
+lightsettingsbase.h
+languagesettingsbase.cpp
+rotationsettingsbase.cpp
+appearancesettingsbase.cpp
+lightsettingsbase.cpp
+languagesettingsbase.h
+rotationsettingsbase.h
+soundsettingsbase.cpp
diff --git a/core/applets/batteryapplet/.cvsignore b/core/applets/batteryapplet/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/core/applets/batteryapplet/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile
diff --git a/core/applets/batteryapplet/Makefile.in b/core/applets/batteryapplet/Makefile.in
new file mode 100644
index 0000000..0493fd6
--- a/dev/null
+++ b/core/applets/batteryapplet/Makefile.in
@@ -0,0 +1,122 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../../plugins/applets/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = batteryapplet
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = battery.h \
+ batterystatus.h \
+ batteryappletimpl.h
+SOURCES = battery.cpp \
+ batterystatus.cpp \
+ batteryappletimpl.cpp
+OBJECTS = battery.o \
+ batterystatus.o \
+ batteryappletimpl.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_battery.cpp
+OBJMOC = moc_battery.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
+
+$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK_LIB)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake batteryapplet.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+battery.o: battery.cpp \
+ battery.h \
+ batterystatus.h
+
+batterystatus.o: batterystatus.cpp \
+ batterystatus.h
+
+batteryappletimpl.o: batteryappletimpl.cpp \
+ battery.h \
+ batteryappletimpl.h
+
+moc_battery.o: moc_battery.cpp \
+ battery.h
+
+moc_battery.cpp: battery.h
+ $(MOC) battery.h -o moc_battery.cpp
+
+
diff --git a/core/applets/batteryapplet/battery.cpp b/core/applets/batteryapplet/battery.cpp
new file mode 100644
index 0000000..3d254fc
--- a/dev/null
+++ b/core/applets/batteryapplet/battery.cpp
@@ -0,0 +1,152 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "battery.h"
+#include "batterystatus.h"
+
+#include <qpe/power.h>
+
+#include <qpainter.h>
+#include <qtimer.h>
+
+
+BatteryMeter::BatteryMeter( QWidget *parent = 0 )
+ : QWidget( parent ), charging(false)
+{
+ ps = new PowerStatus;
+ startTimer( 10000 );
+ setFixedHeight(12);
+ chargeTimer = new QTimer( this );
+ connect( chargeTimer, SIGNAL(timeout()), this, SLOT(chargeTimeout()) );
+ timerEvent(0);
+}
+
+BatteryMeter::~BatteryMeter()
+{
+ delete ps;
+}
+
+QSize BatteryMeter::sizeHint() const
+{
+ return QSize(10,12);
+}
+
+void BatteryMeter::mouseReleaseEvent( QMouseEvent *)
+{
+ if ( batteryView && batteryView->isVisible() ) {
+ delete (QWidget *) batteryView;
+ } else {
+ if ( !batteryView )
+ batteryView = new BatteryStatus( ps );
+ batteryView->showMaximized();
+ batteryView->raise();
+ batteryView->show();
+ }
+}
+
+void BatteryMeter::timerEvent( QTimerEvent * )
+{
+ PowerStatus prev = *ps;
+
+ *ps = PowerStatusManager::readStatus();
+
+ if ( prev != *ps ) {
+ percent = ps->batteryPercentRemaining();
+ if ( !charging && ps->batteryStatus() == PowerStatus::Charging && percent < 0 ) {
+ percent = 0;
+ charging = true;
+ chargeTimer->start( 500 );
+ } else if ( charging && ps->batteryStatus() != PowerStatus::Charging ) {
+ charging = false;
+ chargeTimer->stop();
+ if ( batteryView )
+ batteryView->updatePercent( percent );
+ }
+ repaint(FALSE);
+ if ( batteryView )
+ batteryView->repaint();
+ }
+}
+
+void BatteryMeter::chargeTimeout()
+{
+ percent += 20;
+ if ( percent > 100 )
+ percent = 0;
+
+ repaint(FALSE);
+ if ( batteryView )
+ batteryView->updatePercent( percent );
+}
+
+void BatteryMeter::paintEvent( QPaintEvent* )
+{
+ QPainter p(this);
+
+ QColor c;
+ QColor darkc;
+ QColor lightc;
+ if ( ps->acStatus() == PowerStatus::Offline ) {
+ c = blue.light(120);
+ darkc = c.dark(120);
+ lightc = c.light(140);
+ } else if ( ps->acStatus() == PowerStatus::Online ) {
+ c = green.dark(130);
+ darkc = c.dark(120);
+ lightc = c.light(180);
+ } else {
+ c = red;
+ darkc = c.dark(120);
+ lightc = c.light(160);
+ }
+
+ int w = 6;
+ int h = height()-3;
+ int pix = (percent * h) / 100;
+ int y2 = height() - 2;
+ int y = y2 - pix;
+ int x1 = (width() - w) / 2;
+
+ p.setPen(QColor(80,80,80));
+ p.drawLine(x1+w/4,0,x1+w/4+w/2,0);
+ p.drawRect(x1,1,w,height()-1);
+ p.setBrush(c);
+
+ int extra = ((percent * h) % 100)/(100/4);
+
+#define Y(i) ((i<=extra)?y-1:y)
+#define DRAWUPPER(i) if ( Y(i) >= 2 ) p.drawLine(i+x1,2,i+x1,Y(i));
+ p.setPen( gray );
+ DRAWUPPER(1);
+ DRAWUPPER(3);
+ p.setPen( gray.light(130) );
+ DRAWUPPER(2);
+ p.setPen( gray.dark(120) );
+ DRAWUPPER(4);
+
+#define DRAW(i) { if ( Y(i) < y2 ) p.drawLine(i+x1,Y(i)+1,i+x1,y2); }
+ p.setPen( c );
+ DRAW(1);
+ DRAW(3);
+ p.setPen( lightc );
+ DRAW(2);
+ p.setPen(darkc);
+ DRAW(4);
+}
+
diff --git a/core/applets/batteryapplet/battery.h b/core/applets/batteryapplet/battery.h
new file mode 100644
index 0000000..d4807b0
--- a/dev/null
+++ b/core/applets/batteryapplet/battery.h
@@ -0,0 +1,55 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef BATTERY_H
+#define BATTERY_H
+
+#include <qwidget.h>
+#include <qguardedptr.h>
+
+class PowerStatus;
+class BatteryStatus;
+class QTimer;
+
+class BatteryMeter : public QWidget
+{
+ Q_OBJECT
+public:
+ BatteryMeter( QWidget *parent = 0 );
+ ~BatteryMeter();
+
+ QSize sizeHint() const;
+
+protected:
+ void timerEvent( QTimerEvent * );
+ void paintEvent( QPaintEvent* );
+ void mouseReleaseEvent( QMouseEvent * );
+
+protected slots:
+ void chargeTimeout();
+
+protected:
+ QGuardedPtr<BatteryStatus> batteryView;
+ PowerStatus *ps;
+ QTimer *chargeTimer;
+ int percent;
+ bool charging;
+};
+
+#endif
diff --git a/core/applets/batteryapplet/batteryapplet.pro b/core/applets/batteryapplet/batteryapplet.pro
new file mode 100644
index 0000000..fa0fca8
--- a/dev/null
+++ b/core/applets/batteryapplet/batteryapplet.pro
@@ -0,0 +1,12 @@
+TEMPLATE = lib
+CONFIG += qt warn_on release
+HEADERS = battery.h batterystatus.h batteryappletimpl.h
+SOURCES = battery.cpp batterystatus.cpp batteryappletimpl.cpp
+TARGET = batteryapplet
+DESTDIR = ../../plugins/applets
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += ../$(QPEDIR)/include ..
+LIBS += -lqpe
+VERSION = 1.0.0
+
+TRANSLATIONS += ../../i18n/de/libbatteryapplet.ts
diff --git a/core/applets/batteryapplet/batteryappletimpl.cpp b/core/applets/batteryapplet/batteryappletimpl.cpp
new file mode 100644
index 0000000..3f3079a
--- a/dev/null
+++ b/core/applets/batteryapplet/batteryappletimpl.cpp
@@ -0,0 +1,63 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "battery.h"
+#include "batteryappletimpl.h"
+
+
+BatteryAppletImpl::BatteryAppletImpl()
+ : battery(0), ref(0)
+{
+}
+
+BatteryAppletImpl::~BatteryAppletImpl()
+{
+ delete battery;
+}
+
+QWidget *BatteryAppletImpl::applet( QWidget *parent )
+{
+ if ( !battery )
+ battery = new BatteryMeter( parent );
+ return battery;
+}
+
+int BatteryAppletImpl::position() const
+{
+ return 8;
+}
+
+QRESULT BatteryAppletImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
+{
+ *iface = 0;
+ if ( uuid == IID_QUnknown )
+ *iface = this;
+ else if ( uuid == IID_TaskbarApplet )
+ *iface = this;
+
+ if ( *iface )
+ (*iface)->addRef();
+ return QS_OK;
+}
+
+Q_EXPORT_INTERFACE()
+{
+ Q_CREATE_INSTANCE( BatteryAppletImpl )
+}
+
diff --git a/core/applets/batteryapplet/batteryappletimpl.h b/core/applets/batteryapplet/batteryappletimpl.h
new file mode 100644
index 0000000..94f49db
--- a/dev/null
+++ b/core/applets/batteryapplet/batteryappletimpl.h
@@ -0,0 +1,44 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef BATTERYAPPLETIMPL_H
+#define BATTERYAPPLETIMPL_H
+
+#include <qpe/taskbarappletinterface.h>
+
+class BatteryMeter;
+
+class BatteryAppletImpl : public TaskbarAppletInterface
+{
+public:
+ BatteryAppletImpl();
+ virtual ~BatteryAppletImpl();
+
+ QRESULT queryInterface( const QUuid&, QUnknownInterface** );
+ Q_REFCOUNT
+
+ virtual QWidget *applet( QWidget *parent );
+ virtual int position() const;
+
+private:
+ BatteryMeter *battery;
+ ulong ref;
+};
+
+#endif
diff --git a/core/applets/batteryapplet/batterystatus.cpp b/core/applets/batteryapplet/batterystatus.cpp
new file mode 100644
index 0000000..d18b6c9
--- a/dev/null
+++ b/core/applets/batteryapplet/batterystatus.cpp
@@ -0,0 +1,140 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "batterystatus.h"
+
+#include <qpe/power.h>
+
+#include <qpainter.h>
+#include <qpushbutton.h>
+#include <qdrawutil.h>
+
+
+BatteryStatus::BatteryStatus( const PowerStatus *p, QWidget *parent )
+ : QWidget( parent, 0, WDestructiveClose), ps(p)
+{
+ setCaption( tr("Battery Status") );
+ QPushButton *pb = new QPushButton( tr("Close"), this );
+ pb->move( 70, 220 );
+ pb->show();
+ connect( pb, SIGNAL( clicked() ), this, SLOT( close() ) );
+ percent = ps->batteryPercentRemaining();
+ show();
+}
+
+BatteryStatus::~BatteryStatus()
+{
+}
+
+void BatteryStatus::updatePercent( int pc )
+{
+ percent = pc;
+ repaint(FALSE);
+}
+
+void BatteryStatus::drawSegment( QPainter *p, const QRect &r, const QColor &topgrad, const QColor &botgrad, const QColor &highlight, int hightlight_height )
+{
+ int h1, h2, s1, s2, v1, v2, ng = r.height(), hy = ng*30/100, hh = hightlight_height;
+ topgrad.hsv( &h1, &s1, &v1 );
+ botgrad.hsv( &h2, &s2, &v2 );
+ for ( int j = 0; j < hy-2; j++ ) {
+ p->setPen( QColor( h1 + ((h2-h1)*j)/(ng-1), s1 + ((s2-s1)*j)/(ng-1),
+ v1 + ((v2-v1)*j)/(ng-1), QColor::Hsv ) );
+ p->drawLine( r.x(), r.top()+hy-2-j, r.x()+r.width(), r.top()+hy-2-j );
+ }
+ for ( int j = 0; j < hh; j++ ) {
+ p->setPen( highlight );
+ p->drawLine( r.x(), r.top()+hy-2+j, r.x()+r.width(), r.top()+hy-2+j );
+ }
+ for ( int j = 0; j < ng-hy-hh; j++ ) {
+ p->setPen( QColor( h1 + ((h2-h1)*j)/(ng-1), s1 + ((s2-s1)*j)/(ng-1),
+ v1 + ((v2-v1)*j)/(ng-1), QColor::Hsv ) );
+ p->drawLine( r.x(), r.top()+hy+hh-2+j, r.x()+r.width(), r.top()+hy+hh-2+j );
+ }
+}
+
+void BatteryStatus::paintEvent( QPaintEvent * )
+{
+ QPainter p(this);
+ QString text;
+ if ( ps->batteryStatus() == PowerStatus::Charging ) {
+ text = tr("Charging");
+ } else if ( ps->batteryPercentAccurate() ) {
+ text.sprintf( tr("Percentage battery remaining") + ": %i%%", percent );
+ } else {
+ text = tr("Battery status: ");
+ switch ( ps->batteryStatus() ) {
+ case PowerStatus::High:
+ text += tr("Good");
+ break;
+ case PowerStatus::Low:
+ text += tr("Low");
+ break;
+ case PowerStatus::VeryLow:
+ text += tr("Very Low");
+ break;
+ case PowerStatus::Critical:
+ text += tr("Critical");
+ break;
+ default: // NotPresent, etc.
+ text += tr("Unknown");
+ }
+ }
+ p.drawText( 10, 120, text );
+ if ( ps->acStatus() == PowerStatus::Backup )
+ p.drawText( 10, 150, tr("On backup power") );
+ else if ( ps->acStatus() == PowerStatus::Online )
+ p.drawText( 10, 150, tr("Power on-line") );
+ else if ( ps->acStatus() == PowerStatus::Offline )
+ p.drawText( 10, 150, tr("External power disconnected") );
+
+ if ( ps->batteryTimeRemaining() >= 0 ) {
+ text.sprintf( tr("Battery time remaining") + ": %im %02is",
+ ps->batteryTimeRemaining() / 60, ps->batteryTimeRemaining() % 60 );
+ p.drawText( 10, 180, text );
+ }
+
+ QColor c;
+ QColor darkc;
+ QColor lightc;
+ if ( ps->acStatus() == PowerStatus::Offline ) {
+ c = blue.light(120);
+ darkc = c.dark(280);
+ lightc = c.light(145);
+ } else if ( ps->acStatus() == PowerStatus::Online ) {
+ c = green.dark(130);
+ darkc = c.dark(200);
+ lightc = c.light(220);
+ } else {
+ c = red;
+ darkc = c.dark(280);
+ lightc = c.light(140);
+ }
+ if ( percent < 0 )
+ return;
+
+ int percent2 = percent * 2;
+ p.setPen( black );
+ qDrawShadePanel( &p, 9, 30, 204, 39, colorGroup(), TRUE, 1, NULL);
+ qDrawShadePanel( &p, 212, 37, 12, 24, colorGroup(), TRUE, 1, NULL);
+ drawSegment( &p, QRect( 10, 30, percent2, 40 ), lightc, darkc, lightc.light(115), 6 );
+ drawSegment( &p, QRect( 11 + percent2, 30, 200 - percent2, 40 ), white.light(80), black, white.light(90), 6 );
+ drawSegment( &p, QRect( 212, 37, 10, 25 ), white.light(80), black, white.light(90), 2 );
+}
+
diff --git a/core/applets/batteryapplet/batterystatus.h b/core/applets/batteryapplet/batterystatus.h
new file mode 100644
index 0000000..85b2c4d
--- a/dev/null
+++ b/core/applets/batteryapplet/batterystatus.h
@@ -0,0 +1,45 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef BATTERY_STATUS_H
+#define BATTERY_STATUS_H
+
+#include <qwidget.h>
+
+class PowerStatus;
+
+class BatteryStatus : public QWidget
+{
+public:
+ BatteryStatus( const PowerStatus *s, QWidget *parent=0 );
+ ~BatteryStatus();
+
+ void updatePercent( int );
+
+protected:
+ void drawSegment( QPainter *p, const QRect &r, const QColor &topgrad, const QColor &botgrad, const QColor &highlight, int hightlight_height );
+ void paintEvent( QPaintEvent *pe );
+
+private:
+ const PowerStatus *ps;
+ int percent;
+};
+
+#endif
+
diff --git a/core/applets/batteryapplet/qpe-batteryapplet.control b/core/applets/batteryapplet/qpe-batteryapplet.control
new file mode 100644
index 0000000..83d0b8b
--- a/dev/null
+++ b/core/applets/batteryapplet/qpe-batteryapplet.control
@@ -0,0 +1,9 @@
+Files: plugins/applets/libbatteryapplet.so*
+Priority: optional
+Section: qpe/taskbar
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Battery Monitor applet
+ Battery Monitor applet for the Qtopia environment taskbar.
diff --git a/core/applets/batteryapplet/qpe-batteryapplet.postinst b/core/applets/batteryapplet/qpe-batteryapplet.postinst
new file mode 100755
index 0000000..ba76ffa
--- a/dev/null
+++ b/core/applets/batteryapplet/qpe-batteryapplet.postinst
@@ -0,0 +1,2 @@
+#!/bin/sh
+/opt/QtPalmtop/bin/qcop QPE/TaskBar "reloadApplets()"
diff --git a/core/applets/batteryapplet/qpe-batteryapplet.postrm b/core/applets/batteryapplet/qpe-batteryapplet.postrm
new file mode 100755
index 0000000..ba76ffa
--- a/dev/null
+++ b/core/applets/batteryapplet/qpe-batteryapplet.postrm
@@ -0,0 +1,2 @@
+#!/bin/sh
+/opt/QtPalmtop/bin/qcop QPE/TaskBar "reloadApplets()"
diff --git a/core/applets/clipboardapplet/Makefile.in b/core/applets/clipboardapplet/Makefile.in
new file mode 100644
index 0000000..2ddeb42
--- a/dev/null
+++ b/core/applets/clipboardapplet/Makefile.in
@@ -0,0 +1,115 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../../plugins/applets/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = clipboardapplet
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = clipboard.h \
+ clipboardappletimpl.h
+SOURCES = clipboard.cpp \
+ clipboardappletimpl.cpp
+OBJECTS = clipboard.o \
+ clipboardappletimpl.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_clipboard.cpp
+OBJMOC = moc_clipboard.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
+
+$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK_LIB)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake clipboardapplet.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+clipboard.o: clipboard.cpp \
+ clipboard.h
+
+clipboardappletimpl.o: clipboardappletimpl.cpp \
+ clipboard.h \
+ clipboardappletimpl.h
+
+moc_clipboard.o: moc_clipboard.cpp \
+ clipboard.h
+
+moc_clipboard.cpp: clipboard.h
+ $(MOC) clipboard.h -o moc_clipboard.cpp
+
+
diff --git a/core/applets/clipboardapplet/clipboard.cpp b/core/applets/clipboardapplet/clipboard.cpp
new file mode 100644
index 0000000..57beffc
--- a/dev/null
+++ b/core/applets/clipboardapplet/clipboard.cpp
@@ -0,0 +1,80 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "clipboard.h"
+
+#include <qpe/resource.h>
+
+#include <qpainter.h>
+#include <qpopupmenu.h>
+#include <qwindowsystem_qws.h>
+
+
+//===========================================================================
+
+ClipboardApplet::ClipboardApplet( QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+ setFixedWidth( 14 );
+ clipboardPixmap = Resource::loadPixmap( "clipboard" );
+ menu = 0;
+}
+
+ClipboardApplet::~ClipboardApplet()
+{
+}
+
+void ClipboardApplet::mousePressEvent( QMouseEvent *)
+{
+ if ( !menu ) {
+ menu = new QPopupMenu(this);
+ menu->insertItem(tr("Cut"));
+ menu->insertItem(tr("Copy"));
+ menu->insertItem(tr("Paste"));
+ connect(menu, SIGNAL(selected(int)), this, SLOT(action(int)));
+ }
+ menu->popup(mapToGlobal(QPoint(0,0)));
+}
+
+void ClipboardApplet::action(int i)
+{
+ ushort unicode=0;
+ int scan=0;
+
+ if ( i == 0 )
+ { unicode='X'-'@'; scan=Key_X; } // Cut
+ else if ( i == 1 )
+ { unicode='C'-'@'; scan=Key_C; } // Copy
+ else if ( i == 2 )
+ { unicode='V'-'@'; scan=Key_V; } // Paste
+
+ if ( scan ) {
+ qwsServer->processKeyEvent( unicode, scan, ControlButton, TRUE, FALSE );
+ qwsServer->processKeyEvent( unicode, scan, ControlButton, FALSE, FALSE );
+ }
+}
+
+void ClipboardApplet::paintEvent( QPaintEvent* )
+{
+ QPainter p(this);
+ p.drawPixmap( 0, 1, clipboardPixmap );
+}
+
+
diff --git a/core/applets/clipboardapplet/clipboard.h b/core/applets/clipboardapplet/clipboard.h
new file mode 100644
index 0000000..9dd59ed
--- a/dev/null
+++ b/core/applets/clipboardapplet/clipboard.h
@@ -0,0 +1,47 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef __CLIPBOARD_APPLET_H__
+#define __CLIPBOARD_APPLET_H__
+
+#include <qwidget.h>
+#include <qpixmap.h>
+
+class ClipboardApplet : public QWidget
+{
+ Q_OBJECT
+public:
+ ClipboardApplet( QWidget *parent = 0, const char *name=0 );
+ ~ClipboardApplet();
+
+protected:
+ void mousePressEvent( QMouseEvent *);
+ void paintEvent( QPaintEvent* );
+
+private slots:
+ void action(int);
+
+private:
+ QPopupMenu* menu;
+ QPixmap clipboardPixmap;
+};
+
+
+#endif // __CLIPBOARD_APPLET_H__
+
diff --git a/core/applets/clipboardapplet/clipboardapplet.pro b/core/applets/clipboardapplet/clipboardapplet.pro
new file mode 100644
index 0000000..b0624ef
--- a/dev/null
+++ b/core/applets/clipboardapplet/clipboardapplet.pro
@@ -0,0 +1,10 @@
+TEMPLATE = lib
+CONFIG += qt warn_on release
+HEADERS = clipboard.h clipboardappletimpl.h
+SOURCES = clipboard.cpp clipboardappletimpl.cpp
+TARGET = clipboardapplet
+DESTDIR = ../../plugins/applets
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += ../$(QPEDIR)/include
+LIBS += -lqpe
+VERSION = 1.0.0
diff --git a/core/applets/clipboardapplet/clipboardappletimpl.cpp b/core/applets/clipboardapplet/clipboardappletimpl.cpp
new file mode 100644
index 0000000..8080690
--- a/dev/null
+++ b/core/applets/clipboardapplet/clipboardappletimpl.cpp
@@ -0,0 +1,64 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "clipboard.h"
+#include "clipboardappletimpl.h"
+
+
+ClipboardAppletImpl::ClipboardAppletImpl()
+ : clipboard(0), ref(0)
+{
+}
+
+ClipboardAppletImpl::~ClipboardAppletImpl()
+{
+ delete clipboard;
+}
+
+QWidget *ClipboardAppletImpl::applet( QWidget *parent )
+{
+ if ( !clipboard )
+ clipboard = new ClipboardApplet( parent );
+ return clipboard;
+}
+
+int ClipboardAppletImpl::position() const
+{
+ return 6;
+}
+
+QRESULT ClipboardAppletImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
+{
+ *iface = 0;
+ if ( uuid == IID_QUnknown )
+ *iface = this;
+ else if ( uuid == IID_TaskbarApplet )
+ *iface = this;
+
+ if ( *iface )
+ (*iface)->addRef();
+ return QS_OK;
+}
+
+Q_EXPORT_INTERFACE()
+{
+ Q_CREATE_INSTANCE( ClipboardAppletImpl )
+}
+
+
diff --git a/core/applets/clipboardapplet/clipboardappletimpl.h b/core/applets/clipboardapplet/clipboardappletimpl.h
new file mode 100644
index 0000000..0426109
--- a/dev/null
+++ b/core/applets/clipboardapplet/clipboardappletimpl.h
@@ -0,0 +1,44 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CLIPBOARDAPPLETIMPL_H
+#define CLIPBOARDAPPLETIMPL_H
+
+#include <qpe/taskbarappletinterface.h>
+
+class ClipboardApplet;
+
+class ClipboardAppletImpl : public TaskbarAppletInterface
+{
+public:
+ ClipboardAppletImpl();
+ virtual ~ClipboardAppletImpl();
+
+ QRESULT queryInterface( const QUuid&, QUnknownInterface** );
+ Q_REFCOUNT
+
+ virtual QWidget *applet( QWidget *parent );
+ virtual int position() const;
+
+private:
+ ClipboardApplet *clipboard;
+ ulong ref;
+};
+
+#endif
diff --git a/core/applets/clipboardapplet/qpe-clipboardapplet.control b/core/applets/clipboardapplet/qpe-clipboardapplet.control
new file mode 100644
index 0000000..26cbc55
--- a/dev/null
+++ b/core/applets/clipboardapplet/qpe-clipboardapplet.control
@@ -0,0 +1,9 @@
+Files: plugins/applets/libclipboardapplet.so*
+Priority: optional
+Section: qpe/taskbar
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Clipboard applet
+ Clipboard applet for the Qtopia environment taskbar.
diff --git a/core/applets/clipboardapplet/qpe-clipboardapplet.postinst b/core/applets/clipboardapplet/qpe-clipboardapplet.postinst
new file mode 100644
index 0000000..ba76ffa
--- a/dev/null
+++ b/core/applets/clipboardapplet/qpe-clipboardapplet.postinst
@@ -0,0 +1,2 @@
+#!/bin/sh
+/opt/QtPalmtop/bin/qcop QPE/TaskBar "reloadApplets()"
diff --git a/core/applets/clipboardapplet/qpe-clipboardapplet.postrm b/core/applets/clipboardapplet/qpe-clipboardapplet.postrm
new file mode 100644
index 0000000..ba76ffa
--- a/dev/null
+++ b/core/applets/clipboardapplet/qpe-clipboardapplet.postrm
@@ -0,0 +1,2 @@
+#!/bin/sh
+/opt/QtPalmtop/bin/qcop QPE/TaskBar "reloadApplets()"
diff --git a/core/applets/clockapplet/.cvsignore b/core/applets/clockapplet/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/core/applets/clockapplet/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile
diff --git a/core/applets/clockapplet/Makefile.in b/core/applets/clockapplet/Makefile.in
new file mode 100644
index 0000000..fcf737e
--- a/dev/null
+++ b/core/applets/clockapplet/Makefile.in
@@ -0,0 +1,115 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../../plugins/applets/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = clockapplet
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = clock.h \
+ clockappletimpl.h
+SOURCES = clock.cpp \
+ clockappletimpl.cpp
+OBJECTS = clock.o \
+ clockappletimpl.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_clock.cpp
+OBJMOC = moc_clock.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
+
+$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK_LIB)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake clockapplet.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+clock.o: clock.cpp \
+ clock.h
+
+clockappletimpl.o: clockappletimpl.cpp \
+ clock.h \
+ clockappletimpl.h
+
+moc_clock.o: moc_clock.cpp \
+ clock.h
+
+moc_clock.cpp: clock.h
+ $(MOC) clock.h -o moc_clock.cpp
+
+
diff --git a/core/applets/clockapplet/clock.cpp b/core/applets/clockapplet/clock.cpp
new file mode 100644
index 0000000..178dcbe
--- a/dev/null
+++ b/core/applets/clockapplet/clock.cpp
@@ -0,0 +1,97 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "clock.h"
+
+#include <qpe/global.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/config.h>
+
+#include <qmainwindow.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qmessagebox.h>
+#include <qdatetime.h>
+#include <qtimer.h>
+#include <qpopupmenu.h>
+#include <stdlib.h>
+
+
+LauncherClock::LauncherClock( QWidget *parent ) : QLabel( parent )
+{
+ // If you want a sunken border around the clock do this:
+ // setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ setFont( QFont( "Helvetica", 10, QFont::Normal ) );
+ connect( qApp, SIGNAL( timeChanged() ), this, SLOT( updateTime( ) ) );
+ connect( qApp, SIGNAL( clockChanged( bool ) ),
+ this, SLOT( slotClockChanged( bool ) ) );
+ Config config( "qpe" );
+ config.setGroup( "Time" );
+ ampmFormat = config.readBoolEntry( "AMPM", TRUE );
+ timerId = 0;
+ timerEvent( 0 );
+ show();
+}
+
+void LauncherClock::mouseReleaseEvent( QMouseEvent * )
+{
+ Global::execute( "systemtime" );
+}
+
+
+void LauncherClock::timerEvent( QTimerEvent *e )
+{
+ if ( !e || e->timerId() == timerId ) {
+ killTimer( timerId );
+ changeTime();
+ QTime t = QTime::currentTime();
+ int ms = (60 - t.second())*1000 - t.msec();
+ timerId = startTimer( ms );
+ } else {
+ QLabel::timerEvent( e );
+ }
+}
+
+void LauncherClock::updateTime( void )
+{
+ changeTime();
+}
+
+void LauncherClock::changeTime( void )
+{
+ QTime tm = QDateTime::currentDateTime().time();
+ QString s;
+ if( ampmFormat ) {
+ int hour = tm.hour();
+ if (hour == 0)
+ hour = 12;
+ if (hour > 12)
+ hour -= 12;
+ s.sprintf( "%2d%c%02d %s", hour, ':', tm.minute(), (tm.hour() >= 12) ? "PM" : "AM" );
+ } else
+ s.sprintf( "%2d%c%02d", tm.hour(), ':', tm.minute() );
+ setText( s );
+}
+
+void LauncherClock::slotClockChanged( bool pm )
+{
+ ampmFormat = pm;
+ updateTime();
+}
diff --git a/core/applets/clockapplet/clock.h b/core/applets/clockapplet/clock.h
new file mode 100644
index 0000000..9670d90
--- a/dev/null
+++ b/core/applets/clockapplet/clock.h
@@ -0,0 +1,46 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef __LAUNCHER_CLOCK_H__
+#define __LAUNCHER_CLOCK_H__
+
+
+#include <qlabel.h>
+#include <qdatetime.h>
+
+class LauncherClock : public QLabel
+{
+ Q_OBJECT
+public:
+ LauncherClock( QWidget *parent );
+
+protected slots:
+ void updateTime( void );
+ void slotClockChanged( bool pm );
+
+protected:
+ void mouseReleaseEvent( QMouseEvent * );
+ void timerEvent( QTimerEvent * );
+ void changeTime( void );
+ bool ampmFormat;
+ int timerId;
+};
+
+
+#endif // __LAUNCHER_CLOCK_H__
diff --git a/core/applets/clockapplet/clockapplet.pro b/core/applets/clockapplet/clockapplet.pro
new file mode 100644
index 0000000..29a4e8b
--- a/dev/null
+++ b/core/applets/clockapplet/clockapplet.pro
@@ -0,0 +1,12 @@
+TEMPLATE = lib
+CONFIG += qt warn_on release
+HEADERS = clock.h clockappletimpl.h
+SOURCES = clock.cpp clockappletimpl.cpp
+TARGET = clockapplet
+DESTDIR = ../../plugins/applets
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += ../$(QPEDIR)/include ..
+LIBS += -lqpe
+VERSION = 1.0.0
+
+TRANSLATIONS += ../../i18n/de/libclockapplet.ts
diff --git a/core/applets/clockapplet/clockappletimpl.cpp b/core/applets/clockapplet/clockappletimpl.cpp
new file mode 100644
index 0000000..8bf1baf
--- a/dev/null
+++ b/core/applets/clockapplet/clockappletimpl.cpp
@@ -0,0 +1,65 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "clock.h"
+#include "clockappletimpl.h"
+
+
+ClockAppletImpl::ClockAppletImpl()
+ : clock(0), ref(0)
+{
+}
+
+ClockAppletImpl::~ClockAppletImpl()
+{
+ delete clock;
+}
+
+QWidget *ClockAppletImpl::applet( QWidget *parent )
+{
+ if ( !clock )
+ clock = new LauncherClock( parent );
+ return clock;
+}
+
+int ClockAppletImpl::position() const
+{
+ return 10;
+}
+
+#ifndef QT_NO_COMPONENT
+QRESULT ClockAppletImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
+{
+ *iface = 0;
+ if ( uuid == IID_QUnknown )
+ *iface = this;
+ else if ( uuid == IID_TaskbarApplet )
+ *iface = this;
+
+ if ( *iface )
+ (*iface)->addRef();
+ return QS_OK;
+}
+
+Q_EXPORT_INTERFACE()
+{
+ Q_CREATE_INSTANCE( ClockAppletImpl )
+}
+#endif
+
diff --git a/core/applets/clockapplet/clockappletimpl.h b/core/applets/clockapplet/clockappletimpl.h
new file mode 100644
index 0000000..0c0912e
--- a/dev/null
+++ b/core/applets/clockapplet/clockappletimpl.h
@@ -0,0 +1,46 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef CLOCKAPPLETIMPL_H
+#define CLOCKAPPLETIMPL_H
+
+#include <qpe/taskbarappletinterface.h>
+
+class LauncherClock;
+
+class ClockAppletImpl : public TaskbarAppletInterface
+{
+public:
+ ClockAppletImpl();
+ virtual ~ClockAppletImpl();
+
+#ifndef QT_NO_COMPONENT
+ QRESULT queryInterface( const QUuid&, QUnknownInterface** );
+ Q_REFCOUNT
+#endif
+
+ virtual QWidget *applet( QWidget *parent );
+ virtual int position() const;
+
+private:
+ LauncherClock *clock;
+ ulong ref;
+};
+
+#endif
diff --git a/core/applets/clockapplet/qpe-clockapplet.control b/core/applets/clockapplet/qpe-clockapplet.control
new file mode 100644
index 0000000..9532ca8
--- a/dev/null
+++ b/core/applets/clockapplet/qpe-clockapplet.control
@@ -0,0 +1,9 @@
+Files: plugins/applets/libclockapplet.so*
+Priority: optional
+Section: qpe/taskbar
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Clock applet
+ Clock applet for the Qtopia environment taskbar.
diff --git a/core/applets/clockapplet/qpe-clockapplet.postinst b/core/applets/clockapplet/qpe-clockapplet.postinst
new file mode 100755
index 0000000..ba76ffa
--- a/dev/null
+++ b/core/applets/clockapplet/qpe-clockapplet.postinst
@@ -0,0 +1,2 @@
+#!/bin/sh
+/opt/QtPalmtop/bin/qcop QPE/TaskBar "reloadApplets()"
diff --git a/core/applets/clockapplet/qpe-clockapplet.postrm b/core/applets/clockapplet/qpe-clockapplet.postrm
new file mode 100755
index 0000000..ba76ffa
--- a/dev/null
+++ b/core/applets/clockapplet/qpe-clockapplet.postrm
@@ -0,0 +1,2 @@
+#!/bin/sh
+/opt/QtPalmtop/bin/qcop QPE/TaskBar "reloadApplets()"
diff --git a/core/applets/volumeapplet/.cvsignore b/core/applets/volumeapplet/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/core/applets/volumeapplet/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile
diff --git a/core/applets/volumeapplet/Makefile.in b/core/applets/volumeapplet/Makefile.in
new file mode 100644
index 0000000..7020cb7
--- a/dev/null
+++ b/core/applets/volumeapplet/Makefile.in
@@ -0,0 +1,115 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../../plugins/applets/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = volumeapplet
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = volume.h \
+ volumeappletimpl.h
+SOURCES = volume.cpp \
+ volumeappletimpl.cpp
+OBJECTS = volume.o \
+ volumeappletimpl.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_volume.cpp
+OBJMOC = moc_volume.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
+
+$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK_LIB)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake volumeapplet.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+volume.o: volume.cpp \
+ volume.h
+
+volumeappletimpl.o: volumeappletimpl.cpp \
+ volume.h \
+ volumeappletimpl.h
+
+moc_volume.o: moc_volume.cpp \
+ volume.h
+
+moc_volume.cpp: volume.h
+ $(MOC) volume.h -o moc_volume.cpp
+
+
diff --git a/core/applets/volumeapplet/qpe-volumeapplet.control b/core/applets/volumeapplet/qpe-volumeapplet.control
new file mode 100644
index 0000000..a80262a
--- a/dev/null
+++ b/core/applets/volumeapplet/qpe-volumeapplet.control
@@ -0,0 +1,9 @@
+Files: plugins/applets/libvolumeapplet.so*
+Priority: optional
+Section: qpe/taskbar
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Volume applet
+ Volume applet for the Qtopia environment taskbar.
diff --git a/core/applets/volumeapplet/qpe-volumeapplet.postinst b/core/applets/volumeapplet/qpe-volumeapplet.postinst
new file mode 100755
index 0000000..ba76ffa
--- a/dev/null
+++ b/core/applets/volumeapplet/qpe-volumeapplet.postinst
@@ -0,0 +1,2 @@
+#!/bin/sh
+/opt/QtPalmtop/bin/qcop QPE/TaskBar "reloadApplets()"
diff --git a/core/applets/volumeapplet/qpe-volumeapplet.postrm b/core/applets/volumeapplet/qpe-volumeapplet.postrm
new file mode 100755
index 0000000..ba76ffa
--- a/dev/null
+++ b/core/applets/volumeapplet/qpe-volumeapplet.postrm
@@ -0,0 +1,2 @@
+#!/bin/sh
+/opt/QtPalmtop/bin/qcop QPE/TaskBar "reloadApplets()"
diff --git a/core/applets/volumeapplet/volume.cpp b/core/applets/volumeapplet/volume.cpp
new file mode 100644
index 0000000..35dbf22
--- a/dev/null
+++ b/core/applets/volumeapplet/volume.cpp
@@ -0,0 +1,199 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "volume.h"
+
+#include <qpe/resource.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/config.h>
+#if ( defined Q_WS_QWS || defined(_WS_QWS_) ) && !defined(QT_NO_COP)
+#include <qpe/qcopenvelope_qws.h>
+#endif
+
+#include <qpainter.h>
+#include <qcheckbox.h>
+#include <qslider.h>
+#include <qlayout.h>
+#include <qframe.h>
+#include <qpixmap.h>
+
+
+VolumeControl::VolumeControl( QWidget *parent, const char *name )
+ : QFrame( parent, name, WDestructiveClose | WStyle_StaysOnTop | WType_Popup )
+{
+ setFrameStyle( QFrame::PopupPanel | QFrame::Raised );
+
+ QVBoxLayout *vbox = new QVBoxLayout( this );
+ slider = new QSlider( this );
+ muteBox = new QCheckBox( tr("Mute"), this );
+ slider->setRange( 0, 100 );
+ slider->setTickmarks( QSlider::Both );
+ slider->setTickInterval( 20 );
+ slider->setFocusPolicy( QWidget::NoFocus );
+ muteBox->setFocusPolicy( QWidget::NoFocus );
+ vbox->setMargin( 6 );
+ vbox->setSpacing( 3 );
+ vbox->addWidget( slider, 0, Qt::AlignVCenter | Qt::AlignHCenter );
+ vbox->addWidget( muteBox );
+ setFixedHeight( 100 );
+ setFixedWidth( sizeHint().width() );
+ setFocusPolicy(QWidget::NoFocus);
+}
+
+void VolumeControl::keyPressEvent( QKeyEvent *e)
+{
+ switch(e->key()) {
+ case Key_Up:
+ slider->subtractStep();
+ break;
+ case Key_Down:
+ slider->addStep();
+ break;
+ case Key_Space:
+ muteBox->toggle();
+ break;
+ case Key_Escape:
+ close();
+ break;
+ }
+}
+
+//===========================================================================
+
+VolumeApplet::VolumeApplet( QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+ setFixedHeight( 18 );
+ setFixedWidth( 14 );
+ volumePixmap = Resource::loadPixmap( "volume" );
+ muted = FALSE; // ### read from pref
+ volumePercent = 50; // ### read from pref
+ connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( volumeChanged(bool) ) );
+ writeSystemVolume();
+}
+
+VolumeApplet::~VolumeApplet()
+{
+}
+
+void VolumeApplet::mousePressEvent( QMouseEvent *)
+{
+ // Create a small volume control window to adjust the volume with
+ VolumeControl *vc = new VolumeControl;
+ vc->slider->setValue( 100 - volumePercent );
+ vc->muteBox->setChecked( muted );
+ connect( vc->slider, SIGNAL( valueChanged( int ) ), this, SLOT( sliderMoved( int ) ) );
+ connect( vc->muteBox, SIGNAL( toggled( bool ) ), this, SLOT( mute( bool ) ) );
+ QPoint curPos = mapToGlobal( rect().topLeft() );
+ vc->move( curPos.x()-(vc->sizeHint().width()-width())/2, curPos.y() - 100 );
+ vc->show();
+}
+
+void VolumeApplet::volumeChanged( bool nowMuted )
+{
+ int previousVolume = volumePercent;
+
+ if ( !nowMuted )
+ readSystemVolume();
+
+ // Handle case where muting it toggled
+ if ( muted != nowMuted ) {
+ muted = nowMuted;
+ repaint( TRUE );
+ return;
+ }
+
+ // Avoid over repainting
+ if ( previousVolume != volumePercent )
+ repaint( 2, height() - 3, width() - 4, 2, FALSE );
+}
+
+
+void VolumeApplet::mute( bool toggled )
+{
+ muted = toggled;
+ // clear if removing mute
+ repaint( !toggled );
+ writeSystemVolume();
+}
+
+
+void VolumeApplet::sliderMoved( int percent )
+{
+ setVolume( 100 - percent );
+}
+
+
+void VolumeApplet::readSystemVolume()
+{
+ Config cfg("Sound");
+ cfg.setGroup("System");
+ volumePercent = cfg.readNumEntry("Volume");
+}
+
+
+void VolumeApplet::setVolume( int percent )
+{
+ // clamp volume percent to be between 0 and 100
+ volumePercent = (percent < 0) ? 0 : ((percent > 100) ? 100 : percent);
+ // repaint just the little volume rectangle
+ repaint( 2, height() - 3, width() - 4, 2, FALSE );
+ writeSystemVolume();
+}
+
+
+void VolumeApplet::writeSystemVolume()
+{
+ {
+ Config cfg("Sound");
+ cfg.setGroup("System");
+ cfg.writeEntry("Volume",volumePercent);
+ }
+#if ( defined Q_WS_QWS || defined(_WS_QWS_) ) && !defined(QT_NO_COP)
+ // Send notification that the volume has changed
+ QCopEnvelope( "QPE/System", "volumeChange(bool)" ) << muted;
+#endif
+}
+
+
+void VolumeApplet::paintEvent( QPaintEvent* )
+{
+ QPainter p(this);
+
+ if (volumePixmap.isNull())
+ volumePixmap = Resource::loadPixmap( "volume" );
+ p.drawPixmap( 0, 1, volumePixmap );
+ p.setPen( darkGray );
+ p.drawRect( 1, height() - 4, width() - 2, 4 );
+
+ int pixelsWide = volumePercent * (width() - 4) / 100;
+ p.fillRect( 2, height() - 3, pixelsWide, 2, red );
+ p.fillRect( pixelsWide + 2, height() - 3, width() - 4 - pixelsWide, 2, lightGray );
+
+ if ( muted ) {
+ p.setPen( red );
+ p.drawLine( 1, 2, width() - 2, height() - 5 );
+ p.drawLine( 1, 3, width() - 2, height() - 4 );
+ p.drawLine( width() - 2, 2, 1, height() - 5 );
+ p.drawLine( width() - 2, 3, 1, height() - 4 );
+ }
+}
+
+
diff --git a/core/applets/volumeapplet/volume.h b/core/applets/volumeapplet/volume.h
new file mode 100644
index 0000000..5704cad
--- a/dev/null
+++ b/core/applets/volumeapplet/volume.h
@@ -0,0 +1,75 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef __VOLUME_APPLET_H__
+#define __VOLUME_APPLET_H__
+
+
+#include <qwidget.h>
+#include <qframe.h>
+#include <qpixmap.h>
+#include <qguardedptr.h>
+
+class QSlider;
+class QCheckBox;
+
+class VolumeControl : public QFrame
+{
+ Q_OBJECT
+public:
+ VolumeControl( QWidget *parent=0, const char *name=0 );
+
+public:
+ QSlider *slider;
+ QCheckBox *muteBox;
+
+private:
+ void keyPressEvent( QKeyEvent * );
+};
+
+class VolumeApplet : public QWidget
+{
+ Q_OBJECT
+public:
+ VolumeApplet( QWidget *parent = 0, const char *name=0 );
+ ~VolumeApplet();
+ bool isMute( ) { return muted; }
+ int percent( ) { return volumePercent; }
+
+public slots:
+ void volumeChanged( bool muted );
+ void setVolume( int percent );
+ void sliderMoved( int percent );
+ void mute( bool );
+
+private:
+ void readSystemVolume();
+ void writeSystemVolume();
+ void mousePressEvent( QMouseEvent * );
+ void paintEvent( QPaintEvent* );
+
+private:
+ int volumePercent;
+ bool muted;
+ QPixmap volumePixmap;
+};
+
+
+#endif // __VOLUME_APPLET_H__
+
diff --git a/core/applets/volumeapplet/volumeapplet.pro b/core/applets/volumeapplet/volumeapplet.pro
new file mode 100644
index 0000000..a33cf81
--- a/dev/null
+++ b/core/applets/volumeapplet/volumeapplet.pro
@@ -0,0 +1,12 @@
+TEMPLATE = lib
+CONFIG += qt warn_on release
+HEADERS = volume.h volumeappletimpl.h
+SOURCES = volume.cpp volumeappletimpl.cpp
+TARGET = volumeapplet
+DESTDIR = ../../plugins/applets
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += ../$(QPEDIR)/include
+LIBS += -lqpe
+VERSION = 1.0.0
+
+TRANSLATIONS += ../../i18n/de/libvolumeapplet.ts
diff --git a/core/applets/volumeapplet/volumeappletimpl.cpp b/core/applets/volumeapplet/volumeappletimpl.cpp
new file mode 100644
index 0000000..676ab61
--- a/dev/null
+++ b/core/applets/volumeapplet/volumeappletimpl.cpp
@@ -0,0 +1,64 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "volume.h"
+#include "volumeappletimpl.h"
+
+
+VolumeAppletImpl::VolumeAppletImpl()
+ : volume(0), ref(0)
+{
+}
+
+VolumeAppletImpl::~VolumeAppletImpl()
+{
+ delete volume;
+}
+
+QWidget *VolumeAppletImpl::applet( QWidget *parent )
+{
+ if ( !volume )
+ volume = new VolumeApplet( parent );
+ return volume;
+}
+
+int VolumeAppletImpl::position() const
+{
+ return 6;
+}
+
+QRESULT VolumeAppletImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
+{
+ *iface = 0;
+ if ( uuid == IID_QUnknown )
+ *iface = this;
+ else if ( uuid == IID_TaskbarApplet )
+ *iface = this;
+
+ if ( *iface )
+ (*iface)->addRef();
+ return QS_OK;
+}
+
+Q_EXPORT_INTERFACE()
+{
+ Q_CREATE_INSTANCE( VolumeAppletImpl )
+}
+
+
diff --git a/core/applets/volumeapplet/volumeappletimpl.h b/core/applets/volumeapplet/volumeappletimpl.h
new file mode 100644
index 0000000..9b2952a
--- a/dev/null
+++ b/core/applets/volumeapplet/volumeappletimpl.h
@@ -0,0 +1,44 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef VOLUMEAPPLETIMPL_H
+#define VOLUMEAPPLETIMPL_H
+
+#include <qpe/taskbarappletinterface.h>
+
+class VolumeApplet;
+
+class VolumeAppletImpl : public TaskbarAppletInterface
+{
+public:
+ VolumeAppletImpl();
+ virtual ~VolumeAppletImpl();
+
+ QRESULT queryInterface( const QUuid&, QUnknownInterface** );
+ Q_REFCOUNT
+
+ virtual QWidget *applet( QWidget *parent );
+ virtual int position() const;
+
+private:
+ VolumeApplet *volume;
+ ulong ref;
+};
+
+#endif
diff --git a/core/apps/calibrate/.cvsignore b/core/apps/calibrate/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/core/apps/calibrate/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile
diff --git a/core/apps/calibrate/calibrate.cpp b/core/apps/calibrate/calibrate.cpp
new file mode 100644
index 0000000..96cd1ca
--- a/dev/null
+++ b/core/apps/calibrate/calibrate.cpp
@@ -0,0 +1,243 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "calibrate.h"
+
+#include <qpe/resource.h>
+
+#include <qapplication.h>
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+
+#include <qpainter.h>
+#include <qtimer.h>
+#include <qwindowsystem_qws.h>
+#include <qgfx_qws.h>
+
+
+Calibrate::Calibrate(QWidget* parent, const char * name, WFlags wf) :
+ QDialog( parent, name, TRUE, wf | WStyle_Tool | WStyle_Customize | WStyle_StaysOnTop )
+{
+ showCross = TRUE;
+ const int offset = 30;
+ QRect desk = qApp->desktop()->geometry();
+ setGeometry( 0, 0, desk.width(), desk.height() );
+ if ( desk.height() < 250 ) {
+ int w = desk.height()/3;
+ logo.convertFromImage(Resource::loadImage("qtlogo").smoothScale(w,w));
+ } else {
+ logo = Resource::loadPixmap( "qtlogo" );
+ }
+ cd.screenPoints[QWSPointerCalibrationData::TopLeft] = QPoint( offset, offset );
+ cd.screenPoints[QWSPointerCalibrationData::BottomLeft] = QPoint( offset, qt_screen->deviceHeight() - offset );
+ cd.screenPoints[QWSPointerCalibrationData::BottomRight] = QPoint( qt_screen->deviceWidth() - offset, qt_screen->deviceHeight() - offset );
+ cd.screenPoints[QWSPointerCalibrationData::TopRight] = QPoint( qt_screen->deviceWidth() - offset, offset );
+ cd.screenPoints[QWSPointerCalibrationData::Center] = QPoint( qt_screen->deviceWidth()/2, qt_screen->deviceHeight()/2 );
+ goodcd = cd;
+ reset();
+
+ timer = new QTimer( this );
+ connect( timer, SIGNAL(timeout()), this, SLOT(timeout()) );
+}
+
+Calibrate::~Calibrate()
+{
+ store();
+}
+
+void Calibrate::show()
+{
+ grabMouse();
+ QWSServer::mouseHandler()->getCalibration(&goodcd);
+ QWSServer::mouseHandler()->clearCalibration();
+ QDialog::show();
+}
+
+void Calibrate::store()
+{
+ QWSServer::mouseHandler()->calibrate( &goodcd );
+}
+
+void Calibrate::hide()
+{
+ if ( isVisible() )
+ store();
+ QDialog::hide();
+}
+
+void Calibrate::reset()
+{
+ penPos = QPoint();
+ location = QWSPointerCalibrationData::TopLeft;
+ crossPos = fromDevice( cd.screenPoints[location] );
+}
+
+QPoint Calibrate::fromDevice( const QPoint &p )
+{
+ return qt_screen->mapFromDevice( p,
+ QSize(qt_screen->deviceWidth(), qt_screen->deviceHeight()) );
+}
+
+bool Calibrate::sanityCheck()
+{
+ QPoint tl = cd.devPoints[QWSPointerCalibrationData::TopLeft];
+ QPoint tr = cd.devPoints[QWSPointerCalibrationData::TopRight];
+ QPoint bl = cd.devPoints[QWSPointerCalibrationData::BottomLeft];
+ QPoint br = cd.devPoints[QWSPointerCalibrationData::BottomRight];
+
+ int vl = QABS( tl.y() - bl.y() );
+ int vr = QABS( tr.y() - br.y() );
+ int diff = QABS( vl - vr );
+ int avg = ( vl + vr ) / 2;
+ if ( diff > avg / 20 ) // 5% leeway
+ return FALSE;
+
+ int ht = QABS( tl.x() - tr.x() );
+ int hb = QABS( br.x() - bl.x() );
+ diff = QABS( ht - hb );
+ avg = ( ht + hb ) / 2;
+ if ( diff > avg / 20 ) // 5% leeway
+ return FALSE;
+
+ return TRUE;
+}
+
+void Calibrate::moveCrosshair( QPoint pt )
+{
+/*
+ QPainter p( this );
+ p.drawPixmap( crossPos.x()-8, crossPos.y()-8, saveUnder );
+ saveUnder = QPixmap::grabWindow( winId(), pt.x()-8, pt.y()-8, 16, 16 );
+ p.drawRect( pt.x()-1, pt.y()-8, 2, 7 );
+ p.drawRect( pt.x()-1, pt.y()+1, 2, 7 );
+ p.drawRect( pt.x()-8, pt.y()-1, 7, 2 );
+ p.drawRect( pt.x()+1, pt.y()-1, 7, 2 );
+*/
+ showCross = FALSE;
+ repaint( crossPos.x()-8, crossPos.y()-8, 16, 16 );
+ showCross = TRUE;
+ crossPos = pt;
+ repaint( crossPos.x()-8, crossPos.y()-8, 16, 16 );
+}
+
+void Calibrate::paintEvent( QPaintEvent * )
+{
+ QPainter p( this );
+
+ int y;
+
+ if ( !logo.isNull() ) {
+ y = height() / 2 - logo.height() - 15;
+ p.drawPixmap( (width() - logo.width())/2, y, logo );
+ }
+
+ y = height() / 2 + 15;
+
+ p.drawText( 0, y+height()/8, width(), height() - y, AlignHCenter,
+ tr("Touch the crosshairs firmly and\n"
+ "accurately to calibrate your screen.") );
+
+ QFont f = p.font(); f.setBold(TRUE);
+ p.setFont( f );
+ p.drawText( 0, y, width(), height() - y, AlignHCenter|WordBreak,
+ tr("Welcome to Qtopia") );
+
+/*
+ saveUnder = QPixmap::grabWindow( winId(), crossPos.x()-8, crossPos.y()-8,
+ 16, 16 );
+ moveCrosshair( crossPos );
+*/
+ if ( showCross ) {
+ p.drawRect( crossPos.x()-1, crossPos.y()-8, 2, 7 );
+ p.drawRect( crossPos.x()-1, crossPos.y()+1, 2, 7 );
+ p.drawRect( crossPos.x()-8, crossPos.y()-1, 7, 2 );
+ p.drawRect( crossPos.x()+1, crossPos.y()-1, 7, 2 );
+ }
+}
+
+void Calibrate::mousePressEvent( QMouseEvent *e )
+{
+ // map to device coordinates
+ QPoint devPos = qt_screen->mapToDevice( e->pos(),
+ QSize(qt_screen->width(), qt_screen->height()) );
+ if ( penPos.isNull() )
+ penPos = devPos;
+ else
+ penPos = QPoint( (penPos.x() + devPos.x())/2,
+ (penPos.y() + devPos.y())/2 );
+}
+
+void Calibrate::mouseReleaseEvent( QMouseEvent * )
+{
+ if ( timer->isActive() )
+ return;
+
+ bool doMove = TRUE;
+
+ cd.devPoints[location] = penPos;
+ if ( location < QWSPointerCalibrationData::LastLocation ) {
+ location = (QWSPointerCalibrationData::Location)((int)location + 1);
+ } else {
+ if ( sanityCheck() ) {
+ reset();
+ goodcd = cd;
+ hide();
+ emit accept();
+ doMove = FALSE;
+ } else {
+ location = QWSPointerCalibrationData::TopLeft;
+ }
+ }
+
+ if ( doMove ) {
+ QPoint target = fromDevice( cd.screenPoints[location] );
+ dx = (target.x() - crossPos.x())/10;
+ dy = (target.y() - crossPos.y())/10;
+ timer->start( 30 );
+ }
+}
+
+void Calibrate::timeout()
+{
+ QPoint target = fromDevice( cd.screenPoints[location] );
+
+ bool doneX = FALSE;
+ bool doneY = FALSE;
+ QPoint newPos( crossPos.x() + dx, crossPos.y() + dy );
+
+ if ( QABS(crossPos.x() - target.x()) <= QABS(dx) ) {
+ newPos.setX( target.x() );
+ doneX = TRUE;
+ }
+
+ if ( QABS(crossPos.y() - target.y()) <= QABS(dy) ) {
+ newPos.setY(target.y());
+ doneY = TRUE;
+ }
+
+ if ( doneX && doneY ) {
+ penPos = QPoint();
+ timer->stop();
+ }
+
+ moveCrosshair( newPos );
+}
+
+#endif // _WS_QWS_
diff --git a/core/apps/calibrate/calibrate.h b/core/apps/calibrate/calibrate.h
new file mode 100644
index 0000000..97108c9
--- a/dev/null
+++ b/core/apps/calibrate/calibrate.h
@@ -0,0 +1,67 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qwsmouse_qws.h>
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+
+#include <qdialog.h>
+#include <qpixmap.h>
+
+class QTimer;
+
+class Calibrate : public QDialog
+{
+ Q_OBJECT
+public:
+ Calibrate(QWidget* parent=0, const char * name=0, WFlags=0);
+ ~Calibrate();
+
+ void show();
+ void hide();
+
+private:
+ QPoint fromDevice( const QPoint &p );
+ bool sanityCheck();
+ void moveCrosshair( QPoint pt );
+ void paintEvent( QPaintEvent * );
+ void mousePressEvent( QMouseEvent * );
+ void mouseReleaseEvent( QMouseEvent * );
+
+private slots:
+ void timeout();
+
+private:
+ void store();
+ void reset();
+ QPixmap logo;
+ QWSPointerCalibrationData goodcd,cd;
+ QWSPointerCalibrationData::Location location;
+ QPoint crossPos;
+ QPoint penPos;
+ QPixmap saveUnder;
+ QTimer *timer;
+ int dx;
+ int dy;
+ bool showCross;
+};
+
+#endif // _WS_QWS_
+
diff --git a/core/apps/calibrate/calibrate.pro b/core/apps/calibrate/calibrate.pro
new file mode 100644
index 0000000..9769ea6
--- a/dev/null
+++ b/core/apps/calibrate/calibrate.pro
@@ -0,0 +1 @@
+# This is part of the taskbar
diff --git a/core/apps/embeddedkonsole/.cvsignore b/core/apps/embeddedkonsole/.cvsignore
new file mode 100644
index 0000000..6fe2396
--- a/dev/null
+++ b/core/apps/embeddedkonsole/.cvsignore
@@ -0,0 +1,2 @@
+moc_*
+Makefile
diff --git a/core/apps/embeddedkonsole/Makefile.in b/core/apps/embeddedkonsole/Makefile.in
new file mode 100644
index 0000000..b858cd4
--- a/dev/null
+++ b/core/apps/embeddedkonsole/Makefile.in
@@ -0,0 +1,285 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = embeddedkonsole
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = TEWidget.h \
+ TEScreen.h \
+ TECommon.h \
+ TEHistory.h \
+ TEmulation.h \
+ TEmuVt102.h \
+ session.h \
+ keytrans.h \
+ konsole.h \
+ MyPty.h
+SOURCES = TEScreen.cpp \
+ TEWidget.cpp \
+ TEHistory.cpp \
+ TEmulation.cpp \
+ TEmuVt102.cpp \
+ session.cpp \
+ keytrans.cpp \
+ konsole.cpp \
+ main.cpp \
+ MyPty.cpp
+OBJECTS = TEScreen.o \
+ TEWidget.o \
+ TEHistory.o \
+ TEmulation.o \
+ TEmuVt102.o \
+ session.o \
+ keytrans.o \
+ konsole.o \
+ main.o \
+ MyPty.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_TEWidget.cpp \
+ moc_TEmulation.cpp \
+ moc_TEmuVt102.cpp \
+ moc_session.cpp \
+ moc_konsole.cpp \
+ moc_MyPty.cpp
+OBJMOC = moc_TEWidget.o \
+ moc_TEmulation.o \
+ moc_TEmuVt102.o \
+ moc_session.o \
+ moc_konsole.o \
+ moc_MyPty.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake embeddedkonsole.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=embeddedkonsole
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+TEScreen.o: TEScreen.cpp \
+ TEScreen.h \
+ TECommon.h \
+ TEHistory.h
+
+TEWidget.o: TEWidget.cpp \
+ TEWidget.h \
+ TECommon.h \
+ session.h \
+ MyPty.h \
+ TEmuVt102.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h
+
+TEHistory.o: TEHistory.cpp \
+ TEHistory.h \
+ TECommon.h
+
+TEmulation.o: TEmulation.cpp \
+ TEmulation.h \
+ TEWidget.h \
+ TECommon.h \
+ TEScreen.h \
+ TEHistory.h \
+ keytrans.h
+
+TEmuVt102.o: TEmuVt102.cpp \
+ TEmuVt102.h \
+ TEWidget.h \
+ TECommon.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h
+
+session.o: session.cpp \
+ session.h \
+ MyPty.h \
+ TEWidget.h \
+ TECommon.h \
+ TEmuVt102.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h
+
+keytrans.o: keytrans.cpp \
+ keytrans.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ default.keytab.h
+
+konsole.o: konsole.cpp \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ konsole.h \
+ MyPty.h \
+ TEWidget.h \
+ TECommon.h \
+ TEmuVt102.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h \
+ session.h
+
+main.o: main.cpp \
+ konsole.h \
+ MyPty.h \
+ TEWidget.h \
+ TECommon.h \
+ TEmuVt102.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h \
+ session.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+MyPty.o: MyPty.cpp \
+ MyPty.h
+
+moc_TEWidget.o: moc_TEWidget.cpp \
+ TEWidget.h \
+ TECommon.h
+
+moc_TEmulation.o: moc_TEmulation.cpp \
+ TEmulation.h \
+ TEWidget.h \
+ TECommon.h \
+ TEScreen.h \
+ TEHistory.h \
+ keytrans.h
+
+moc_TEmuVt102.o: moc_TEmuVt102.cpp \
+ TEmuVt102.h \
+ TEWidget.h \
+ TECommon.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h
+
+moc_session.o: moc_session.cpp \
+ session.h \
+ MyPty.h \
+ TEWidget.h \
+ TECommon.h \
+ TEmuVt102.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h
+
+moc_konsole.o: moc_konsole.cpp \
+ konsole.h \
+ MyPty.h \
+ TEWidget.h \
+ TECommon.h \
+ TEmuVt102.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h \
+ session.h
+
+moc_MyPty.o: moc_MyPty.cpp \
+ MyPty.h
+
+moc_TEWidget.cpp: TEWidget.h
+ $(MOC) TEWidget.h -o moc_TEWidget.cpp
+
+moc_TEmulation.cpp: TEmulation.h
+ $(MOC) TEmulation.h -o moc_TEmulation.cpp
+
+moc_TEmuVt102.cpp: TEmuVt102.h
+ $(MOC) TEmuVt102.h -o moc_TEmuVt102.cpp
+
+moc_session.cpp: session.h
+ $(MOC) session.h -o moc_session.cpp
+
+moc_konsole.cpp: konsole.h
+ $(MOC) konsole.h -o moc_konsole.cpp
+
+moc_MyPty.cpp: MyPty.h
+ $(MOC) MyPty.h -o moc_MyPty.cpp
+
+
diff --git a/core/apps/embeddedkonsole/MyPty.cpp b/core/apps/embeddedkonsole/MyPty.cpp
new file mode 100644
index 0000000..3622d48
--- a/dev/null
+++ b/core/apps/embeddedkonsole/MyPty.cpp
@@ -0,0 +1,279 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [MyPty.C] Pseudo Terminal Device */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+/* If you're compiling konsole on non-Linux platforms and find
+ problems that you can track down to this file, please have
+ a look into ../README.ports, too.
+*/
+
+/*! \file
+*/
+
+/*! \class TEPty
+
+ \brief Ptys provide a pseudo terminal connection to a program.
+
+ Although closely related to pipes, these pseudo terminal connections have
+ some ability, that makes it nessesary to uses them. Most importent, they
+ know about changing screen sizes and UNIX job control.
+
+ Within the terminal emulation framework, this class represents the
+ host side of the terminal together with the connecting serial line.
+
+ One can create many instances of this class within a program.
+ As a side effect of using this class, a signal(2) handler is
+ installed on SIGCHLD.
+
+ \par FIXME
+
+ [NOTE: much of the technical stuff below will be replaced by forkpty.]
+
+ publish the SIGCHLD signal if not related to an instance.
+
+ clearify TEPty::done vs. TEPty::~TEPty semantics.
+ check if pty is restartable via run after done.
+
+ \par Pseudo terminals
+
+ Pseudo terminals are a unique feature of UNIX, and always come in form of
+ pairs of devices (/dev/ptyXX and /dev/ttyXX), which are connected to each
+ other by the operating system. One may think of them as two serial devices
+ linked by a null-modem cable. Being based on devices the number of
+ simultanous instances of this class is (globally) limited by the number of
+ those device pairs, which is 256.
+
+ Another technic are UNIX 98 PTY's. These are supported also, and prefered
+ over the (obsolete) predecessor.
+
+ There's a sinister ioctl(2), signal(2) and job control stuff
+ nessesary to make everything work as it should.
+*/
+
+
+#include <qapplication.h>
+#include <qsocketnotifier.h>
+#include <qstring.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <termios.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+
+#ifdef HAVE_OPENPTY
+#include <pty.h>
+#endif
+
+#include "MyPty.h"
+
+
+#undef VERBOSE_DEBUG
+
+
+/* -------------------------------------------------------------------------- */
+
+/*!
+ Informs the client program about the
+ actual size of the window.
+*/
+
+void MyPty::setSize(int lines, int columns)
+{
+ struct winsize wsize;
+ wsize.ws_row = (unsigned short)lines;
+ wsize.ws_col = (unsigned short)columns;
+ if(fd < 0) return;
+ ioctl(fd,TIOCSWINSZ,(char *)&wsize);
+}
+
+
+void MyPty::donePty()
+{
+ // This is code from the Qt DumbTerminal example
+ int status = 0;
+
+ ::close(fd);
+
+ if (cpid) {
+ kill(cpid, SIGHUP);
+ waitpid(cpid, &status, 0);
+ }
+
+ emit done(status);
+}
+
+
+const char* MyPty::deviceName()
+{
+ return ttynam;
+}
+
+
+void MyPty::error()
+{
+ // This is code from the Qt DumbTerminal example
+ donePty();
+}
+
+
+/*!
+ start the client program.
+*/
+int MyPty::run(const char* cmd, QStrList &, const char*, int)
+{
+ // This is code from the Qt DumbTerminal example
+ cpid = fork();
+
+ if ( !cpid ) {
+ // child - exec shell on tty
+ for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL);
+ int ttyfd = open(ttynam, O_RDWR);
+ dup2(ttyfd, STDIN_FILENO);
+ dup2(ttyfd, STDOUT_FILENO);
+ dup2(ttyfd, STDERR_FILENO);
+ // should be done with tty, so close it
+ close(ttyfd);
+ static struct termios ttmode;
+ if ( setsid() < 0 )
+ perror( "failed to set process group" );
+#if defined (TIOCSCTTY)
+ // grabbed from APUE by Stevens
+ ioctl(STDIN_FILENO, TIOCSCTTY, 0);
+#endif
+ tcgetattr( STDIN_FILENO, &ttmode );
+ ttmode.c_cc[VINTR] = 3;
+ ttmode.c_cc[VERASE] = 8;
+ tcsetattr( STDIN_FILENO, TCSANOW, &ttmode );
+ setenv("TERM","vt100",1);
+ setenv("COLORTERM","0",1);
+
+ if (getuid() == 0) {
+ char msg[] = "WARNING: You are running this shell as root!\n";
+ write(ttyfd, msg, sizeof(msg));
+ }
+ execl(cmd, cmd, 0);
+
+ donePty();
+ exit(-1);
+ }
+
+ // parent - continue as a widget
+ QSocketNotifier* sn_r = new QSocketNotifier(fd,QSocketNotifier::Read,this);
+ QSocketNotifier* sn_e = new QSocketNotifier(fd,QSocketNotifier::Exception,this);
+ connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty()));
+ connect(sn_e,SIGNAL(activated(int)),this,SLOT(error()));
+
+ return 0;
+}
+
+int MyPty::openPty()
+{
+ // This is code from the Qt DumbTerminal example
+ int ptyfd = -1;
+
+#ifdef HAVE_OPENPTY
+ int ttyfd;
+ if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) )
+ ptyfd = -1;
+ else
+ close(ttyfd); // we open the ttynam ourselves.
+#else
+ for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) {
+ for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) {
+ sprintf(ptynam,"/dev/pty%c%c",*c0,*c1);
+ sprintf(ttynam,"/dev/tty%c%c",*c0,*c1);
+ if ((ptyfd = ::open(ptynam,O_RDWR)) >= 0) {
+ if (geteuid() != 0 && !access(ttynam,R_OK|W_OK) == 0) {
+ ::close(ptyfd);
+ ptyfd = -1;
+ }
+ }
+ }
+ }
+#endif
+
+ if ( ptyfd < 0 ) {
+ qApp->exit(1);
+ return -1;
+ }
+
+ return ptyfd;
+}
+
+/*!
+ Create an instance.
+*/
+MyPty::MyPty() : cpid(0)
+{
+ fd = openPty();
+}
+
+/*!
+ Destructor.
+ Note that the related client program is not killed
+ (yet) when a instance is deleted.
+*/
+MyPty::~MyPty()
+{
+ donePty();
+}
+
+
+/*! sends len bytes through the line */
+void MyPty::send_bytes(const char* s, int len)
+{
+
+#ifdef VERBOSE_DEBUG
+ // verbose debug
+ printf("sending bytes:\n");
+ for (int i = 0; i < len; i++)
+ printf("%c", s[i]);
+ printf("\n");
+#endif
+
+ ::write(fd, s, len);
+}
+
+/*! indicates that a block of data is received */
+void MyPty::readPty()
+{
+ char buf[4096];
+
+ int len = ::read( fd, buf, 4096 );
+
+ if (len == -1)
+ donePty();
+
+ if (len < 0)
+ return;
+
+ emit block_in(buf,len);
+
+#ifdef VERBOSE_DEBUG
+ // verbose debug
+ printf("read bytes:\n");
+ for (int i = 0; i < len; i++)
+ printf("%c", buf[i]);
+ printf("\n");
+#endif
+
+}
+
diff --git a/core/apps/embeddedkonsole/MyPty.h b/core/apps/embeddedkonsole/MyPty.h
new file mode 100644
index 0000000..b2a5b58
--- a/dev/null
+++ b/core/apps/embeddedkonsole/MyPty.h
@@ -0,0 +1,88 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [MyPty.h] Pseudo Terminal Device */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+/*! \file
+*/
+
+#ifndef MY_PTY_H
+#define MY_PTY_H
+
+#include <qobject.h>
+#include <qstrlist.h>
+
+
+class MyPty : public QObject
+{
+Q_OBJECT
+
+ public:
+
+ MyPty();
+ ~MyPty();
+
+ /*!
+ having a `run' separate from the constructor allows to make
+ the necessary connections to the signals and slots of the
+ instance before starting the execution of the client.
+ */
+ int run(const char* pgm, QStrList & args, const char* term, int addutmp);
+
+ public slots:
+
+ void send_bytes(const char* s, int len);
+ void setSize(int lines, int columns);
+ void error();
+
+ signals:
+
+ /*!
+ emitted when the client program terminates.
+ \param status the wait(2) status code of the terminated client program.
+ */
+ void done(int status);
+
+ /*!
+ emitted when a new block of data comes in.
+ \param s - the data
+ \param len - the length of the block
+ */
+ void block_in(const char* s, int len);
+
+ public:
+
+ void send_byte(char s);
+// void send_string(const char* s);
+
+ const char* deviceName();
+
+ protected slots:
+ void readPty();
+ void donePty();
+
+ private:
+ int openPty();
+
+ private:
+
+ char ptynam[16]; // "/dev/ptyxx" | "/dev/ptmx"
+ char ttynam[16]; // "/dev/ttyxx" | "/dev/pts/########..."
+ int fd;
+ int cpid;
+};
+
+#endif
diff --git a/core/apps/embeddedkonsole/TECommon.h b/core/apps/embeddedkonsole/TECommon.h
new file mode 100644
index 0000000..261d51b
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TECommon.h
@@ -0,0 +1,114 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [TECommon.h] Common Definitions */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+/*! \file TECommon.h
+ \brief Definitions shared between TEScreen and TEWidget.
+*/
+
+#ifndef TECOMMON_H
+#define TECOMMON_H
+
+#include <qcolor.h>
+
+#ifndef BOOL
+typedef int BOOL;
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef UINT8
+typedef unsigned char UINT8;
+#endif
+
+#ifndef UINT16
+typedef unsigned short UINT16;
+#endif
+
+// Attributed Character Representations ///////////////////////////////
+
+// Colors
+
+#define BASE_COLORS (2+8)
+#define INTENSITIES 2
+#define TABLE_COLORS (INTENSITIES*BASE_COLORS)
+
+#define DEFAULT_FORE_COLOR 0
+#define DEFAULT_BACK_COLOR 1
+
+#define DEFAULT_RENDITION 0
+#define RE_BOLD (1 << 0)
+#define RE_BLINK (1 << 1)
+#define RE_UNDERLINE (1 << 2)
+#define RE_REVERSE (1 << 3) // Screen only
+#define RE_INTENSIVE (1 << 3) // Widget only
+
+/*! \class ca
+ * \brief a character with rendition attributes.
+*/
+
+class ca
+{
+public:
+ inline ca(UINT16 _c = ' ',
+ UINT8 _f = DEFAULT_FORE_COLOR,
+ UINT8 _b = DEFAULT_BACK_COLOR,
+ UINT8 _r = DEFAULT_RENDITION)
+ : c(_c), f(_f), b(_b), r(_r) {}
+public:
+ UINT16 c; // character
+ UINT8 f; // foreground color
+ UINT8 b; // background color
+ UINT8 r; // rendition
+public:
+ friend BOOL operator == (ca a, ca b);
+ friend BOOL operator != (ca a, ca b);
+};
+
+inline BOOL operator == (ca a, ca b)
+{
+ return a.c == b.c && a.f == b.f && a.b == b.b && a.r == b.r;
+}
+
+inline BOOL operator != (ca a, ca b)
+{
+ return a.c != b.c || a.f != b.f || a.b != b.b || a.r != b.r;
+}
+
+/*!
+*/
+struct ColorEntry
+{
+ ColorEntry(QColor c, bool tr, bool b) : color(c), transparent(tr), bold(b) {}
+ ColorEntry() : transparent(false), bold(false) {} // default constructors
+ void operator=(const ColorEntry& rhs) {
+ color = rhs.color;
+ transparent = rhs.transparent;
+ bold = rhs.bold;
+ }
+ QColor color;
+ bool transparent; // if used on bg
+ bool bold; // if used on fg
+};
+
+#endif // TECOMMON_H
diff --git a/core/apps/embeddedkonsole/TEHistory.cpp b/core/apps/embeddedkonsole/TEHistory.cpp
new file mode 100644
index 0000000..317ce57
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEHistory.cpp
@@ -0,0 +1,212 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [TEHistory.C] History Buffer */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#include "TEHistory.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
+
+/*
+ An arbitrary long scroll.
+
+ One can modify the scroll only by adding either cells
+ or newlines, but access it randomly.
+
+ The model is that of an arbitrary wide typewriter scroll
+ in that the scroll is a serie of lines and each line is
+ a serie of cells with no overwriting permitted.
+
+ The implementation provides arbitrary length and numbers
+ of cells and line/column indexed read access to the scroll
+ at constant costs.
+
+FIXME: some complain about the history buffer comsuming the
+ memory of their machines. This problem is critical
+ since the history does not behave gracefully in cases
+ where the memory is used up completely.
+
+ I put in a workaround that should handle it problem
+ now gracefully. I'm not satisfied with the solution.
+
+FIXME: Terminating the history is not properly indicated
+ in the menu. We should throw a signal.
+
+FIXME: There is noticable decrease in speed, also. Perhaps,
+ there whole feature needs to be revisited therefore.
+ Disadvantage of a more elaborated, say block-oriented
+ scheme with wrap around would be it's complexity.
+*/
+
+//FIXME: tempory replacement for tmpfile
+// this is here one for debugging purpose.
+
+//#define tmpfile xTmpFile
+
+FILE* xTmpFile()
+{
+ static int fid = 0;
+ char fname[80];
+ sprintf(fname,"TmpFile.%d",fid++);
+ return fopen(fname,"w");
+}
+
+
+// History Buffer ///////////////////////////////////////////
+
+/*
+ A Row(X) data type which allows adding elements to the end.
+*/
+
+HistoryBuffer::HistoryBuffer()
+{
+ ion = -1;
+ length = 0;
+}
+
+HistoryBuffer::~HistoryBuffer()
+{
+ setScroll(FALSE);
+}
+
+void HistoryBuffer::setScroll(bool on)
+{
+ if (on == hasScroll()) return;
+
+ if (on)
+ {
+ assert( ion < 0 );
+ assert( length == 0);
+ FILE* tmp = tmpfile(); if (!tmp) { perror("konsole: cannot open temp file.\n"); return; }
+ ion = dup(fileno(tmp)); if (ion<0) perror("konsole: cannot dup temp file.\n");
+ fclose(tmp);
+ }
+ else
+ {
+ assert( ion >= 0 );
+ close(ion);
+ ion = -1;
+ length = 0;
+ }
+}
+
+bool HistoryBuffer::hasScroll()
+{
+ return ion >= 0;
+}
+
+void HistoryBuffer::add(const unsigned char* bytes, int len)
+{ int rc;
+ assert(hasScroll());
+ rc = lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::add.seek"); setScroll(FALSE); return; }
+ rc = write(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::add.write"); setScroll(FALSE); return; }
+ length += rc;
+}
+
+void HistoryBuffer::get(unsigned char* bytes, int len, int loc)
+{ int rc;
+ assert(hasScroll());
+ if (loc < 0 || len < 0 || loc + len > length)
+ fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc);
+ rc = lseek(ion,loc,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::get.seek"); setScroll(FALSE); return; }
+ rc = read(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::get.read"); setScroll(FALSE); return; }
+}
+
+int HistoryBuffer::len()
+{
+ return length;
+}
+
+// History Scroll //////////////////////////////////////
+
+/*
+ The history scroll makes a Row(Row(Cell)) from
+ two history buffers. The index buffer contains
+ start of line positions which refere to the cells
+ buffer.
+
+ Note that index[0] addresses the second line
+ (line #1), while the first line (line #0) starts
+ at 0 in cells.
+*/
+
+HistoryScroll::HistoryScroll()
+{
+}
+
+HistoryScroll::~HistoryScroll()
+{
+}
+
+void HistoryScroll::setScroll(bool on)
+{
+ index.setScroll(on);
+ cells.setScroll(on);
+}
+
+bool HistoryScroll::hasScroll()
+{
+ return index.hasScroll() && cells.hasScroll();
+}
+
+int HistoryScroll::getLines()
+{
+ if (!hasScroll()) return 0;
+ return index.len() / sizeof(int);
+}
+
+int HistoryScroll::getLineLen(int lineno)
+{
+ if (!hasScroll()) return 0;
+ return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(ca);
+}
+
+int HistoryScroll::startOfLine(int lineno)
+{
+ if (lineno <= 0) return 0;
+ if (!hasScroll()) return 0;
+ if (lineno <= getLines())
+ { int res;
+ index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int));
+ return res;
+ }
+ return cells.len();
+}
+
+void HistoryScroll::getCells(int lineno, int colno, int count, ca res[])
+{
+ assert(hasScroll());
+ cells.get((unsigned char*)res,count*sizeof(ca),startOfLine(lineno)+colno*sizeof(ca));
+}
+
+void HistoryScroll::addCells(ca text[], int count)
+{
+ if (!hasScroll()) return;
+ cells.add((unsigned char*)text,count*sizeof(ca));
+}
+
+void HistoryScroll::addLine()
+{
+ if (!hasScroll()) return;
+ int locn = cells.len();
+ index.add((unsigned char*)&locn,sizeof(int));
+}
diff --git a/core/apps/embeddedkonsole/TEHistory.h b/core/apps/embeddedkonsole/TEHistory.h
new file mode 100644
index 0000000..8339ec6
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEHistory.h
@@ -0,0 +1,75 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [TEHistory.H] History Buffer */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef TEHISTORY_H
+#define TEHISTORY_H
+
+#include "TECommon.h"
+
+/*
+ An extendable tmpfile(1) based buffer.
+*/
+class HistoryBuffer
+{
+public:
+ HistoryBuffer();
+ ~HistoryBuffer();
+
+public:
+ void setScroll(bool on);
+ bool hasScroll();
+
+public:
+ void add(const unsigned char* bytes, int len);
+ void get(unsigned char* bytes, int len, int loc);
+ int len();
+
+private:
+ int ion;
+ int length;
+};
+
+class HistoryScroll
+{
+public:
+ HistoryScroll();
+ ~HistoryScroll();
+
+public:
+ void setScroll(bool on);
+ bool hasScroll();
+
+public: // access to history
+ int getLines();
+ int getLineLen(int lineno);
+ void getCells(int lineno, int colno, int count, ca res[]);
+
+public: // backward compatibility (obsolete)
+ ca getCell(int lineno, int colno) { ca res; getCells(lineno,colno,1,&res); return res; }
+
+public: // adding lines.
+ void addCells(ca a[], int count);
+ void addLine();
+
+private:
+ int startOfLine(int lineno);
+ HistoryBuffer index; // lines Row(int)
+ HistoryBuffer cells; // text Row(ca)
+};
+
+#endif // TEHISTORY_H
diff --git a/core/apps/embeddedkonsole/TEScreen.cpp b/core/apps/embeddedkonsole/TEScreen.cpp
new file mode 100644
index 0000000..a3d115d
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEScreen.cpp
@@ -0,0 +1,1197 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [TEScreen.C] Screen Data Type */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+/*! \file
+*/
+
+/*! \class TEScreen
+
+ \brief The image manipulated by the emulation.
+
+ This class implements the operations of the terminal emulation framework.
+ It is a complete passive device, driven by the emulation decoder
+ (TEmuVT102). By this it forms in fact an ADT, that defines operations
+ on a rectangular image.
+
+ It does neither know how to display its image nor about escape sequences.
+ It is further independent of the underlying toolkit. By this, one can even
+ use this module for an ordinary text surface.
+
+ Since the operations are called by a specific emulation decoder, one may
+ collect their different operations here.
+
+ The state manipulated by the operations is mainly kept in `image', though
+ it is a little more complex bejond this. See the header file of the class.
+
+ \sa TEWidget \sa VT102Emulation
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+// #include <kdebug.h>
+
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "TEScreen.h"
+
+#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
+
+//FIXME: this is emulation specific. Use FALSE for xterm, TRUE for ANSI.
+//FIXME: see if we can get this from terminfo.
+#define BS_CLEARS FALSE
+
+#define loc(X,Y) ((Y)*columns+(X))
+
+/*! creates a `TEScreen' of `lines' lines and `columns' columns.
+*/
+
+TEScreen::TEScreen(int lines, int columns)
+{
+ this->lines = lines;
+ this->columns = columns;
+
+ image = (ca*) malloc(lines*columns*sizeof(ca));
+ tabstops = NULL; initTabStops();
+
+ histCursor = 0;
+
+ clearSelection();
+ reset();
+}
+
+/*! Destructor
+*/
+
+TEScreen::~TEScreen()
+{
+ free(image);
+ if (tabstops) free(tabstops);
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Normalized Screen Operations */
+/* */
+/* ------------------------------------------------------------------------- */
+
+// Cursor Setting --------------------------------------------------------------
+
+/*! \section Cursor
+
+ The `cursor' is a location within the screen that is implicitely used in
+ many operations. The operations within this section allow to manipulate
+ the cursor explicitly and to obtain it's value.
+
+ The position of the cursor is guarantied to be between (including) 0 and
+ `columns-1' and `lines-1'.
+*/
+
+/*!
+ Move the cursor up.
+
+ The cursor will not be moved beyond the top margin.
+*/
+
+void TEScreen::cursorUp(int n)
+//=CUU
+{
+ if (n == 0) n = 1; // Default
+ int stop = cuY < tmargin ? 0 : tmargin;
+ cuX = QMIN(columns-1,cuX); // nowrap!
+ cuY = QMAX(stop,cuY-n);
+}
+
+/*!
+ Move the cursor down.
+
+ The cursor will not be moved beyond the bottom margin.
+*/
+
+void TEScreen::cursorDown(int n)
+//=CUD
+{
+ if (n == 0) n = 1; // Default
+ int stop = cuY > bmargin ? lines-1 : bmargin;
+ cuX = QMIN(columns-1,cuX); // nowrap!
+ cuY = QMIN(stop,cuY+n);
+}
+
+/*!
+ Move the cursor left.
+
+ The cursor will not move beyond the first column.
+*/
+
+void TEScreen::cursorLeft(int n)
+//=CUB
+{
+ if (n == 0) n = 1; // Default
+ cuX = QMIN(columns-1,cuX); // nowrap!
+ cuX = QMAX(0,cuX-n);
+}
+
+/*!
+ Move the cursor left.
+
+ The cursor will not move beyond the rightmost column.
+*/
+
+void TEScreen::cursorRight(int n)
+//=CUF
+{
+ if (n == 0) n = 1; // Default
+ cuX = QMIN(columns-1,cuX+n);
+}
+
+/*!
+ Set top and bottom margin.
+*/
+
+void TEScreen::setMargins(int top, int bot)
+//=STBM
+{
+ if (top == 0) top = 1; // Default
+ if (bot == 0) bot = lines; // Default
+ top = top - 1; // Adjust to internal lineno
+ bot = bot - 1; // Adjust to internal lineno
+ if ( !( 0 <= top && top < bot && bot < lines ) )
+ { fprintf(stderr,"%s(%d) : setRegion(%d,%d) : bad range.\n",
+ __FILE__,__LINE__,top,bot);
+ return; // Default error action: ignore
+ }
+ tmargin = top;
+ bmargin = bot;
+ cuX = 0;
+ cuY = getMode(MODE_Origin) ? top : 0;
+}
+
+/*!
+ Move the cursor down one line.
+
+ If cursor is on bottom margin, the region between the
+ actual top and bottom margin is scrolled up instead.
+*/
+
+void TEScreen::index()
+//=IND
+{
+ if (cuY == bmargin)
+ {
+ if (tmargin == 0 && bmargin == lines-1) addHistLine(); // hist.history
+ scrollUp(tmargin,1);
+ }
+ else if (cuY < lines-1)
+ cuY += 1;
+}
+
+/*!
+ Move the cursor up one line.
+
+ If cursor is on the top margin, the region between the
+ actual top and bottom margin is scrolled down instead.
+*/
+
+void TEScreen::reverseIndex()
+//=RI
+{
+ if (cuY == tmargin)
+ scrollDown(tmargin,1);
+ else if (cuY > 0)
+ cuY -= 1;
+}
+
+/*!
+ Move the cursor to the begin of the next line.
+
+ If cursor is on bottom margin, the region between the
+ actual top and bottom margin is scrolled up.
+*/
+
+void TEScreen::NextLine()
+//=NEL
+{
+ Return(); index();
+}
+
+// Line Editing ----------------------------------------------------------------
+
+/*! \section inserting / deleting characters
+*/
+
+/*! erase `n' characters starting from (including) the cursor position.
+
+ The line is filled in from the right with spaces.
+*/
+
+void TEScreen::eraseChars(int n)
+{
+ if (n == 0) n = 1; // Default
+ int p = QMAX(0,QMIN(cuX+n-1,columns-1));
+ clearImage(loc(cuX,cuY),loc(p,cuY),' ');
+}
+
+/*! delete `n' characters starting from (including) the cursor position.
+
+ The line is filled in from the right with spaces.
+*/
+
+void TEScreen::deleteChars(int n)
+{
+ if (n == 0) n = 1; // Default
+ int p = QMAX(0,QMIN(cuX+n,columns-1));
+ moveImage(loc(cuX,cuY),loc(p,cuY),loc(columns-1,cuY));
+ clearImage(loc(columns-n,cuY),loc(columns-1,cuY),' ');
+}
+
+/*! insert `n' spaces at the cursor position.
+
+ The cursor is not moved by the operation.
+*/
+
+void TEScreen::insertChars(int n)
+{
+ if (n == 0) n = 1; // Default
+ int p = QMAX(0,QMIN(columns-1-n,columns-1));
+ int q = QMAX(0,QMIN(cuX+n,columns-1));
+ moveImage(loc(q,cuY),loc(cuX,cuY),loc(p,cuY));
+ clearImage(loc(cuX,cuY),loc(q-1,cuY),' ');
+}
+
+/*! delete `n' lines starting from (including) the cursor position.
+
+ The cursor is not moved by the operation.
+*/
+
+void TEScreen::deleteLines(int n)
+{
+ if (n == 0) n = 1; // Default
+ scrollUp(cuY,n);
+}
+
+/*! insert `n' lines at the cursor position.
+
+ The cursor is not moved by the operation.
+*/
+
+void TEScreen::insertLines(int n)
+{
+ if (n == 0) n = 1; // Default
+ scrollDown(cuY,n);
+}
+
+// Mode Operations -----------------------------------------------------------
+
+/*! Set a specific mode. */
+
+void TEScreen::setMode(int m)
+{
+ currParm.mode[m] = TRUE;
+ switch(m)
+ {
+ case MODE_Origin : cuX = 0; cuY = tmargin; break; //FIXME: home
+ }
+}
+
+/*! Reset a specific mode. */
+
+void TEScreen::resetMode(int m)
+{
+ currParm.mode[m] = FALSE;
+ switch(m)
+ {
+ case MODE_Origin : cuX = 0; cuY = 0; break; //FIXME: home
+ }
+}
+
+/*! Save a specific mode. */
+
+void TEScreen::saveMode(int m)
+{
+ saveParm.mode[m] = currParm.mode[m];
+}
+
+/*! Restore a specific mode. */
+
+void TEScreen::restoreMode(int m)
+{
+ currParm.mode[m] = saveParm.mode[m];
+}
+
+//NOTE: this is a helper function
+/*! Return the setting a specific mode. */
+BOOL TEScreen::getMode(int m)
+{
+ return currParm.mode[m];
+}
+
+/*! Save the cursor position and the rendition attribute settings. */
+
+void TEScreen::saveCursor()
+{
+ sa_cuX = cuX;
+ sa_cuY = cuY;
+ sa_cu_re = cu_re;
+ sa_cu_fg = cu_fg;
+ sa_cu_bg = cu_bg;
+}
+
+/*! Restore the cursor position and the rendition attribute settings. */
+
+void TEScreen::restoreCursor()
+{
+ cuX = QMIN(sa_cuX,columns-1);
+ cuY = QMIN(sa_cuY,lines-1);
+ cu_re = sa_cu_re;
+ cu_fg = sa_cu_fg;
+ cu_bg = sa_cu_bg;
+ effectiveRendition();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Screen Operations */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*! Assing a new size to the screen.
+
+ The topmost left position is maintained, while lower lines
+ or right hand side columns might be removed or filled with
+ spaces to fit the new size.
+
+ The region setting is reset to the whole screen and the
+ tab positions reinitialized.
+*/
+
+void TEScreen::resizeImage(int new_lines, int new_columns)
+{
+
+ if (cuY > new_lines-1)
+ { // attempt to preserve focus and lines
+ bmargin = lines-1; //FIXME: margin lost
+ for (int i = 0; i < cuY-(new_lines-1); i++)
+ {
+ addHistLine(); scrollUp(0,1);
+ }
+ }
+
+ // make new image
+ ca* newimg = (ca*)malloc(new_lines*new_columns*sizeof(ca));
+
+ clearSelection();
+
+ // clear new image
+ for (int y = 0; y < new_lines; y++)
+ for (int x = 0; x < new_columns; x++)
+ {
+ newimg[y*new_columns+x].c = ' ';
+ newimg[y*new_columns+x].f = DEFAULT_FORE_COLOR;
+ newimg[y*new_columns+x].b = DEFAULT_BACK_COLOR;
+ newimg[y*new_columns+x].r = DEFAULT_RENDITION;
+ }
+ int cpy_lines = QMIN(new_lines, lines);
+ int cpy_columns = QMIN(new_columns,columns);
+ // copy to new image
+ for (int y = 0; y < cpy_lines; y++)
+ for (int x = 0; x < cpy_columns; x++)
+ {
+ newimg[y*new_columns+x].c = image[loc(x,y)].c;
+ newimg[y*new_columns+x].f = image[loc(x,y)].f;
+ newimg[y*new_columns+x].b = image[loc(x,y)].b;
+ newimg[y*new_columns+x].r = image[loc(x,y)].r;
+ }
+ free(image);
+ image = newimg;
+ lines = new_lines;
+ columns = new_columns;
+ cuX = QMIN(cuX,columns-1);
+ cuY = QMIN(cuY,lines-1);
+
+ // FIXME: try to keep values, evtl.
+ tmargin=0;
+ bmargin=lines-1;
+ initTabStops();
+ clearSelection();
+}
+
+/*
+ Clarifying rendition here and in TEWidget.
+
+ currently, TEWidget's color table is
+ 0 1 2 .. 9 10 .. 17
+ dft_fg, dft_bg, dim 0..7, intensive 0..7
+
+ cu_fg, cu_bg contain values 0..8;
+ - 0 = default color
+ - 1..8 = ansi specified color
+
+ re_fg, re_bg contain values 0..17
+ due to the TEWidget's color table
+
+ rendition attributes are
+
+ attr widget screen
+ -------------- ------ ------
+ RE_UNDERLINE XX XX affects foreground only
+ RE_BLINK XX XX affects foreground only
+ RE_BOLD XX XX affects foreground only
+ RE_REVERSE -- XX
+ RE_TRANSPARENT XX -- affects background only
+ RE_INTENSIVE XX -- affects foreground only
+
+ Note that RE_BOLD is used in both widget
+ and screen rendition. Since xterm/vt102
+ is to poor to distinguish between bold
+ (which is a font attribute) and intensive
+ (which is a color attribute), we translate
+ this and RE_BOLD in falls eventually appart
+ into RE_BOLD and RE_INTENSIVE.
+*/
+
+void TEScreen::reverseRendition(ca* p)
+{ UINT8 f = p->f; UINT8 b = p->b;
+ p->f = b; p->b = f; //p->r &= ~RE_TRANSPARENT;
+}
+
+void TEScreen::effectiveRendition()
+// calculate rendition
+{
+ ef_re = cu_re & (RE_UNDERLINE | RE_BLINK);
+ if (cu_re & RE_REVERSE)
+ {
+ ef_fg = cu_bg;
+ ef_bg = cu_fg;
+ }
+ else
+ {
+ ef_fg = cu_fg;
+ ef_bg = cu_bg;
+ }
+ if (cu_re & RE_BOLD)
+ {
+ if (ef_fg < BASE_COLORS)
+ ef_fg += BASE_COLORS;
+ else
+ ef_fg -= BASE_COLORS;
+ }
+}
+
+/*!
+ returns the image.
+
+ Get the size of the image by \sa getLines and \sa getColumns.
+
+ NOTE that the image returned by this function must later be
+ freed.
+
+*/
+
+ca* TEScreen::getCookedImage()
+{ int x,y;
+ ca* merged = (ca*)malloc(lines*columns*sizeof(ca));
+ ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION);
+
+ for (y = 0; (y < lines) && (y < (hist.getLines()-histCursor)); y++)
+ {
+ int len = QMIN(columns,hist.getLineLen(y+histCursor));
+ int yp = y*columns;
+ int yq = (y+histCursor)*columns;
+
+ hist.getCells(y+histCursor,0,len,merged+yp);
+ for (x = len; x < columns; x++) merged[yp+x] = dft;
+ for (x = 0; x < columns; x++)
+ { int p=x + yp; int q=x + yq;
+ if ( ( q >= sel_TL ) && ( q <= sel_BR ) )
+ reverseRendition(&merged[p]); // for selection
+ }
+ }
+ if (lines >= hist.getLines()-histCursor)
+ {
+ for (y = (hist.getLines()-histCursor); y < lines ; y++)
+ {
+ int yp = y*columns;
+ int yq = (y+histCursor)*columns;
+ int yr = (y-hist.getLines()+histCursor)*columns;
+ for (x = 0; x < columns; x++)
+ { int p = x + yp; int q = x + yq; int r = x + yr;
+ merged[p] = image[r];
+ if ( q >= sel_TL && q <= sel_BR )
+ reverseRendition(&merged[p]); // for selection
+ }
+
+ }
+ }
+ // evtl. inverse display
+ if (getMode(MODE_Screen))
+ { int i,n = lines*columns;
+ for (i = 0; i < n; i++)
+ reverseRendition(&merged[i]); // for reverse display
+ }
+ if (getMode(MODE_Cursor) && (cuY+(hist.getLines()-histCursor) < lines)) // cursor visible
+ reverseRendition(&merged[loc(cuX,cuY+(hist.getLines()-histCursor))]);
+ return merged;
+}
+
+
+/*!
+*/
+
+void TEScreen::reset()
+{
+ setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin
+ resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1]
+ resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke
+ setMode(MODE_Cursor); // cursor visible
+ resetMode(MODE_Screen); // screen not inverse
+ resetMode(MODE_NewLine);
+
+ tmargin=0;
+ bmargin=lines-1;
+
+ setDefaultRendition();
+ saveCursor();
+
+ clear();
+}
+
+/*! Clear the entire screen and home the cursor.
+*/
+
+void TEScreen::clear()
+{
+ clearEntireScreen();
+ home();
+}
+
+/*! Moves the cursor left one column.
+*/
+
+void TEScreen::BackSpace()
+{
+ cuX = QMAX(0,cuX-1);
+ if (BS_CLEARS) image[loc(cuX,cuY)].c = ' ';
+}
+
+/*!
+*/
+
+void TEScreen::Tabulate()
+{
+ // note that TAB is a format effector (does not write ' ');
+ cursorRight(1); while(cuX < columns-1 && !tabstops[cuX]) cursorRight(1);
+}
+
+void TEScreen::clearTabStops()
+{
+ for (int i = 0; i < columns; i++) tabstops[i-1] = FALSE;
+}
+
+void TEScreen::changeTabStop(bool set)
+{
+ if (cuX >= columns) return;
+ tabstops[cuX] = set;
+}
+
+void TEScreen::initTabStops()
+{
+ if (tabstops) free(tabstops);
+ tabstops = (bool*)malloc(columns*sizeof(bool));
+ // Arrg! The 1st tabstop has to be one longer than the other.
+ // i.e. the kids start counting from 0 instead of 1.
+ // Other programs might behave correctly. Be aware.
+ for (int i = 0; i < columns; i++) tabstops[i] = (i%8 == 0 && i != 0);
+}
+
+/*!
+ This behaves either as IND (Screen::Index) or as NEL (Screen::NextLine)
+ depending on the NewLine Mode (LNM). This mode also
+ affects the key sequence returned for newline ([CR]LF).
+*/
+
+void TEScreen::NewLine()
+{
+ if (getMode(MODE_NewLine)) Return();
+ index();
+}
+
+/*! put `c' literally onto the screen at the current cursor position.
+
+ VT100 uses the convention to produce an automatic newline (am)
+ with the *first* character that would fall onto the next line (xenl).
+*/
+
+void TEScreen::checkSelection(int from, int to)
+{
+ if (sel_begin == -1) return;
+ int scr_TL = loc(0, hist.getLines());
+ //Clear entire selection if it overlaps region [from, to]
+ if ( (sel_BR > (from+scr_TL) )&&(sel_TL < (to+scr_TL)) )
+ {
+ clearSelection();
+ }
+}
+
+void TEScreen::ShowCharacter(unsigned short c)
+{
+ // Note that VT100 does wrapping BEFORE putting the character.
+ // This has impact on the assumption of valid cursor positions.
+ // We indicate the fact that a newline has to be triggered by
+ // putting the cursor one right to the last column of the screen.
+
+ if (cuX >= columns)
+ {
+ if (getMode(MODE_Wrap)) NextLine(); else cuX = columns-1;
+ }
+
+ if (getMode(MODE_Insert)) insertChars(1);
+
+ int i = loc(cuX,cuY);
+
+ checkSelection(i, i); // check if selection is still valid.
+
+ image[i].c = c;
+ image[i].f = ef_fg;
+ image[i].b = ef_bg;
+ image[i].r = ef_re;
+
+ cuX += 1;
+}
+
+// Region commands -------------------------------------------------------------
+
+
+/*! scroll up `n' lines within current region.
+ The `n' new lines are cleared.
+ \sa setRegion \sa scrollDown
+*/
+
+void TEScreen::scrollUp(int from, int n)
+{
+ if (n <= 0 || from + n > bmargin) return;
+ //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
+ moveImage(loc(0,from),loc(0,from+n),loc(columns-1,bmargin));
+ clearImage(loc(0,bmargin-n+1),loc(columns-1,bmargin),' ');
+}
+
+/*! scroll down `n' lines within current region.
+ The `n' new lines are cleared.
+ \sa setRegion \sa scrollUp
+*/
+
+void TEScreen::scrollDown(int from, int n)
+{
+//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
+ if (n <= 0) return;
+ if (from > bmargin) return;
+ if (from + n > bmargin) n = bmargin - from;
+ moveImage(loc(0,from+n),loc(0,from),loc(columns-1,bmargin-n));
+ clearImage(loc(0,from),loc(columns-1,from+n-1),' ');
+}
+
+/*! position the cursor to a specific line and column. */
+void TEScreen::setCursorYX(int y, int x)
+{
+ setCursorY(y); setCursorX(x);
+}
+
+/*! Set the cursor to x-th line. */
+
+void TEScreen::setCursorX(int x)
+{
+ if (x == 0) x = 1; // Default
+ x -= 1; // Adjust
+ cuX = QMAX(0,QMIN(columns-1, x));
+}
+
+/*! Set the cursor to y-th line. */
+
+void TEScreen::setCursorY(int y)
+{
+ if (y == 0) y = 1; // Default
+ y -= 1; // Adjust
+ cuY = QMAX(0,QMIN(lines -1, y + (getMode(MODE_Origin) ? tmargin : 0) ));
+}
+
+/*! set cursor to the `left upper' corner of the screen (1,1).
+*/
+
+void TEScreen::home()
+{
+ cuX = 0;
+ cuY = 0;
+}
+
+/*! set cursor to the begin of the current line.
+*/
+
+void TEScreen::Return()
+{
+ cuX = 0;
+}
+
+/*! returns the current cursor columns.
+*/
+
+int TEScreen::getCursorX()
+{
+ return cuX;
+}
+
+/*! returns the current cursor line.
+*/
+
+int TEScreen::getCursorY()
+{
+ return cuY;
+}
+
+// Erasing ---------------------------------------------------------------------
+
+/*! \section Erasing
+
+ This group of operations erase parts of the screen contents by filling
+ it with spaces colored due to the current rendition settings.
+
+ Althought the cursor position is involved in most of these operations,
+ it is never modified by them.
+*/
+
+/*! fill screen between (including) `loca' and `loce' with spaces.
+
+ This is an internal helper functions. The parameter types are internal
+ addresses of within the screen image and make use of the way how the
+ screen matrix is mapped to the image vector.
+*/
+
+void TEScreen::clearImage(int loca, int loce, char c)
+{ int i;
+ int scr_TL=loc(0,hist.getLines());
+ //FIXME: check positions
+
+ //Clear entire selection if it overlaps region to be moved...
+ if ( (sel_BR > (loca+scr_TL) )&&(sel_TL < (loce+scr_TL)) )
+ {
+ clearSelection();
+ }
+ for (i = loca; i <= loce; i++)
+ {
+ image[i].c = c;
+ image[i].f = ef_fg; //DEFAULT_FORE_COLOR; //FIXME: xterm and linux/ansi
+ image[i].b = ef_bg; //DEFAULT_BACK_COLOR; // many have different
+ image[i].r = ef_re; //DEFAULT_RENDITION; // ideas here.
+ }
+}
+
+/*! move image between (including) `loca' and `loce' to 'dst'.
+
+ This is an internal helper functions. The parameter types are internal
+ addresses of within the screen image and make use of the way how the
+ screen matrix is mapped to the image vector.
+*/
+
+void TEScreen::moveImage(int dst, int loca, int loce)
+{
+//FIXME: check positions
+ if (loce < loca) {
+ // kdDebug() << "WARNING!!! call to TEScreen:moveImage with loce < loca!" << endl;
+ return;
+ }
+ memmove(&image[dst],&image[loca],(loce-loca+1)*sizeof(ca));
+}
+
+/*! clear from (including) current cursor position to end of screen.
+*/
+
+void TEScreen::clearToEndOfScreen()
+{
+ clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' ');
+}
+
+/*! clear from begin of screen to (including) current cursor position.
+*/
+
+void TEScreen::clearToBeginOfScreen()
+{
+ clearImage(loc(0,0),loc(cuX,cuY),' ');
+}
+
+/*! clear the entire screen.
+*/
+
+void TEScreen::clearEntireScreen()
+{
+ clearImage(loc(0,0),loc(columns-1,lines-1),' ');
+}
+
+/*! fill screen with 'E'
+ This is to aid screen alignment
+*/
+
+void TEScreen::helpAlign()
+{
+ clearImage(loc(0,0),loc(columns-1,lines-1),'E');
+}
+
+/*! clear from (including) current cursor position to end of current cursor line.
+*/
+
+void TEScreen::clearToEndOfLine()
+{
+ clearImage(loc(cuX,cuY),loc(columns-1,cuY),' ');
+}
+
+/*! clear from begin of current cursor line to (including) current cursor position.
+*/
+
+void TEScreen::clearToBeginOfLine()
+{
+ clearImage(loc(0,cuY),loc(cuX,cuY),' ');
+}
+
+/*! clears entire current cursor line
+*/
+
+void TEScreen::clearEntireLine()
+{
+ clearImage(loc(0,cuY),loc(columns-1,cuY),' ');
+}
+
+// Rendition ------------------------------------------------------------------
+
+/*!
+ set rendition mode
+*/
+
+void TEScreen::setRendition(int re)
+{
+ cu_re |= re;
+ effectiveRendition();
+}
+
+/*!
+ reset rendition mode
+*/
+
+void TEScreen::resetRendition(int re)
+{
+ cu_re &= ~re;
+ effectiveRendition();
+}
+
+/*!
+*/
+
+void TEScreen::setDefaultRendition()
+{
+ setForeColorToDefault();
+ setBackColorToDefault();
+ cu_re = DEFAULT_RENDITION;
+ effectiveRendition();
+}
+
+/*!
+*/
+
+void TEScreen::setForeColor(int fgcolor)
+{
+ cu_fg = (fgcolor&7)+((fgcolor&8) ? 4+8 : 2);
+ effectiveRendition();
+}
+
+/*!
+*/
+
+void TEScreen::setBackColor(int bgcolor)
+{
+ cu_bg = (bgcolor&7)+((bgcolor&8) ? 4+8 : 2);
+ effectiveRendition();
+}
+
+/*!
+*/
+
+void TEScreen::setBackColorToDefault()
+{
+ cu_bg = DEFAULT_BACK_COLOR;
+ effectiveRendition();
+}
+
+/*!
+*/
+
+void TEScreen::setForeColorToDefault()
+{
+ cu_fg = DEFAULT_FORE_COLOR;
+ effectiveRendition();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Marking & Selection */
+/* */
+/* ------------------------------------------------------------------------- */
+
+void TEScreen::clearSelection()
+{
+ sel_BR = -1;
+ sel_TL = -1;
+ sel_begin = -1;
+}
+
+void TEScreen::setSelBeginXY(const int x, const int y)
+{
+ sel_begin = loc(x,y+histCursor) ;
+ sel_BR = sel_begin;
+ sel_TL = sel_begin;
+}
+
+void TEScreen::setSelExtentXY(const int x, const int y)
+{
+ if (sel_begin == -1) return;
+ int l = loc(x,y + histCursor);
+
+ if (l < sel_begin)
+ {
+ sel_TL = l;
+ sel_BR = sel_begin;
+ }
+ else
+ {
+ /* FIXME, HACK to correct for x too far to the right... */
+ if (( x == columns )|| (x == 0)) l--;
+
+ sel_TL = sel_begin;
+ sel_BR = l;
+ }
+}
+
+QString TEScreen::getSelText(const BOOL preserve_line_breaks)
+{
+ if (sel_begin == -1)
+ return QString::null; // Selection got clear while selecting.
+
+ int *m; // buffer to fill.
+ int s, d; // source index, dest. index.
+ int hist_BR = loc(0, hist.getLines());
+ int hY = sel_TL / columns;
+ int hX = sel_TL % columns;
+ int eol; // end of line
+
+ s = sel_TL; // tracks copy in source.
+
+ // allocate buffer for maximum
+ // possible size...
+ d = (sel_BR - sel_TL) / columns + 1;
+ m = new int[d * (columns + 1) + 2];
+ d = 0;
+
+ while (s <= sel_BR)
+ {
+ if (s < hist_BR)
+ { // get lines from hist.history
+ // buffer.
+ eol = hist.getLineLen(hY);
+
+ if ((hY == (sel_BR / columns)) &&
+ (eol >= (sel_BR % columns)))
+ {
+ eol = sel_BR % columns + 1;
+ }
+
+ while (hX < eol)
+ {
+ m[d++] = hist.getCell(hY, hX++).c;
+ s++;
+ }
+
+ if (s <= sel_BR)
+ {
+ // The line break handling
+ // It's different from the screen
+ // image case!
+ if (eol % columns == 0)
+ {
+ // That's either a completely filled
+ // line or an empty line
+ if (eol == 0)
+ {
+ m[d++] = '\n';
+ }
+ else
+ {
+ // We have a full line.
+ // FIXME: How can we handle newlines
+ // at this position?!
+ }
+ }
+ else if ((eol + 1) % columns == 0)
+ {
+ // FIXME: We don't know if this was a
+ // space at the last position or a
+ // short line!!
+ m[d++] = ' ';
+ }
+ else
+ {
+ // We have a short line here. Put a
+ // newline or a space into the
+ // buffer.
+ m[d++] = preserve_line_breaks ? '\n' : ' ';
+ }
+ }
+
+ hY++;
+ hX = 0;
+ s = hY * columns;
+ }
+ else
+ { // or from screen image.
+ eol = (s / columns + 1) * columns - 1;
+
+ if (eol < sel_BR)
+ {
+ while ((eol > s) &&
+ isspace(image[eol - hist_BR].c))
+ {
+ eol--;
+ }
+ }
+ else
+ {
+ eol = sel_BR;
+ }
+
+ while (s <= eol)
+ {
+ m[d++] = image[s++ - hist_BR].c;
+ }
+
+ if (eol < sel_BR)
+ {
+ // eol processing see below ...
+ if ((eol + 1) % columns == 0)
+ {
+ if (image[eol - hist_BR].c == ' ')
+ {
+ m[d++] = ' ';
+ }
+ }
+ else
+ {
+ m[d++] = ((preserve_line_breaks ||
+ ((eol % columns) == 0)) ?
+ '\n' : ' ');
+ }
+ }
+
+ s = (eol / columns + 1) * columns;
+ }
+ }
+
+ QChar* qc = new QChar[d];
+
+ for (int i = 0; i < d; i++)
+ {
+ qc[i] = m[i];
+ }
+
+ QString res(qc, d);
+
+ delete m;
+ delete qc;
+
+ return res;
+}
+/* above ... end of line processing for selection -- psilva
+cases:
+
+1) (eol+1)%columns == 0 --> the whole line is filled.
+ If the last char is a space, insert (preserve) space. otherwise
+ leave the text alone, so that words that are broken by linewrap
+ are preserved.
+
+FIXME:
+ * this suppresses \n for command output that is
+ sized to the exact column width of the screen.
+
+2) eol%columns == 0 --> blank line.
+ insert a \n unconditionally.
+ Do it either you would because you are in preserve_line_break mode,
+ or because it's an ASCII paragraph delimiter, so even when
+ not preserving line_breaks, you want to preserve paragraph breaks.
+
+3) else --> partially filled line
+ insert a \n in preserve line break mode, else a space
+ The space prevents concatenation of the last word of one
+ line with the first of the next.
+
+*/
+
+void TEScreen::addHistLine()
+{
+ assert(hasScroll() || histCursor == 0);
+
+ // add to hist buffer
+ // we have to take care about scrolling, too...
+
+ if (hasScroll())
+ { ca dft;
+
+ int end = columns-1;
+ while (end >= 0 && image[end] == dft)
+ end -= 1;
+
+ hist.addCells(image,end+1);
+ hist.addLine();
+
+ // adjust history cursor
+ histCursor += (hist.getLines()-1 == histCursor);
+ }
+
+ if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround
+}
+
+void TEScreen::setHistCursor(int cursor)
+{
+ histCursor = cursor; //FIXME:rangecheck
+}
+
+int TEScreen::getHistCursor()
+{
+ return histCursor;
+}
+
+int TEScreen::getHistLines()
+{
+ return hist.getLines();
+}
+
+void TEScreen::setScroll(bool on)
+{
+ histCursor = 0;
+ clearSelection();
+ hist.setScroll(on);
+}
+
+bool TEScreen::hasScroll()
+{
+ return hist.hasScroll();
+}
diff --git a/core/apps/embeddedkonsole/TEScreen.h b/core/apps/embeddedkonsole/TEScreen.h
new file mode 100644
index 0000000..ba47ee5
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEScreen.h
@@ -0,0 +1,259 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [te_screen.h] Screen Data Type */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef TESCREEN_H
+#define TESCREEN_H
+
+/*! \file
+*/
+
+#include "TECommon.h"
+#include "TEHistory.h"
+
+#define MODE_Origin 0
+#define MODE_Wrap 1
+#define MODE_Insert 2
+#define MODE_Screen 3
+#define MODE_Cursor 4
+#define MODE_NewLine 5
+#define MODES_SCREEN 6
+
+/*!
+*/
+struct ScreenParm
+{
+ int mode[MODES_SCREEN];
+};
+
+
+class TEScreen
+{
+public:
+ TEScreen(int lines, int columns);
+ ~TEScreen();
+
+public: // these are all `Screen' operations
+ //
+ // VT100/2 Operations ------------------
+ //
+ // Cursor Movement
+ //
+ void cursorUp (int n);
+ void cursorDown (int n);
+ void cursorLeft (int n);
+ void cursorRight (int n);
+ void setCursorY (int y);
+ void setCursorX (int x);
+ void setCursorYX (int y, int x);
+ void setMargins (int t, int b);
+ //
+ // Cursor Movement with Scrolling
+ //
+ void NewLine ();
+ void NextLine ();
+ void index ();
+ void reverseIndex();
+ //
+ void Return ();
+ void BackSpace ();
+ void Tabulate ();
+ //
+ // Editing
+ //
+ void eraseChars (int n);
+ void deleteChars (int n);
+ void insertChars (int n);
+ void deleteLines (int n);
+ void insertLines (int n);
+ //
+ // -------------------------------------
+ //
+ void clearTabStops();
+ void changeTabStop(bool set);
+ //
+ void resetMode (int n);
+ void setMode (int n);
+ void saveMode (int n);
+ void restoreMode (int n);
+ //
+ void saveCursor ();
+ void restoreCursor();
+ //
+ // -------------------------------------
+ //
+ void clearEntireScreen();
+ void clearToEndOfScreen();
+ void clearToBeginOfScreen();
+ //
+ void clearEntireLine();
+ void clearToEndOfLine();
+ void clearToBeginOfLine();
+ //
+ void helpAlign ();
+ //
+ // -------------------------------------
+ //
+ void setRendition (int rendition);
+ void resetRendition(int rendition);
+ void setForeColor (int fgcolor);
+ void setBackColor (int bgcolor);
+ //
+ void setDefaultRendition();
+ void setForeColorToDefault();
+ void setBackColorToDefault();
+ //
+ // -------------------------------------
+ //
+ BOOL getMode (int n);
+ //
+ // only for report cursor position
+ //
+ int getCursorX();
+ int getCursorY();
+ //
+ // -------------------------------------
+ //
+ void clear();
+ void home();
+ void reset();
+ //
+ void ShowCharacter(unsigned short c);
+ //
+ void resizeImage(int new_lines, int new_columns);
+ //
+ ca* getCookedImage();
+
+ /*! return the number of lines. */
+ int getLines() { return lines; }
+ /*! return the number of columns. */
+ int getColumns() { return columns; }
+
+ /*! set the position of the history cursor. */
+ void setHistCursor(int cursor);
+ /*! return the position of the history cursor. */
+ int getHistCursor();
+
+ int getHistLines ();
+ void setScroll(bool on);
+ bool hasScroll();
+
+ //
+ // Selection
+ //
+ void setSelBeginXY(const int x, const int y);
+ void setSelExtentXY(const int x, const int y);
+ void clearSelection();
+ QString getSelText(const BOOL preserve_line_breaks);
+
+ void checkSelection(int from, int to);
+
+private: // helper
+
+ void clearImage(int loca, int loce, char c);
+ void moveImage(int dst, int loca, int loce);
+
+ void scrollUp(int from, int i);
+ void scrollDown(int from, int i);
+
+ void addHistLine();
+
+ void initTabStops();
+
+ void effectiveRendition();
+ void reverseRendition(ca* p);
+
+private:
+
+ /*
+ The state of the screen is more complex as one would
+ expect first. The screem does really do part of the
+ emulation providing state informations in form of modes,
+ margins, tabulators, cursor etc.
+
+ Even more unexpected are variables to save and restore
+ parts of the state.
+ */
+
+ // screen image ----------------
+
+ int lines;
+ int columns;
+ ca *image; // [lines][columns]
+
+ // history buffer ---------------
+
+ int histCursor; // display position relative to start of the history buffer
+ HistoryScroll hist;
+
+ // cursor location
+
+ int cuX;
+ int cuY;
+
+ // cursor color and rendition info
+
+ UINT8 cu_fg; // foreground
+ UINT8 cu_bg; // background
+ UINT8 cu_re; // rendition
+
+ // margins ----------------
+
+ int tmargin; // top margin
+ int bmargin; // bottom margin
+
+ // states ----------------
+
+ ScreenParm currParm;
+
+ // ----------------------------
+
+ bool* tabstops;
+
+ // selection -------------------
+
+ int sel_begin; // The first location selected.
+ int sel_TL; // TopLeft Location.
+ int sel_BR; // Bottom Right Location.
+
+ // effective colors and rendition ------------
+
+ UINT8 ef_fg; // These are derived from
+ UINT8 ef_bg; // the cu_* variables above
+ UINT8 ef_re; // to speed up operation
+
+ //
+ // save cursor, rendition & states ------------
+ //
+
+ // cursor location
+
+ int sa_cuX;
+ int sa_cuY;
+
+ // rendition info
+
+ UINT8 sa_cu_re;
+ UINT8 sa_cu_fg;
+ UINT8 sa_cu_bg;
+
+ // modes
+
+ ScreenParm saveParm;
+};
+
+#endif // TESCREEN_H
diff --git a/core/apps/embeddedkonsole/TEWidget.cpp b/core/apps/embeddedkonsole/TEWidget.cpp
new file mode 100644
index 0000000..dc83998
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEWidget.cpp
@@ -0,0 +1,1243 @@
+/* ------------------------------------------------------------------------ */
+/* */
+/* [TEWidget.C] Terminal Emulation Widget */
+/* */
+/* ------------------------------------------------------------------------ */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* ------------------------------------------------------------------------ */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+/*! \class TEWidget
+
+ \brief Visible screen contents
+
+ This class is responsible to map the `image' of a terminal emulation to the
+ display. All the dependency of the emulation to a specific GUI or toolkit is
+ localized here. Further, this widget has no knowledge about being part of an
+ emulation, it simply work within the terminal emulation framework by exposing
+ size and key events and by being ordered to show a new image.
+
+ <ul>
+ <li> The internal image has the size of the widget (evtl. rounded up)
+ <li> The external image used in setImage can have any size.
+ <li> (internally) the external image is simply copied to the internal
+ when a setImage happens. During a resizeEvent no painting is done
+ a paintEvent is expected to follow anyway.
+ </ul>
+
+ \sa TEScreen \sa Emulation
+*/
+
+/* FIXME:
+ - 'image' may also be used uninitialized (it isn't in fact) in resizeEvent
+ - 'font_a' not used in mouse events
+ - add destructor
+*/
+
+/* TODO
+ - evtl. be sensitive to `paletteChange' while using default colors.
+ - set different 'rounding' styles? I.e. have a mode to show clipped chars?
+*/
+
+// #include "config.h"
+#include "TEWidget.h"
+#include "session.h"
+
+#include <qcursor.h>
+#include <qregexp.h>
+#include <qpainter.h>
+#include <qclipboard.h>
+#include <qstyle.h>
+#include <qfile.h>
+#include <qdragobject.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <assert.h>
+
+// #include "TEWidget.moc"
+//#include <kapp.h>
+//#include <kcursor.h>
+//#include <kurl.h>
+//#include <kdebug.h>
+//#include <klocale.h>
+
+#define HERE printf("%s(%d): %s\n",__FILE__,__LINE__,__FUNCTION__)
+#define HCNT(Name) // { static int cnt = 1; printf("%s(%d): %s %d\n",__FILE__,__LINE__,Name,cnt++); }
+
+#define loc(X,Y) ((Y)*columns+(X))
+
+//FIXME: the rim should normally be 1, 0 only when running in full screen mode.
+#define rimX 0 // left/right rim width
+#define rimY 0 // top/bottom rim high
+
+#define SCRWIDTH 16 // width of the scrollbar
+
+#define yMouseScroll 1
+// scroll increment used when dragging selection at top/bottom of window.
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Colors */
+/* */
+/* ------------------------------------------------------------------------- */
+
+//FIXME: the default color table is in session.C now.
+// We need a way to get rid of this one, here.
+static const ColorEntry base_color_table[TABLE_COLORS] =
+// The following are almost IBM standard color codes, with some slight
+// gamma correction for the dim colors to compensate for bright X screens.
+// It contains the 8 ansiterm/xterm colors in 2 intensities.
+{
+ // Fixme: could add faint colors here, also.
+ // normal
+ ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback
+ ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red
+ ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow
+ ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta
+ ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White
+ // intensiv
+ ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ),
+ ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ),
+ ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ),
+ ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0xFF), 0, 0 ),
+ ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 )
+};
+
+/* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb)
+
+ Code 0 1 2 3 4 5 6 7
+ ----------- ------- ------- ------- ------- ------- ------- ------- -------
+ ANSI (bgr) Black Red Green Yellow Blue Magenta Cyan White
+ IBMPC (rgb) Black Blue Green Cyan Red Magenta Yellow White
+*/
+
+QColor TEWidget::getDefaultBackColor()
+{
+ return color_table[DEFAULT_BACK_COLOR].color;
+}
+
+const ColorEntry* TEWidget::getColorTable() const
+{
+ return color_table;
+}
+
+const QPixmap *TEWidget::backgroundPixmap()
+{
+ static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm");
+ const QPixmap *pm = bg;
+ return pm;
+}
+
+void TEWidget::setColorTable(const ColorEntry table[])
+{
+ for (int i = 0; i < TABLE_COLORS; i++) color_table[i] = table[i];
+
+ const QPixmap* pm = backgroundPixmap();
+ if (!pm) setBackgroundColor(color_table[DEFAULT_BACK_COLOR].color);
+ update();
+}
+
+//FIXME: add backgroundPixmapChanged.
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Font */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*
+ The VT100 has 32 special graphical characters. The usual vt100 extended
+ xterm fonts have these at 0x00..0x1f.
+
+ QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals
+ come in here as proper unicode characters.
+
+ We treat non-iso10646 fonts as VT100 extended and do the requiered mapping
+ from unicode to 0x00..0x1f. The remaining translation is then left to the
+ QCodec.
+*/
+
+// assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i.
+
+unsigned short vt100_graphics[32] =
+{ // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15
+ 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0,
+ 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c,
+ 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534,
+ 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7
+};
+
+static QChar vt100extended(QChar c)
+{
+ switch (c.unicode())
+ {
+ case 0x25c6 : return 1;
+ case 0x2592 : return 2;
+ case 0x2409 : return 3;
+ case 0x240c : return 4;
+ case 0x240d : return 5;
+ case 0x240a : return 6;
+ case 0x00b0 : return 7;
+ case 0x00b1 : return 8;
+ case 0x2424 : return 9;
+ case 0x240b : return 10;
+ case 0x2518 : return 11;
+ case 0x2510 : return 12;
+ case 0x250c : return 13;
+ case 0x2514 : return 14;
+ case 0x253c : return 15;
+ case 0xf800 : return 16;
+ case 0xf801 : return 17;
+ case 0x2500 : return 18;
+ case 0xf803 : return 19;
+ case 0xf804 : return 20;
+ case 0x251c : return 21;
+ case 0x2524 : return 22;
+ case 0x2534 : return 23;
+ case 0x252c : return 24;
+ case 0x2502 : return 25;
+ case 0x2264 : return 26;
+ case 0x2265 : return 27;
+ case 0x03c0 : return 28;
+ case 0x2260 : return 29;
+ case 0x00a3 : return 30;
+ case 0x00b7 : return 31;
+ }
+ return c;
+}
+
+static QChar identicalMap(QChar c)
+{
+ return c;
+}
+
+void TEWidget::fontChange(const QFont &)
+{
+ QFontMetrics fm(font());
+ font_h = fm.height();
+ font_w = fm.maxWidth();
+ font_a = fm.ascent();
+//printf("font_h: %d\n",font_h);
+//printf("font_w: %d\n",font_w);
+//printf("font_a: %d\n",font_a);
+//printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii());
+//printf("rawname: %s\n",font().rawName().ascii());
+ fontMap =
+#if QT_VERSION < 300
+ strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646")
+ ? vt100extended
+ :
+#endif
+ identicalMap;
+ propagateSize();
+ update();
+}
+
+void TEWidget::setVTFont(const QFont& f)
+{
+ QFrame::setFont(f);
+}
+
+QFont TEWidget::getVTFont()
+{
+ return font();
+}
+
+void TEWidget::setFont(const QFont &)
+{
+ // ignore font change request if not coming from konsole itself
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Constructor / Destructor */
+/* */
+/* ------------------------------------------------------------------------- */
+
+TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name)
+{
+#ifndef QT_NO_CLIPBOARD
+ cb = QApplication::clipboard();
+ QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
+ this, SLOT(onClearSelection()) );
+#endif
+
+ scrollbar = new QScrollBar(this);
+ scrollbar->setCursor( arrowCursor );
+ connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
+ scrollLoc = SCRNONE;
+
+ blinkT = new QTimer(this);
+ connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent()));
+ // blinking = FALSE;
+ blinking = TRUE;
+
+ resizing = FALSE;
+ actSel = 0;
+ image = 0;
+ lines = 1;
+ columns = 1;
+ font_w = 1;
+ font_h = 1;
+ font_a = 1;
+ word_selection_mode = FALSE;
+
+ setMouseMarks(TRUE);
+ setVTFont( QFont("fixed") );
+ setColorTable(base_color_table); // init color table
+
+ qApp->installEventFilter( this ); //FIXME: see below
+// KCursor::setAutoHideCursor( this, true );
+
+ // Init DnD ////////////////////////////////////////////////////////////////
+ currentSession = NULL;
+// setAcceptDrops(true); // attempt
+// m_drop = new QPopupMenu(this);
+// m_drop->insertItem( QString("Paste"), 0);
+// m_drop->insertItem( QString("cd"), 1);
+// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int)));
+
+ // we need focus so that the auto-hide cursor feature works
+ setFocus();
+ setFocusPolicy( WheelFocus );
+}
+
+//FIXME: make proper destructor
+// Here's a start (David)
+TEWidget::~TEWidget()
+{
+ qApp->removeEventFilter( this );
+ if (image) free(image);
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Display Operations */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*!
+ attributed string draw primitive
+*/
+
+void TEWidget::drawAttrStr(QPainter &paint, QRect rect,
+ QString& str, ca attr, BOOL pm, BOOL clear)
+{
+ if (pm && color_table[attr.b].transparent)
+ {
+ paint.setBackgroundMode( TransparentMode );
+ if (clear) erase(rect);
+ }
+ else
+ {
+ if (blinking)
+ paint.fillRect(rect, color_table[attr.b].color);
+ else
+ {
+ paint.setBackgroundMode( OpaqueMode );
+ paint.setBackgroundColor( color_table[attr.b].color );
+ }
+ }
+
+ if (color_table[attr.f].bold)
+ paint.setPen(QColor( 0x8F, 0x00, 0x00 ));
+ else
+ paint.setPen(color_table[attr.f].color);
+
+ paint.drawText(rect.x(),rect.y()+font_a, str);
+
+ if (attr.r & RE_UNDERLINE)
+ paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 );
+}
+
+/*!
+ The image can only be set completely.
+
+ The size of the new image may or may not match the size of the widget.
+*/
+
+void TEWidget::setImage(const ca* const newimg, int lines, int columns)
+{ int y,x,len;
+ const QPixmap* pm = backgroundPixmap();
+ QPainter paint;
+ setUpdatesEnabled(FALSE);
+ paint.begin( this );
+HCNT("setImage");
+
+ QPoint tL = contentsRect().topLeft();
+ int tLx = tL.x();
+ int tLy = tL.y();
+ hasBlinker = FALSE;
+
+ int cf = -1; // undefined
+ int cb = -1; // undefined
+ int cr = -1; // undefined
+
+ int lins = QMIN(this->lines, QMAX(0,lines ));
+ int cols = QMIN(this->columns,QMAX(0,columns));
+ QChar *disstrU = new QChar[cols];
+
+//{ static int cnt = 0; printf("setImage %d\n",cnt++); }
+ for (y = 0; y < lins; y++)
+ {
+ const ca* lcl = &image[y*this->columns];
+ const ca* const ext = &newimg[y*columns];
+ if (!resizing) // not while resizing, we're expecting a paintEvent
+ for (x = 0; x < cols; x++)
+ {
+ hasBlinker |= (ext[x].r & RE_BLINK);
+ if (ext[x] != lcl[x])
+ {
+ cr = ext[x].r;
+ cb = ext[x].b;
+ if (ext[x].f != cf) cf = ext[x].f;
+ int lln = cols - x;
+ disstrU[0] = fontMap(ext[x+0].c);
+ for (len = 1; len < lln; len++)
+ {
+ if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr ||
+ ext[x+len] == lcl[x+len] )
+ break;
+ disstrU[len] = fontMap(ext[x+len].c);
+ }
+ QString unistr(disstrU,len);
+ drawAttrStr(paint,
+ QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
+ unistr, ext[x], pm != NULL, true);
+ x += len - 1;
+ }
+ }
+ // finally, make `image' become `newimg'.
+ memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca));
+ }
+ drawFrame( &paint );
+ paint.end();
+ setUpdatesEnabled(TRUE);
+ if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms
+ if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; }
+ delete [] disstrU;
+}
+
+// paint Event ////////////////////////////////////////////////////
+
+/*!
+ The difference of this routine vs. the `setImage' is,
+ that the drawing does not include a difference analysis
+ between the old and the new image. Instead, the internal
+ image is used and the painting bound by the PaintEvent box.
+*/
+
+void TEWidget::paintEvent( QPaintEvent* pe )
+{
+
+//{ static int cnt = 0; printf("paint %d\n",cnt++); }
+ const QPixmap* pm = backgroundPixmap();
+ QPainter paint;
+ setUpdatesEnabled(FALSE);
+ paint.begin( this );
+ paint.setBackgroundMode( TransparentMode );
+HCNT("paintEvent");
+
+ // Note that the actual widget size can be slightly larger
+ // that the image (the size is truncated towards the smaller
+ // number of characters in `resizeEvent'. The paint rectangle
+ // can thus be larger than the image, but less then the size
+ // of one character.
+
+ QRect rect = pe->rect().intersect(contentsRect());
+
+ QPoint tL = contentsRect().topLeft();
+ int tLx = tL.x();
+ int tLy = tL.y();
+
+ int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w));
+ int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h));
+ int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w));
+ int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h));
+
+ /*
+ printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly,
+ rect.left(), rect.right(), rect.top(), rect.bottom());
+ */
+
+ // if (pm != NULL && color_table[image->b].transparent)
+ // erase(rect);
+ // BL: I have no idea why we need this, and it breaks the refresh.
+
+ QChar *disstrU = new QChar[columns];
+ for (int y = luy; y <= rly; y++)
+ for (int x = lux; x <= rlx; x++)
+ {
+ int len = 1;
+ disstrU[0] = fontMap(image[loc(x,y)].c);
+ int cf = image[loc(x,y)].f;
+ int cb = image[loc(x,y)].b;
+ int cr = image[loc(x,y)].r;
+ while (x+len <= rlx &&
+ image[loc(x+len,y)].f == cf &&
+ image[loc(x+len,y)].b == cb &&
+ image[loc(x+len,y)].r == cr )
+ {
+ disstrU[len] = fontMap(image[loc(x+len,y)].c);
+ len += 1;
+ }
+ QString unistr(disstrU,len);
+ drawAttrStr(paint,
+ QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
+ unistr, image[loc(x,y)], pm != NULL, false);
+ x += len - 1;
+ }
+ delete [] disstrU;
+ drawFrame( &paint );
+ paint.end();
+ setUpdatesEnabled(TRUE);
+}
+
+void TEWidget::blinkEvent()
+{
+ blinking = !blinking;
+ repaint(FALSE);
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Resizing */
+/* */
+/* ------------------------------------------------------------------------- */
+
+void TEWidget::resizeEvent(QResizeEvent* ev)
+{
+ //printf("resize: %d,%d\n",ev->size().width(),ev->size().height());
+ //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h);
+ //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h);
+ //printf("curren: %d,%d\n",width(),height());
+HCNT("resizeEvent");
+
+ // see comment in `paintEvent' concerning the rounding.
+ //FIXME: could make a routine here; check width(),height()
+ assert(ev->size().width() == width());
+ assert(ev->size().height() == height());
+
+ propagateSize();
+}
+
+void TEWidget::propagateSize()
+{
+ ca* oldimg = image;
+ int oldlin = lines;
+ int oldcol = columns;
+ makeImage();
+ // we copy the old image to reduce flicker
+ int lins = QMIN(oldlin,lines);
+ int cols = QMIN(oldcol,columns);
+ if (oldimg)
+ {
+ for (int lin = 0; lin < lins; lin++)
+ memcpy((void*)&image[columns*lin],
+ (void*)&oldimg[oldcol*lin],cols*sizeof(ca));
+ free(oldimg); //FIXME: try new,delete
+ }
+ else
+ clearImage();
+
+ //NOTE: control flows from the back through the chest right into the eye.
+ // `emu' will call back via `setImage'.
+
+ resizing = TRUE;
+ emit changedImageSizeSignal(lines, columns); // expose resizeEvent
+ resizing = FALSE;
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Scrollbar */
+/* */
+/* ------------------------------------------------------------------------- */
+
+void TEWidget::scrollChanged(int)
+{
+ emit changedHistoryCursor(scrollbar->value()); //expose
+}
+
+void TEWidget::setScroll(int cursor, int slines)
+{
+ disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
+ scrollbar->setRange(0,slines);
+ scrollbar->setSteps(1,lines);
+ scrollbar->setValue(cursor);
+ connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
+}
+
+void TEWidget::setScrollbarLocation(int loc)
+{
+ if (scrollLoc == loc) return; // quickly
+ scrollLoc = loc;
+ propagateSize();
+ update();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Mouse */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*!
+ Three different operations can be performed using the mouse, and the
+ routines in this section serve all of them:
+
+ 1) The press/release events are exposed to the application
+ 2) Marking (press and move left button) and Pasting (press middle button)
+ 3) The right mouse button is used from the configuration menu
+
+ NOTE: During the marking process we attempt to keep the cursor within
+ the bounds of the text as being displayed by setting the mouse position
+ whenever the mouse has left the text area.
+
+ Two reasons to do so:
+ 1) QT does not allow the `grabMouse' to confine-to the TEWidget.
+ Thus a `XGrapPointer' would have to be used instead.
+ 2) Even if so, this would not help too much, since the text area
+ of the TEWidget is normally not identical with it's bounds.
+
+ The disadvantage of the current handling is, that the mouse can visibly
+ leave the bounds of the widget and is then moved back. Because of the
+ current construction, and the reasons mentioned above, we cannot do better
+ without changing the overall construction.
+*/
+
+/*!
+*/
+
+void TEWidget::mousePressEvent(QMouseEvent* ev)
+{
+//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
+ if ( !contentsRect().contains(ev->pos()) ) return;
+ QPoint tL = contentsRect().topLeft();
+ int tLx = tL.x();
+ int tLy = tL.y();
+
+ word_selection_mode = FALSE;
+
+//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY);
+ if ( ev->button() == LeftButton)
+ {
+ QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
+
+ if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ;
+
+ if (mouse_marks || (ev->state() & ShiftButton))
+ {
+ emit clearSelectionSignal();
+ iPntSel = pntSel = pos;
+ actSel = 1; // left mouse button pressed but nothing selected yet.
+ grabMouse( /*crossCursor*/ ); // handle with care!
+ }
+ else
+ {
+ emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button
+ }
+ }
+ if ( ev->button() == MidButton )
+ {
+ emitSelection();
+ }
+ if ( ev->button() == RightButton ) // Configure
+ {
+ emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() );
+ }
+}
+
+void TEWidget::mouseMoveEvent(QMouseEvent* ev)
+{
+ // for auto-hiding the cursor, we need mouseTracking
+ if (ev->state() == NoButton ) return;
+
+ if (actSel == 0) return;
+
+ // don't extend selection while pasting
+ if (ev->state() & MidButton) return;
+
+ //if ( !contentsRect().contains(ev->pos()) ) return;
+ QPoint tL = contentsRect().topLeft();
+ int tLx = tL.x();
+ int tLy = tL.y();
+ int scroll = scrollbar->value();
+
+ // we're in the process of moving the mouse with the left button pressed
+ // the mouse cursor will kept catched within the bounds of the text in
+ // this widget.
+
+ // Adjust position within text area bounds. See FIXME above.
+ QPoint pos = ev->pos();
+ if ( pos.x() < tLx+blX ) pos.setX( tLx+blX );
+ if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w );
+ if ( pos.y() < tLy+bY ) pos.setY( tLy+bY );
+ if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 );
+ // check if we produce a mouse move event by this
+ if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos));
+
+ if ( pos.y() == tLy+bY+lines*font_h-1 )
+ {
+ scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward
+ }
+ if ( pos.y() == tLy+bY )
+ {
+ scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback
+ }
+
+ QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h);
+ QPoint ohere;
+ bool swapping = FALSE;
+
+ if ( word_selection_mode )
+ {
+ // Extend to word boundaries
+ int i;
+ int selClass;
+
+ bool left_not_right = ( here.y() < iPntSel.y() ||
+ here.y() == iPntSel.y() && here.x() < iPntSel.x() );
+ bool old_left_not_right = ( pntSel.y() < iPntSel.y() ||
+ pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() );
+ swapping = left_not_right != old_left_not_right;
+
+ // Find left (left_not_right ? from here : from start)
+ QPoint left = left_not_right ? here : iPntSel;
+ i = loc(left.x(),left.y());
+ selClass = charClass(image[i].c);
+ while ( left.x() > 0 && charClass(image[i-1].c) == selClass )
+ { i--; left.rx()--; }
+
+ // Find left (left_not_right ? from start : from here)
+ QPoint right = left_not_right ? iPntSel : here;
+ i = loc(right.x(),right.y());
+ selClass = charClass(image[i].c);
+ while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass )
+ { i++; right.rx()++; }
+
+ // Pick which is start (ohere) and which is extension (here)
+ if ( left_not_right )
+ {
+ here = left; ohere = right;
+ }
+ else
+ {
+ here = right; ohere = left;
+ }
+ }
+
+ if (here == pntSel && scroll == scrollbar->value()) return; // not moved
+
+ if ( word_selection_mode ) {
+ if ( actSel < 2 || swapping ) {
+ emit beginSelectionSignal( ohere.x(), ohere.y() );
+ }
+ } else if ( actSel < 2 ) {
+ emit beginSelectionSignal( pntSel.x(), pntSel.y() );
+ }
+
+ actSel = 2; // within selection
+ pntSel = here;
+ emit extendSelectionSignal( here.x(), here.y() );
+}
+
+void TEWidget::mouseReleaseEvent(QMouseEvent* ev)
+{
+//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
+ if ( ev->button() == LeftButton)
+ {
+ if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks);
+ preserve_line_breaks = TRUE;
+ actSel = 0;
+
+ //FIXME: emits a release event even if the mouse is
+ // outside the range. The procedure used in `mouseMoveEvent'
+ // applies here, too.
+
+ QPoint tL = contentsRect().topLeft();
+ int tLx = tL.x();
+ int tLy = tL.y();
+
+ if (!mouse_marks && !(ev->state() & ShiftButton))
+ emit mouseSignal( 3, // release
+ (ev->x()-tLx-blX)/font_w + 1,
+ (ev->y()-tLy-bY)/font_h + 1 );
+ releaseMouse();
+ }
+}
+
+void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev)
+{
+ if ( ev->button() != LeftButton) return;
+
+ QPoint tL = contentsRect().topLeft();
+ int tLx = tL.x();
+ int tLy = tL.y();
+ QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
+
+ // pass on double click as two clicks.
+ if (!mouse_marks && !(ev->state() & ShiftButton))
+ {
+ emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
+ emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release
+ emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
+ return;
+ }
+
+
+ emit clearSelectionSignal();
+ QPoint bgnSel = pos;
+ QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
+ int i = loc(bgnSel.x(),bgnSel.y());
+ iPntSel = bgnSel;
+
+ word_selection_mode = TRUE;
+
+ // find word boundaries...
+ int selClass = charClass(image[i].c);
+ {
+ // set the start...
+ int x = bgnSel.x();
+ while ( x > 0 && charClass(image[i-1].c) == selClass )
+ { i--; x--; }
+ bgnSel.setX(x);
+ emit beginSelectionSignal( bgnSel.x(), bgnSel.y() );
+
+ // set the end...
+ i = loc( endSel.x(), endSel.y() );
+ x = endSel.x();
+ while( x < columns-1 && charClass(image[i+1].c) == selClass )
+ { i++; x++ ; }
+ endSel.setX(x);
+ actSel = 2; // within selection
+ emit extendSelectionSignal( endSel.x(), endSel.y() );
+ emit endSelectionSignal(preserve_line_breaks);
+ preserve_line_breaks = TRUE;
+ }
+}
+
+void TEWidget::focusInEvent( QFocusEvent * )
+{
+ // do nothing, to prevent repainting
+}
+
+
+void TEWidget::focusOutEvent( QFocusEvent * )
+{
+ // do nothing, to prevent repainting
+}
+
+bool TEWidget::focusNextPrevChild( bool next )
+{
+ if (next)
+ return false; // This disables changing the active part in konqueror
+ // when pressing Tab
+ return QFrame::focusNextPrevChild( next );
+}
+
+
+int TEWidget::charClass(char ch) const
+{
+ // This might seem like overkill, but imagine if ch was a Unicode
+ // character (Qt 2.0 QChar) - it might then be sensible to separate
+ // the different language ranges, etc.
+
+ if ( isspace(ch) ) return ' ';
+
+ static const char *word_characters = ":@-./_~";
+ if ( isalnum(ch) || strchr(word_characters, ch) )
+ return 'a';
+
+ // Everything else is weird
+ return 1;
+}
+
+void TEWidget::setMouseMarks(bool on)
+{
+ mouse_marks = on;
+ setCursor( mouse_marks ? ibeamCursor : arrowCursor );
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Clipboard */
+/* */
+/* ------------------------------------------------------------------------- */
+
+#undef KeyPress
+
+void TEWidget::emitSelection()
+// Paste Clipboard by simulating keypress events
+{
+#ifndef QT_NO_CLIPBOARD
+ QString text = QApplication::clipboard()->text();
+ if ( ! text.isNull() )
+ {
+ text.replace(QRegExp("\n"), "\r");
+ QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
+ emit keyPressedSignal(&e); // expose as a big fat keypress event
+ emit clearSelectionSignal();
+ }
+#endif
+}
+
+void TEWidget::emitText(QString text)
+{
+ QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
+ emit keyPressedSignal(&e); // expose as a big fat keypress event
+}
+
+void TEWidget::pasteClipboard( )
+{
+ emitSelection();
+}
+
+void TEWidget::setSelection(const QString& t)
+{
+#ifndef QT_NO_CLIPBOARD
+ // Disconnect signal while WE set the clipboard
+ QObject *cb = QApplication::clipboard();
+ QObject::disconnect( cb, SIGNAL(dataChanged()),
+ this, SLOT(onClearSelection()) );
+
+ QApplication::clipboard()->setText(t);
+
+ QObject::connect( cb, SIGNAL(dataChanged()),
+ this, SLOT(onClearSelection()) );
+#endif
+}
+
+void TEWidget::onClearSelection()
+{
+ emit clearSelectionSignal();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Keyboard */
+/* */
+/* ------------------------------------------------------------------------- */
+
+//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent'
+// due to a bug in `QT' or the ignorance of the author to prevent
+// repaint events being emitted to the screen whenever one leaves
+// or reenters the screen to/from another application.
+//
+// Troll says one needs to change focusInEvent() and focusOutEvent(),
+// which would also let you have an in-focus cursor and an out-focus
+// cursor like xterm does.
+
+// for the auto-hide cursor feature, I added empty focusInEvent() and
+// focusOutEvent() so that update() isn't called.
+// For auto-hide, we need to get keypress-events, but we only get them when
+// we have focus.
+
+void TEWidget::doScroll(int lines)
+{
+ scrollbar->setValue(scrollbar->value()+lines);
+}
+
+bool TEWidget::eventFilter( QObject *obj, QEvent *e )
+{
+ if ( (e->type() == QEvent::Accel ||
+ e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this )
+ {
+ static_cast<QKeyEvent *>( e )->ignore();
+ return true;
+ }
+ if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ )
+ return FALSE; // not us
+ if ( e->type() == QEvent::Wheel)
+ {
+ QApplication::sendEvent(scrollbar, e);
+ }
+
+#ifdef FAKE_CTRL_AND_ALT
+ static bool control = FALSE;
+ static bool alt = FALSE;
+ // Has a keyboard with no CTRL and ALT keys, but we fake it:
+ bool dele=FALSE;
+ if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
+ QKeyEvent* ke = (QKeyEvent*)e;
+ bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat();
+ switch (ke->key()) {
+ case Key_F9: // let this be "Control"
+ control = keydown;
+ e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state());
+ dele=TRUE;
+ break;
+ case Key_F13: // let this be "Alt"
+ alt = keydown;
+ e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state());
+ dele=TRUE;
+ break;
+ default:
+ if ( control ) {
+ int a = toupper(ke->ascii())-64;
+ if ( a >= 0 && a < ' ' ) {
+ e = new QKeyEvent(e->type(), ke->key(),
+ a, ke->state()|ControlButton, QChar(a,0));
+ dele=TRUE;
+ }
+ }
+ if ( alt ) {
+ e = new QKeyEvent(e->type(), ke->key(),
+ ke->ascii(), ke->state()|AltButton, ke->text());
+ dele=TRUE;
+ }
+ }
+ }
+#endif
+
+ if ( e->type() == QEvent::KeyPress )
+ {
+ QKeyEvent* ke = (QKeyEvent*)e;
+
+ actSel=0; // Key stroke implies a screen update, so TEWidget won't
+ // know where the current selection is.
+
+ emit keyPressedSignal(ke); // expose
+ ke->accept();
+#ifdef FAKE_CTRL_AND_ALT
+ if ( dele ) delete e;
+#endif
+ return true; // stop the event
+ }
+ if ( e->type() == QEvent::Enter )
+ {
+ QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()),
+ this, SLOT(onClearSelection()) );
+ }
+ if ( e->type() == QEvent::Leave )
+ {
+ QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
+ this, SLOT(onClearSelection()) );
+ }
+ return QFrame::eventFilter( obj, e );
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Frame */
+/* */
+/* ------------------------------------------------------------------------- */
+
+void TEWidget::frameChanged()
+{
+ propagateSize();
+ update();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Sound */
+/* */
+/* ------------------------------------------------------------------------- */
+
+void TEWidget::Bell()
+{
+ QApplication::beep();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Auxiluary */
+/* */
+/* ------------------------------------------------------------------------- */
+
+void TEWidget::clearImage()
+// initialize the image
+// for internal use only
+{
+ for (int y = 0; y < lines; y++)
+ for (int x = 0; x < columns; x++)
+ {
+ image[loc(x,y)].c = 0xff; //' ';
+ image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR;
+ image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR;
+ image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION;
+ }
+}
+
+// Create Image ///////////////////////////////////////////////////////
+
+void TEWidget::calcGeometry()
+{
+ //FIXME: set rimX == rimY == 0 when running in full screen mode.
+
+ scrollbar->resize(QApplication::style().scrollBarExtent().width(),
+ contentsRect().height());
+ switch(scrollLoc)
+ {
+ case SCRNONE :
+ columns = ( contentsRect().width() - 2 * rimX ) / font_w;
+ blX = (contentsRect().width() - (columns*font_w) ) / 2;
+ brX = blX;
+ scrollbar->hide();
+ break;
+ case SCRLEFT :
+ columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
+ brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
+ blX = brX + scrollbar->width();
+ scrollbar->move(contentsRect().topLeft());
+ scrollbar->show();
+ break;
+ case SCRRIGHT:
+ columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
+ blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
+ brX = blX;
+ scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0));
+ scrollbar->show();
+ break;
+ }
+ //FIXME: support 'rounding' styles
+ lines = ( contentsRect().height() - 2 * rimY ) / font_h;
+ bY = (contentsRect().height() - (lines *font_h)) / 2;
+}
+
+void TEWidget::makeImage()
+//FIXME: rename 'calcGeometry?
+{
+ calcGeometry();
+ image = (ca*) malloc(lines*columns*sizeof(ca));
+ clearImage();
+}
+
+// calculate the needed size
+QSize TEWidget::calcSize(int cols, int lins) const
+{
+ int frw = width() - contentsRect().width();
+ int frh = height() - contentsRect().height();
+ int scw = (scrollLoc==SCRNONE?0:scrollbar->width());
+ return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh );
+}
+
+QSize TEWidget::sizeHint() const
+{
+ return size();
+}
+
+void TEWidget::styleChange(QStyle &)
+{
+ propagateSize();
+}
+
+#ifndef QT_NO_DRAGANDDROP
+
+/* --------------------------------------------------------------------- */
+/* */
+/* Drag & Drop */
+/* */
+/* --------------------------------------------------------------------- */
+
+
+void TEWidget::dragEnterEvent(QDragEnterEvent* e)
+{
+ e->accept(QTextDrag::canDecode(e) ||
+ QUriDrag::canDecode(e));
+}
+
+void TEWidget::dropEvent(QDropEvent* event)
+{
+ // The current behaviour when url(s) are dropped is
+ // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd
+ // * in all other cases, just paste
+ // (for non-local ones, or for a list of URLs, 'cd' is nonsense)
+ QStrList strlist;
+ int file_count = 0;
+ dropText = "";
+ bool bPopup = true;
+
+ if(QUriDrag::decode(event, strlist)) {
+ if (strlist.count()) {
+ for(const char* p = strlist.first(); p; p = strlist.next()) {
+ if(file_count++ > 0) {
+ dropText += " ";
+ bPopup = false; // more than one file, don't popup
+ }
+
+/*
+ KURL url(p);
+ if (url.isLocalFile()) {
+ dropText += url.path(); // local URL : remove protocol
+ }
+ else {
+ dropText += url.prettyURL();
+ bPopup = false; // a non-local file, don't popup
+ }
+*/
+
+ }
+
+ if (bPopup)
+ // m_drop->popup(pos() + event->pos());
+ m_drop->popup(mapToGlobal(event->pos()));
+ else
+ {
+ if (currentSession) {
+ currentSession->getEmulation()->sendString(dropText.local8Bit());
+ }
+// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
+ }
+ }
+ }
+ else if(QTextDrag::decode(event, dropText)) {
+// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
+ if (currentSession) {
+ currentSession->getEmulation()->sendString(dropText.local8Bit());
+ }
+ // Paste it
+ }
+}
+#endif
+
+
+void TEWidget::drop_menu_activated(int item)
+{
+#ifndef QT_NO_DRAGANDDROP
+ switch (item)
+ {
+ case 0: // paste
+ currentSession->getEmulation()->sendString(dropText.local8Bit());
+// KWM::activate((Window)this->winId());
+ break;
+ case 1: // cd ...
+ currentSession->getEmulation()->sendString("cd ");
+ struct stat statbuf;
+ if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 )
+ {
+ if ( !S_ISDIR(statbuf.st_mode) )
+ {
+/*
+ KURL url;
+ url.setPath( dropText );
+ dropText = url.directory( true, false ); // remove filename
+*/
+ }
+ }
+ dropText.replace(QRegExp(" "), "\\ "); // escape spaces
+ currentSession->getEmulation()->sendString(dropText.local8Bit());
+ currentSession->getEmulation()->sendString("\n");
+// KWM::activate((Window)this->winId());
+ break;
+ }
+#endif
+}
+
diff --git a/core/apps/embeddedkonsole/TEWidget.h b/core/apps/embeddedkonsole/TEWidget.h
new file mode 100644
index 0000000..3f9f4ae
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEWidget.h
@@ -0,0 +1,202 @@
+/* ----------------------------------------------------------------------- */
+/* */
+/* [te_widget.h] Terminal Emulation Widget */
+/* */
+/* ----------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* ----------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef TE_WIDGET_H
+#define TE_WIDGET_H
+
+#include <qwidget.h>
+#include <qlabel.h>
+#include <qtimer.h>
+#include <qcolor.h>
+#include <qkeycode.h>
+#include <qscrollbar.h>
+
+#include <qpopupmenu.h>
+
+#include "TECommon.h"
+
+extern unsigned short vt100_graphics[32];
+
+class TESession;
+
+// class Konsole;
+
+class TEWidget : public QFrame
+// a widget representing attributed text
+{ Q_OBJECT
+
+// friend class Konsole;
+
+public:
+
+ TEWidget(QWidget *parent=0, const char *name=0);
+ virtual ~TEWidget();
+
+public:
+
+ QColor getDefaultBackColor();
+
+ const ColorEntry* getColorTable() const;
+ void setColorTable(const ColorEntry table[]);
+
+ void setScrollbarLocation(int loc);
+ enum { SCRNONE=0, SCRLEFT=1, SCRRIGHT=2 };
+
+ void setScroll(int cursor, int lines);
+ void doScroll(int lines);
+
+ void emitSelection();
+
+public:
+
+ void setImage(const ca* const newimg, int lines, int columns);
+
+ int Lines() { return lines; }
+ int Columns() { return columns; }
+
+ void calcGeometry();
+ void propagateSize();
+ QSize calcSize(int cols, int lins) const;
+
+ QSize sizeHint() const;
+
+public:
+
+ void Bell();
+ void emitText(QString text);
+ void pasteClipboard();
+
+signals:
+
+ void keyPressedSignal(QKeyEvent *e);
+ void mouseSignal(int cb, int cx, int cy);
+ void changedImageSizeSignal(int lines, int columns);
+ void changedHistoryCursor(int value);
+ void configureRequest( TEWidget*, int state, int x, int y );
+
+ void clearSelectionSignal();
+ void beginSelectionSignal( const int x, const int y );
+ void extendSelectionSignal( const int x, const int y );
+ void endSelectionSignal(const BOOL preserve_line_breaks);
+
+
+protected:
+
+ virtual void styleChange( QStyle& );
+
+ bool eventFilter( QObject *, QEvent * );
+
+ void drawAttrStr(QPainter &paint, QRect rect,
+ QString& str, ca attr, BOOL pm, BOOL clear);
+ void paintEvent( QPaintEvent * );
+
+ void resizeEvent(QResizeEvent*);
+
+ void fontChange(const QFont &font);
+ void frameChanged();
+
+ void mouseDoubleClickEvent(QMouseEvent* ev);
+ void mousePressEvent( QMouseEvent* );
+ void mouseReleaseEvent( QMouseEvent* );
+ void mouseMoveEvent( QMouseEvent* );
+
+ void focusInEvent( QFocusEvent * );
+ void focusOutEvent( QFocusEvent * );
+ bool focusNextPrevChild( bool next );
+
+#ifndef QT_NO_DRAGANDDROP
+ // Dnd
+ void dragEnterEvent(QDragEnterEvent* event);
+ void dropEvent(QDropEvent* event);
+#endif
+
+ virtual int charClass(char) const;
+
+ void clearImage();
+
+public:
+ const QPixmap *backgroundPixmap();
+
+ void setSelection(const QString &t);
+
+ virtual void setFont(const QFont &);
+ void setVTFont(const QFont &);
+ QFont getVTFont();
+
+ void setMouseMarks(bool on);
+
+public slots:
+
+ void onClearSelection();
+
+protected slots:
+
+ void scrollChanged(int value);
+ void blinkEvent();
+
+private:
+
+ QChar (*fontMap)(QChar); // possible vt100 font extention
+
+ bool fixed_font; // has fixed pitch
+ int font_h; // height
+ int font_w; // width
+ int font_a; // ascend
+
+ int blX; // actual offset (left)
+ int brX; // actual offset (right)
+ int bY; // actual offset
+
+ int lines;
+ int columns;
+ ca *image; // [lines][columns]
+
+ ColorEntry color_table[TABLE_COLORS];
+
+ BOOL resizing;
+ bool mouse_marks;
+
+ void makeImage();
+
+ QPoint iPntSel; // initial selection point
+ QPoint pntSel; // current selection point
+ int actSel; // selection state
+ BOOL word_selection_mode;
+ BOOL preserve_line_breaks;
+
+ QClipboard* cb;
+ QScrollBar* scrollbar;
+ int scrollLoc;
+
+//#define SCRNONE 0
+//#define SCRLEFT 1
+//#define SCRRIGHT 2
+
+ BOOL blinking; // hide text in paintEvent
+ BOOL hasBlinker; // has characters to blink
+ QTimer* blinkT; // active when hasBlinker
+ QPopupMenu* m_drop;
+ QString dropText;
+ public:
+ // current session in this widget
+ TESession *currentSession;
+private slots:
+ void drop_menu_activated(int item);
+};
+
+#endif // TE_WIDGET_H
diff --git a/core/apps/embeddedkonsole/TEmuVt102.cpp b/core/apps/embeddedkonsole/TEmuVt102.cpp
new file mode 100644
index 0000000..752c49f
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEmuVt102.cpp
@@ -0,0 +1,991 @@
+/* ------------------------------------------------------------------------- */
+/* */
+/* [TEmuVt102.C] VT102 Terminal Emulation */
+/* */
+/* ------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* ------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+/*! \class TEmuVt102
+
+ \brief Actual Emulation for Konsole
+
+ \sa TEWidget \sa TEScreen
+*/
+
+#include "TEmuVt102.h"
+#include "TEWidget.h"
+#include "TEScreen.h"
+#include "keytrans.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <qkeycode.h>
+#include <qtextcodec.h>
+
+
+/* VT102 Terminal Emulation
+
+ This class puts together the screens, the pty and the widget to a
+ complete terminal emulation. Beside combining it's componentes, it
+ handles the emulations's protocol.
+
+ This module consists of the following sections:
+
+ - Constructor/Destructor
+ - Incoming Bytes Event pipeline
+ - Outgoing Bytes
+ - Mouse Events
+ - Keyboard Events
+ - Modes and Charset State
+ - Diagnostics
+*/
+
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Constructor / Destructor */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*
+ Nothing really intesting happens here.
+*/
+
+/*!
+*/
+
+TEmuVt102::TEmuVt102(TEWidget* gui) : TEmulation(gui)
+{
+ QObject::connect(gui,SIGNAL(mouseSignal(int,int,int)),
+ this,SLOT(onMouse(int,int,int)));
+ initTokenizer();
+ reset();
+}
+
+/*!
+*/
+
+TEmuVt102::~TEmuVt102()
+{
+}
+
+/*!
+*/
+
+void TEmuVt102::reset()
+{
+ resetToken();
+ resetModes();
+ resetCharset(0); screen[0]->reset();
+ resetCharset(1); screen[0]->reset();
+ setCodec(0);
+ setKeytrans("linux.keytab");
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Processing the incoming byte stream */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/* Incoming Bytes Event pipeline
+
+ This section deals with decoding the incoming character stream.
+ Decoding means here, that the stream is first seperated into `tokens'
+ which are then mapped to a `meaning' provided as operations by the
+ `TEScreen' class or by the emulation class itself.
+
+ The pipeline proceeds as follows:
+
+ - Tokenizing the ESC codes (onRcvChar)
+ - VT100 code page translation of plain characters (applyCharset)
+ - Interpretation of ESC codes (tau)
+
+ The escape codes and their meaning are described in the
+ technical reference of this program.
+*/
+
+// Tokens ------------------------------------------------------------------ --
+
+/*
+ Since the tokens are the central notion if this section, we've put them
+ in front. They provide the syntactical elements used to represent the
+ terminals operations as byte sequences.
+
+ They are encodes here into a single machine word, so that we can later
+ switch over them easily. Depending on the token itself, additional
+ argument variables are filled with parameter values.
+
+ The tokens are defined below:
+
+ - CHR - Printable characters (32..255 but DEL (=127))
+ - CTL - Control characters (0..31 but ESC (= 27), DEL)
+ - ESC - Escape codes of the form <ESC><CHR but `[]()+*#'>
+ - ESC_DE - Escape codes of the form <ESC><any of `()+*#%'> C
+ - CSI_PN - Escape codes of the form <ESC>'[' {Pn} ';' {Pn} C
+ - CSI_PS - Escape codes of the form <ESC>'[' {Pn} ';' ... C
+ - CSI_PR - Escape codes of the form <ESC>'[' '?' {Pn} ';' ... C
+ - VT52 - VT52 escape codes
+ - <ESC><Chr>
+ - <ESC>'Y'{Pc}{Pc}
+ - XTE_HA - Xterm hacks <ESC>`]' {Pn} `;' {Text} <BEL>
+ note that this is handled differently
+
+ The last two forms allow list of arguments. Since the elements of
+ the lists are treated individually the same way, they are passed
+ as individual tokens to the interpretation. Further, because the
+ meaning of the parameters are names (althought represented as numbers),
+ they are includes within the token ('N').
+
+*/
+
+#define TY_CONSTR(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) )
+
+#define TY_CHR___( ) TY_CONSTR(0,0,0)
+#define TY_CTL___(A ) TY_CONSTR(1,A,0)
+#define TY_ESC___(A ) TY_CONSTR(2,A,0)
+#define TY_ESC_CS(A,B) TY_CONSTR(3,A,B)
+#define TY_ESC_DE(A ) TY_CONSTR(4,A,0)
+#define TY_CSI_PS(A,N) TY_CONSTR(5,A,N)
+#define TY_CSI_PN(A ) TY_CONSTR(6,A,0)
+#define TY_CSI_PR(A,N) TY_CONSTR(7,A,N)
+
+#define TY_VT52__(A ) TY_CONSTR(8,A,0)
+
+// Tokenizer --------------------------------------------------------------- --
+
+/* The tokenizers state
+
+ The state is represented by the buffer (pbuf, ppos),
+ and accompanied by decoded arguments kept in (argv,argc).
+ Note that they are kept internal in the tokenizer.
+*/
+
+void TEmuVt102::resetToken()
+{
+ ppos = 0; argc = 0; argv[0] = 0; argv[1] = 0;
+}
+
+void TEmuVt102::addDigit(int dig)
+{
+ argv[argc] = 10*argv[argc] + dig;
+}
+
+void TEmuVt102::addArgument()
+{
+ argc = QMIN(argc+1,MAXARGS-1);
+ argv[argc] = 0;
+}
+
+void TEmuVt102::pushToToken(int cc)
+{
+ pbuf[ppos] = cc;
+ ppos = QMIN(ppos+1,MAXPBUF-1);
+}
+
+// Character Classes used while decoding
+
+#define CTL 1
+#define CHR 2
+#define CPN 4
+#define DIG 8
+#define SCS 16
+#define GRP 32
+
+void TEmuVt102::initTokenizer()
+{ int i; UINT8* s;
+ for(i = 0; i < 256; i++) tbl[ i] = 0;
+ for(i = 0; i < 32; i++) tbl[ i] |= CTL;
+ for(i = 32; i < 256; i++) tbl[ i] |= CHR;
+ for(s = (UINT8*)"@ABCDGHLMPXcdfry"; *s; s++) tbl[*s] |= CPN;
+ for(s = (UINT8*)"0123456789" ; *s; s++) tbl[*s] |= DIG;
+ for(s = (UINT8*)"()+*%" ; *s; s++) tbl[*s] |= SCS;
+ for(s = (UINT8*)"()+*#[]%" ; *s; s++) tbl[*s] |= GRP;
+ resetToken();
+}
+
+/* Ok, here comes the nasty part of the decoder.
+
+ Instead of keeping an explicit state, we deduce it from the
+ token scanned so far. It is then immediately combined with
+ the current character to form a scanning decision.
+
+ This is done by the following defines.
+
+ - P is the length of the token scanned so far.
+ - L (often P-1) is the position on which contents we base a decision.
+ - C is a character or a group of characters (taken from 'tbl').
+
+ Note that they need to applied in proper order.
+*/
+
+#define lec(P,L,C) (p == (P) && s[(L)] == (C))
+#define lun( ) (p == 1 && cc >= 32 )
+#define les(P,L,C) (p == (P) && s[L] < 256 && (tbl[s[(L)]] & (C)) == (C))
+#define eec(C) (p >= 3 && cc == (C))
+#define ees(C) (p >= 3 && cc < 256 && (tbl[ cc ] & (C)) == (C))
+#define eps(C) (p >= 3 && s[2] != '?' && cc < 256 && (tbl[ cc ] & (C)) == (C))
+#define epp( ) (p >= 3 && s[2] == '?' )
+#define egt( ) (p == 3 && s[2] == '>' )
+#define Xpe (ppos>=2 && pbuf[1] == ']' )
+#define Xte (Xpe && cc == 7 )
+#define ces(C) ( cc < 256 && (tbl[ cc ] & (C)) == (C) && !Xte)
+
+#define ESC 27
+#define CNTL(c) ((c)-'@')
+
+// process an incoming unicode character
+
+void TEmuVt102::onRcvChar(int cc)
+{ int i;
+
+ if (cc == 127) return; //VT100: ignore.
+
+ if (ces( CTL))
+ { // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
+ // This means, they do neither a resetToken nor a pushToToken. Some of them, do
+ // of course. Guess this originates from a weakly layered handling of the X-on
+ // X-off protocol, which comes really below this level.
+ if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) resetToken(); //VT100: CAN or SUB
+ if (cc != ESC) { tau( TY_CTL___(cc+'@' ), 0, 0); return; }
+ }
+
+ pushToToken(cc); // advance the state
+
+ int* s = pbuf;
+ int p = ppos;
+
+ if (getMode(MODE_Ansi)) // decide on proper action
+ {
+ if (lec(1,0,ESC)) { return; }
+ if (les(2,1,GRP)) { return; }
+ if (Xte ) { XtermHack(); resetToken(); return; }
+ if (Xpe ) { return; }
+ if (lec(3,2,'?')) { return; }
+ if (lec(3,2,'>')) { return; }
+ if (lun( )) { tau( TY_CHR___(), applyCharset(cc), 0); resetToken(); return; }
+ if (lec(2,0,ESC)) { tau( TY_ESC___(s[1]), 0, 0); resetToken(); return; }
+ if (les(3,1,SCS)) { tau( TY_ESC_CS(s[1],s[2]), 0, 0); resetToken(); return; }
+ if (lec(3,1,'#')) { tau( TY_ESC_DE(s[2]), 0, 0); resetToken(); return; }
+// if (egt( )) { tau( TY_CSI_PG(cc ), '>', 0); resetToken(); return; }
+ if (eps( CPN)) { tau( TY_CSI_PN(cc), argv[0],argv[1]); resetToken(); return; }
+ if (ees( DIG)) { addDigit(cc-'0'); return; }
+ if (eec( ';')) { addArgument(); return; }
+ for (i=0;i<=argc;i++)
+ if (epp( )) tau( TY_CSI_PR(cc,argv[i]), 0, 0); else
+ tau( TY_CSI_PS(cc,argv[i]), 0, 0);
+ resetToken();
+ }
+ else // mode VT52
+ {
+ if (lec(1,0,ESC)) return;
+ if (les(1,0,CHR)) { tau( TY_CHR___( ), s[0], 0); resetToken(); return; }
+ if (lec(2,1,'Y')) return;
+ if (lec(3,1,'Y')) return;
+ if (p < 4) { tau( TY_VT52__(s[1] ), 0, 0); resetToken(); return; }
+ tau( TY_VT52__(s[1] ), s[2],s[3]); resetToken(); return;
+ }
+}
+
+void TEmuVt102::XtermHack()
+{ int i,arg = 0;
+ for (i = 2; i < ppos && '0'<=pbuf[i] && pbuf[i]<'9' ; i++)
+ arg = 10*arg + (pbuf[i]-'0');
+ if (pbuf[i] != ';') { ReportErrorToken(); return; }
+ QChar *str = new QChar[ppos-i-2];
+ for (int j = 0; j < ppos-i-2; j++) str[j] = pbuf[i+1+j];
+ QString unistr(str,ppos-i-2);
+ // arg == 1 doesn't change the title. In XTerm it only changes the icon name
+ // (btw: arg=0 changes title and icon, arg=1 only icon, arg=2 only title
+ if (arg == 0 || arg == 2) emit changeTitle(arg,unistr);
+ delete [] str;
+}
+
+// Interpreting Codes ---------------------------------------------------------
+
+/*
+ Now that the incoming character stream is properly tokenized,
+ meaning is assigned to them. These are either operations of
+ the current screen, or of the emulation class itself.
+
+ The token to be interpreteted comes in as a machine word
+ possibly accompanied by two parameters.
+
+ Likewise, the operations assigned to, come with up to two
+ arguments. One could consider to make up a proper table
+ from the function below.
+
+ The technical reference manual provides more informations
+ about this mapping.
+*/
+
+void TEmuVt102::tau( int token, int p, int q )
+{
+//scan_buffer_report();
+//if (token == TY_CHR___()) printf("%c",p); else
+//printf("tau(%d,%d,%d, %d,%d)\n",(token>>0)&0xff,(token>>8)&0xff,(token>>16)&0xffff,p,q);
+ switch (token)
+ {
+
+ case TY_CHR___( ) : scr->ShowCharacter (p ); break; //UTF16
+
+ // 127 DEL : ignored on input
+
+ case TY_CTL___('@' ) : /* NUL: ignored */ break;
+ case TY_CTL___('A' ) : /* SOH: ignored */ break;
+ case TY_CTL___('B' ) : /* STX: ignored */ break;
+ case TY_CTL___('C' ) : /* ETX: ignored */ break;
+ case TY_CTL___('D' ) : /* EOT: ignored */ break;
+ case TY_CTL___('E' ) : reportAnswerBack ( ); break; //VT100
+ case TY_CTL___('F' ) : /* ACK: ignored */ break;
+ case TY_CTL___('G' ) : gui->Bell ( ); break; //VT100
+ case TY_CTL___('H' ) : scr->BackSpace ( ); break; //VT100
+ case TY_CTL___('I' ) : scr->Tabulate ( ); break; //VT100
+ case TY_CTL___('J' ) : scr->NewLine ( ); break; //VT100
+ case TY_CTL___('K' ) : scr->NewLine ( ); break; //VT100
+ case TY_CTL___('L' ) : scr->NewLine ( ); break; //VT100
+ case TY_CTL___('M' ) : scr->Return ( ); break; //VT100
+
+ case TY_CTL___('N' ) : useCharset ( 1); break; //VT100
+ case TY_CTL___('O' ) : useCharset ( 0); break; //VT100
+
+ case TY_CTL___('P' ) : /* DLE: ignored */ break;
+ case TY_CTL___('Q' ) : /* DC1: XON continue */ break; //VT100
+ case TY_CTL___('R' ) : /* DC2: ignored */ break;
+ case TY_CTL___('S' ) : /* DC3: XOFF halt */ break; //VT100
+ case TY_CTL___('T' ) : /* DC4: ignored */ break;
+ case TY_CTL___('U' ) : /* NAK: ignored */ break;
+ case TY_CTL___('V' ) : /* SYN: ignored */ break;
+ case TY_CTL___('W' ) : /* ETB: ignored */ break;
+ case TY_CTL___('X' ) : scr->ShowCharacter ( 0x2592); break; //VT100
+ case TY_CTL___('Y' ) : /* EM : ignored */ break;
+ case TY_CTL___('Z' ) : scr->ShowCharacter ( 0x2592); break; //VT100
+ case TY_CTL___('[' ) : /* ESC: cannot be seen here. */ break;
+ case TY_CTL___('\\' ) : /* FS : ignored */ break;
+ case TY_CTL___(']' ) : /* GS : ignored */ break;
+ case TY_CTL___('^' ) : /* RS : ignored */ break;
+ case TY_CTL___('_' ) : /* US : ignored */ break;
+
+ case TY_ESC___('D' ) : scr->index ( ); break; //VT100
+ case TY_ESC___('E' ) : scr->NextLine ( ); break; //VT100
+ case TY_ESC___('H' ) : scr->changeTabStop (TRUE ); break; //VT100
+ case TY_ESC___('M' ) : scr->reverseIndex ( ); break; //VT100
+ case TY_ESC___('Z' ) : reportTerminalType ( ); break;
+ case TY_ESC___('c' ) : reset ( ); break;
+
+ case TY_ESC___('n' ) : useCharset ( 2); break;
+ case TY_ESC___('o' ) : useCharset ( 3); break;
+ case TY_ESC___('7' ) : saveCursor ( ); break;
+ case TY_ESC___('8' ) : restoreCursor ( ); break;
+
+ case TY_ESC___('=' ) : setMode (MODE_AppKeyPad); break;
+ case TY_ESC___('>' ) : resetMode (MODE_AppKeyPad); break;
+ case TY_ESC___('<' ) : setMode (MODE_Ansi ); break; //VT100
+
+ case TY_ESC_CS('(', '0') : setCharset (0, '0'); break; //VT100
+ case TY_ESC_CS('(', 'A') : setCharset (0, 'A'); break; //VT100
+ case TY_ESC_CS('(', 'B') : setCharset (0, 'B'); break; //VT100
+
+ case TY_ESC_CS(')', '0') : setCharset (1, '0'); break; //VT100
+ case TY_ESC_CS(')', 'A') : setCharset (1, 'A'); break; //VT100
+ case TY_ESC_CS(')', 'B') : setCharset (1, 'B'); break; //VT100
+
+ case TY_ESC_CS('*', '0') : setCharset (2, '0'); break; //VT100
+ case TY_ESC_CS('*', 'A') : setCharset (2, 'A'); break; //VT100
+ case TY_ESC_CS('*', 'B') : setCharset (2, 'B'); break; //VT100
+
+ case TY_ESC_CS('+', '0') : setCharset (3, '0'); break; //VT100
+ case TY_ESC_CS('+', 'A') : setCharset (3, 'A'); break; //VT100
+ case TY_ESC_CS('+', 'B') : setCharset (3, 'B'); break; //VT100
+
+ case TY_ESC_CS('%', 'G') : setCodec (1 ); break; //LINUX
+ case TY_ESC_CS('%', '@') : setCodec (0 ); break; //LINUX
+
+ case TY_ESC_DE('3' ) : /* IGNORED: double high, top half */ break;
+ case TY_ESC_DE('4' ) : /* IGNORED: double high, bottom half */ break;
+ case TY_ESC_DE('5' ) : /* IGNORED: single width, single high*/ break;
+ case TY_ESC_DE('6' ) : /* IGNORED: double width, single high*/ break;
+ case TY_ESC_DE('8' ) : scr->helpAlign ( ); break;
+
+ case TY_CSI_PS('K', 0) : scr->clearToEndOfLine ( ); break;
+ case TY_CSI_PS('K', 1) : scr->clearToBeginOfLine ( ); break;
+ case TY_CSI_PS('K', 2) : scr->clearEntireLine ( ); break;
+ case TY_CSI_PS('J', 0) : scr->clearToEndOfScreen ( ); break;
+ case TY_CSI_PS('J', 1) : scr->clearToBeginOfScreen ( ); break;
+ case TY_CSI_PS('J', 2) : scr->clearEntireScreen ( ); break;
+ case TY_CSI_PS('g', 0) : scr->changeTabStop (FALSE ); break; //VT100
+ case TY_CSI_PS('g', 3) : scr->clearTabStops ( ); break; //VT100
+ case TY_CSI_PS('h', 4) : scr-> setMode (MODE_Insert ); break;
+ case TY_CSI_PS('h', 20) : setMode (MODE_NewLine ); break;
+ case TY_CSI_PS('i', 0) : /* IGNORE: attached printer */ break; //VT100
+ case TY_CSI_PS('l', 4) : scr-> resetMode (MODE_Insert ); break;
+ case TY_CSI_PS('l', 20) : resetMode (MODE_NewLine ); break;
+
+ case TY_CSI_PS('m', 0) : scr->setDefaultRendition ( ); break;
+ case TY_CSI_PS('m', 1) : scr-> setRendition (RE_BOLD ); break; //VT100
+ case TY_CSI_PS('m', 4) : scr-> setRendition (RE_UNDERLINE); break; //VT100
+ case TY_CSI_PS('m', 5) : scr-> setRendition (RE_BLINK ); break; //VT100
+ case TY_CSI_PS('m', 7) : scr-> setRendition (RE_REVERSE ); break;
+ case TY_CSI_PS('m', 10) : /* IGNORED: mapping related */ break; //LINUX
+ case TY_CSI_PS('m', 11) : /* IGNORED: mapping related */ break; //LINUX
+ case TY_CSI_PS('m', 12) : /* IGNORED: mapping related */ break; //LINUX
+ case TY_CSI_PS('m', 22) : scr->resetRendition (RE_BOLD ); break;
+ case TY_CSI_PS('m', 24) : scr->resetRendition (RE_UNDERLINE); break;
+ case TY_CSI_PS('m', 25) : scr->resetRendition (RE_BLINK ); break;
+ case TY_CSI_PS('m', 27) : scr->resetRendition (RE_REVERSE ); break;
+
+ case TY_CSI_PS('m', 30) : scr->setForeColor ( 0); break;
+ case TY_CSI_PS('m', 31) : scr->setForeColor ( 1); break;
+ case TY_CSI_PS('m', 32) : scr->setForeColor ( 2); break;
+ case TY_CSI_PS('m', 33) : scr->setForeColor ( 3); break;
+ case TY_CSI_PS('m', 34) : scr->setForeColor ( 4); break;
+ case TY_CSI_PS('m', 35) : scr->setForeColor ( 5); break;
+ case TY_CSI_PS('m', 36) : scr->setForeColor ( 6); break;
+ case TY_CSI_PS('m', 37) : scr->setForeColor ( 7); break;
+ case TY_CSI_PS('m', 39) : scr->setForeColorToDefault( ); break;
+
+ case TY_CSI_PS('m', 40) : scr->setBackColor ( 0); break;
+ case TY_CSI_PS('m', 41) : scr->setBackColor ( 1); break;
+ case TY_CSI_PS('m', 42) : scr->setBackColor ( 2); break;
+ case TY_CSI_PS('m', 43) : scr->setBackColor ( 3); break;
+ case TY_CSI_PS('m', 44) : scr->setBackColor ( 4); break;
+ case TY_CSI_PS('m', 45) : scr->setBackColor ( 5); break;
+ case TY_CSI_PS('m', 46) : scr->setBackColor ( 6); break;
+ case TY_CSI_PS('m', 47) : scr->setBackColor ( 7); break;
+ case TY_CSI_PS('m', 49) : scr->setBackColorToDefault( ); break;
+
+ case TY_CSI_PS('m', 90) : scr->setForeColor ( 8); break;
+ case TY_CSI_PS('m', 91) : scr->setForeColor ( 9); break;
+ case TY_CSI_PS('m', 92) : scr->setForeColor ( 10); break;
+ case TY_CSI_PS('m', 93) : scr->setForeColor ( 11); break;
+ case TY_CSI_PS('m', 94) : scr->setForeColor ( 12); break;
+ case TY_CSI_PS('m', 95) : scr->setForeColor ( 13); break;
+ case TY_CSI_PS('m', 96) : scr->setForeColor ( 14); break;
+ case TY_CSI_PS('m', 97) : scr->setForeColor ( 15); break;
+
+ case TY_CSI_PS('m', 100) : scr->setBackColor ( 8); break;
+ case TY_CSI_PS('m', 101) : scr->setBackColor ( 9); break;
+ case TY_CSI_PS('m', 102) : scr->setBackColor ( 10); break;
+ case TY_CSI_PS('m', 103) : scr->setBackColor ( 11); break;
+ case TY_CSI_PS('m', 104) : scr->setBackColor ( 12); break;
+ case TY_CSI_PS('m', 105) : scr->setBackColor ( 13); break;
+ case TY_CSI_PS('m', 106) : scr->setBackColor ( 14); break;
+ case TY_CSI_PS('m', 107) : scr->setBackColor ( 15); break;
+
+ case TY_CSI_PS('n', 5) : reportStatus ( ); break;
+ case TY_CSI_PS('n', 6) : reportCursorPosition ( ); break;
+ case TY_CSI_PS('q', 0) : /* IGNORED: LEDs off */ break; //VT100
+ case TY_CSI_PS('q', 1) : /* IGNORED: LED1 on */ break; //VT100
+ case TY_CSI_PS('q', 2) : /* IGNORED: LED2 on */ break; //VT100
+ case TY_CSI_PS('q', 3) : /* IGNORED: LED3 on */ break; //VT100
+ case TY_CSI_PS('q', 4) : /* IGNORED: LED4 on */ break; //VT100
+ case TY_CSI_PS('x', 0) : reportTerminalParms ( 2); break; //VT100
+ case TY_CSI_PS('x', 1) : reportTerminalParms ( 3); break; //VT100
+
+ case TY_CSI_PN('@' ) : scr->insertChars (p ); break;
+ case TY_CSI_PN('A' ) : scr->cursorUp (p ); break; //VT100
+ case TY_CSI_PN('B' ) : scr->cursorDown (p ); break; //VT100
+ case TY_CSI_PN('C' ) : scr->cursorRight (p ); break; //VT100
+ case TY_CSI_PN('D' ) : scr->cursorLeft (p ); break; //VT100
+ case TY_CSI_PN('G' ) : scr->setCursorX (p ); break; //LINUX
+ case TY_CSI_PN('H' ) : scr->setCursorYX (p, q); break; //VT100
+ case TY_CSI_PN('L' ) : scr->insertLines (p ); break;
+ case TY_CSI_PN('M' ) : scr->deleteLines (p ); break;
+ case TY_CSI_PN('P' ) : scr->deleteChars (p ); break;
+ case TY_CSI_PN('X' ) : scr->eraseChars (p ); break;
+ case TY_CSI_PN('c' ) : reportTerminalType ( ); break; //VT100
+ case TY_CSI_PN('d' ) : scr->setCursorY (p ); break; //LINUX
+ case TY_CSI_PN('f' ) : scr->setCursorYX (p, q); break; //VT100
+ case TY_CSI_PN('r' ) : scr->setMargins (p, q); break; //VT100
+ case TY_CSI_PN('y' ) : /* IGNORED: Confidence test */ break; //VT100
+
+ case TY_CSI_PR('h', 1) : setMode (MODE_AppCuKeys); break; //VT100
+ case TY_CSI_PR('l', 1) : resetMode (MODE_AppCuKeys); break; //VT100
+ case TY_CSI_PR('s', 1) : saveMode (MODE_AppCuKeys); break; //FIXME
+ case TY_CSI_PR('r', 1) : restoreMode (MODE_AppCuKeys); break; //FIXME
+
+ case TY_CSI_PR('l', 2) : resetMode (MODE_Ansi ); break; //VT100
+
+ case TY_CSI_PR('h', 3) : setColumns ( 132); break; //VT100
+ case TY_CSI_PR('l', 3) : setColumns ( 80); break; //VT100
+
+ case TY_CSI_PR('h', 4) : /* IGNORED: soft scrolling */ break; //VT100
+ case TY_CSI_PR('l', 4) : /* IGNORED: soft scrolling */ break; //VT100
+
+ case TY_CSI_PR('h', 5) : scr-> setMode (MODE_Screen ); break; //VT100
+ case TY_CSI_PR('l', 5) : scr-> resetMode (MODE_Screen ); break; //VT100
+
+ case TY_CSI_PR('h', 6) : scr-> setMode (MODE_Origin ); break; //VT100
+ case TY_CSI_PR('l', 6) : scr-> resetMode (MODE_Origin ); break; //VT100
+ case TY_CSI_PR('s', 6) : scr-> saveMode (MODE_Origin ); break; //FIXME
+ case TY_CSI_PR('r', 6) : scr->restoreMode (MODE_Origin ); break; //FIXME
+
+ case TY_CSI_PR('h', 7) : scr-> setMode (MODE_Wrap ); break; //VT100
+ case TY_CSI_PR('l', 7) : scr-> resetMode (MODE_Wrap ); break; //VT100
+ case TY_CSI_PR('s', 7) : scr-> saveMode (MODE_Wrap ); break; //FIXME
+ case TY_CSI_PR('r', 7) : scr->restoreMode (MODE_Wrap ); break; //FIXME
+
+ case TY_CSI_PR('h', 8) : /* IGNORED: autorepeat on */ break; //VT100
+ case TY_CSI_PR('l', 8) : /* IGNORED: autorepeat off */ break; //VT100
+
+ case TY_CSI_PR('h', 9) : /* IGNORED: interlace */ break; //VT100
+ case TY_CSI_PR('l', 9) : /* IGNORED: interlace */ break; //VT100
+
+ case TY_CSI_PR('h', 25) : setMode (MODE_Cursor ); break; //VT100
+ case TY_CSI_PR('l', 25) : resetMode (MODE_Cursor ); break; //VT100
+
+ case TY_CSI_PR('h', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
+ case TY_CSI_PR('l', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
+ case TY_CSI_PR('s', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
+ case TY_CSI_PR('r', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
+
+ case TY_CSI_PR('h', 47) : setMode (MODE_AppScreen); break; //VT100
+ case TY_CSI_PR('l', 47) : resetMode (MODE_AppScreen); break; //VT100
+
+ case TY_CSI_PR('h', 1000) : setMode (MODE_Mouse1000); break; //XTERM
+ case TY_CSI_PR('l', 1000) : resetMode (MODE_Mouse1000); break; //XTERM
+ case TY_CSI_PR('s', 1000) : saveMode (MODE_Mouse1000); break; //XTERM
+ case TY_CSI_PR('r', 1000) : restoreMode (MODE_Mouse1000); break; //XTERM
+
+ case TY_CSI_PR('h', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
+ case TY_CSI_PR('l', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
+ case TY_CSI_PR('s', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
+ case TY_CSI_PR('r', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
+
+ case TY_CSI_PR('h', 1047) : setMode (MODE_AppScreen); break; //XTERM
+ case TY_CSI_PR('l', 1047) : resetMode (MODE_AppScreen); break; //XTERM
+
+ //FIXME: Unitoken: save translations
+ case TY_CSI_PR('h', 1048) : saveCursor ( ); break; //XTERM
+ case TY_CSI_PR('l', 1048) : restoreCursor ( ); break; //XTERM
+
+ //FIXME: every once new sequences like this pop up in xterm.
+ // Here's a guess of what they could mean.
+ case TY_CSI_PR('h', 1049) : setMode (MODE_AppScreen); break; //XTERM
+ case TY_CSI_PR('l', 1049) : resetMode (MODE_AppScreen); break; //XTERM
+
+ //FIXME: when changing between vt52 and ansi mode evtl do some resetting.
+ case TY_VT52__('A' ) : scr->cursorUp ( 1); break; //VT52
+ case TY_VT52__('B' ) : scr->cursorDown ( 1); break; //VT52
+ case TY_VT52__('C' ) : scr->cursorRight ( 1); break; //VT52
+ case TY_VT52__('D' ) : scr->cursorLeft ( 1); break; //VT52
+
+ case TY_VT52__('F' ) : setAndUseCharset (0, '0'); break; //VT52
+ case TY_VT52__('G' ) : setAndUseCharset (0, 'B'); break; //VT52
+
+ case TY_VT52__('H' ) : scr->setCursorYX (1,1 ); break; //VT52
+ case TY_VT52__('I' ) : scr->reverseIndex ( ); break; //VT52
+ case TY_VT52__('J' ) : scr->clearToEndOfScreen ( ); break; //VT52
+ case TY_VT52__('K' ) : scr->clearToEndOfLine ( ); break; //VT52
+ case TY_VT52__('Y' ) : scr->setCursorYX (p-31,q-31 ); break; //VT52
+ case TY_VT52__('Z' ) : reportTerminalType ( ); break; //VT52
+ case TY_VT52__('<' ) : setMode (MODE_Ansi ); break; //VT52
+ case TY_VT52__('=' ) : setMode (MODE_AppKeyPad); break; //VT52
+ case TY_VT52__('>' ) : resetMode (MODE_AppKeyPad); break; //VT52
+
+ default : ReportErrorToken(); break;
+ };
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Terminal to Host protocol */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*
+ Outgoing bytes originate from several sources:
+
+ - Replies to Enquieries.
+ - Mouse Events
+ - Keyboard Events
+*/
+
+/*!
+*/
+
+void TEmuVt102::sendString(const char* s)
+{
+ emit sndBlock(s,strlen(s));
+}
+
+// Replies ----------------------------------------------------------------- --
+
+// This section copes with replies send as response to an enquiery control code.
+
+/*!
+*/
+
+void TEmuVt102::reportCursorPosition()
+{ char tmp[20];
+ sprintf(tmp,"\033[%d;%dR",scr->getCursorY()+1,scr->getCursorX()+1);
+ sendString(tmp);
+}
+
+/*
+ What follows here is rather obsolete and faked stuff.
+ The correspondent enquieries are neverthenless issued.
+*/
+
+/*!
+*/
+
+void TEmuVt102::reportTerminalType()
+{
+//FIXME: should change?
+ if (getMode(MODE_Ansi))
+// sendString("\033[?1;2c"); // I'm a VT100 with AP0 //FIXME: send only in response to ^[[0c
+ sendString("\033[>0;115;0c"); // I'm a VT220 //FIXME: send only in response to ^[[>c
+ else
+ sendString("\033/Z"); // I'm a VT52
+}
+
+void TEmuVt102::reportTerminalParms(int p)
+// DECREPTPARM
+{ char tmp[100];
+ sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p); // not really true.
+ sendString(tmp);
+}
+
+/*!
+*/
+
+void TEmuVt102::reportStatus()
+{
+ sendString("\033[0n"); //VT100. Device status report. 0 = Ready.
+}
+
+/*!
+*/
+
+#define ANSWER_BACK "" // This is really obsolete VT100 stuff.
+
+void TEmuVt102::reportAnswerBack()
+{
+ sendString(ANSWER_BACK);
+}
+
+// Mouse Handling ---------------------------------------------------------- --
+
+/*!
+ Mouse clicks are possibly reported to the client
+ application if it has issued interest in them.
+ They are normally consumed by the widget for copy
+ and paste, but may be propagated from the widget
+ when gui->setMouseMarks is set via setMode(MODE_Mouse1000).
+
+ `x',`y' are 1-based.
+ `ev' (event) indicates the button pressed (0-2)
+ or a general mouse release (3).
+*/
+
+void TEmuVt102::onMouse( int cb, int cx, int cy )
+{ char tmp[20];
+ if (!connected) return;
+ sprintf(tmp,"\033[M%c%c%c",cb+040,cx+040,cy+040);
+ sendString(tmp);
+}
+
+// Keyboard Handling ------------------------------------------------------- --
+
+#define encodeMode(M,B) BITS(B,getMode(M))
+#define encodeStat(M,B) BITS(B,((ev->state() & (M)) == (M)))
+
+/*
+ Keyboard event handling has been simplified somewhat by pushing
+ the complications towards a configuration file [see KeyTrans class].
+*/
+
+void TEmuVt102::onKeyPress( QKeyEvent* ev )
+{
+ if (!connected) return; // someone else gets the keys
+
+//printf("State/Key: 0x%04x 0x%04x (%d,%d)\n",ev->state(),ev->key(),ev->text().length(),ev->text().length()?ev->text().ascii()[0]:0);
+
+ // revert to non-history when typing
+ if (scr->getHistCursor() != scr->getHistLines());
+ scr->setHistCursor(scr->getHistLines());
+
+ // lookup in keyboard translation table ...
+ int cmd; const char* txt; int len;
+ if (keytrans->findEntry(ev->key(), encodeMode(MODE_NewLine , BITS_NewLine ) + // OLD,
+ encodeMode(MODE_Ansi , BITS_Ansi ) + // OBSOLETE,
+ encodeMode(MODE_AppCuKeys, BITS_AppCuKeys ) + // VT100 stuff
+ encodeStat(ControlButton , BITS_Control ) +
+ encodeStat(ShiftButton , BITS_Shift ) +
+ encodeStat(AltButton , BITS_Alt ),
+ &cmd, &txt, &len ))
+//printf("cmd: %d, %s, %d\n",cmd,txt,len);
+ switch(cmd) // ... and execute if found.
+ {
+ case CMD_emitSelection : gui->emitSelection(); return;
+ case CMD_scrollPageUp : gui->doScroll(-gui->Lines()/2); return;
+ case CMD_scrollPageDown : gui->doScroll(+gui->Lines()/2); return;
+ case CMD_scrollLineUp : gui->doScroll(-1 ); return;
+ case CMD_scrollLineDown : gui->doScroll(+1 ); return;
+ case CMD_send : emit sndBlock(txt,len); return;
+ case CMD_prevSession : emit prevSession(); return;
+ case CMD_nextSession : emit nextSession(); return;
+ }
+
+ // fall back handling
+ if (!ev->text().isEmpty())
+ {
+ if (ev->state() & AltButton) sendString("\033"); // ESC, this is the ALT prefix
+ QCString s = codec->fromUnicode(ev->text()); // encode for application
+ emit sndBlock(s.data(),s.length()); // we may well have s.length() > 1
+ return;
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* VT100 Charsets */
+/* */
+/* ------------------------------------------------------------------------- */
+
+// Character Set Conversion ------------------------------------------------ --
+
+/*
+ The processing contains a VT100 specific code translation layer.
+ It's still in use and mainly responsible for the line drawing graphics.
+
+ These and some other glyphs are assigned to codes (0x5f-0xfe)
+ normally occupied by the latin letters. Since this codes also
+ appear within control sequences, the extra code conversion
+ does not permute with the tokenizer and is placed behind it
+ in the pipeline. It only applies to tokens, which represent
+ plain characters.
+
+ This conversion it eventually continued in TEWidget.C, since
+ it might involve VT100 enhanced fonts, which have these
+ particular glyphs allocated in (0x00-0x1f) in their code page.
+*/
+
+#define CHARSET charset[scr==screen[1]]
+
+// Apply current character map.
+
+unsigned short TEmuVt102::applyCharset(unsigned short c)
+{
+ if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f];
+ if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete
+ return c;
+}
+
+/*
+ "Charset" related part of the emulation state.
+ This configures the VT100 charset filter.
+
+ While most operation work on the current screen,
+ the following two are different.
+*/
+
+void TEmuVt102::resetCharset(int scrno)
+{
+ charset[scrno].cu_cs = 0;
+ strncpy(charset[scrno].charset,"BBBB",4);
+ charset[scrno].sa_graphic = FALSE;
+ charset[scrno].sa_pound = FALSE;
+ charset[scrno].graphic = FALSE;
+ charset[scrno].pound = FALSE;
+}
+
+/*!
+*/
+
+void TEmuVt102::setCharset(int n, int cs) // on both screens.
+{
+ charset[0].charset[n&3] = cs; useCharset(charset[0].cu_cs);
+ charset[1].charset[n&3] = cs; useCharset(charset[1].cu_cs);
+}
+
+/*!
+*/
+
+void TEmuVt102::setAndUseCharset(int n, int cs)
+{
+ CHARSET.charset[n&3] = cs;
+ useCharset(n&3);
+}
+
+/*!
+*/
+
+void TEmuVt102::useCharset(int n)
+{
+ CHARSET.cu_cs = n&3;
+ CHARSET.graphic = (CHARSET.charset[n&3] == '0');
+ CHARSET.pound = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete
+}
+
+/*! Save the cursor position and the rendition attribute settings. */
+
+void TEmuVt102::saveCursor()
+{
+ CHARSET.sa_graphic = CHARSET.graphic;
+ CHARSET.sa_pound = CHARSET.pound; //This mode is obsolete
+ // we are not clear about these
+ //sa_charset = charsets[cScreen->charset];
+ //sa_charset_num = cScreen->charset;
+ scr->saveCursor();
+}
+
+/*! Restore the cursor position and the rendition attribute settings. */
+
+void TEmuVt102::restoreCursor()
+{
+ CHARSET.graphic = CHARSET.sa_graphic;
+ CHARSET.pound = CHARSET.sa_pound; //This mode is obsolete
+ scr->restoreCursor();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Mode Operations */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*
+ Some of the emulations state is either added to the state of the screens.
+
+ This causes some scoping problems, since different emulations choose to
+ located the mode either to the current screen or to both.
+
+ For strange reasons, the extend of the rendition attributes ranges over
+ all screens and not over the actual screen.
+
+ We decided on the precise precise extend, somehow.
+*/
+
+// "Mode" related part of the state. These are all booleans.
+
+void TEmuVt102::resetModes()
+{
+ resetMode(MODE_Mouse1000); saveMode(MODE_Mouse1000);
+ resetMode(MODE_AppScreen); saveMode(MODE_AppScreen);
+ // here come obsolete modes
+ resetMode(MODE_AppCuKeys); saveMode(MODE_AppCuKeys);
+ resetMode(MODE_NewLine );
+ setMode(MODE_Ansi );
+}
+
+void TEmuVt102::setMode(int m)
+{
+ currParm.mode[m] = TRUE;
+ switch (m)
+ {
+ case MODE_Mouse1000 : gui->setMouseMarks(FALSE);
+ break;
+ case MODE_AppScreen : screen[1]->clearSelection();
+ screen[1]->clearEntireScreen();
+ setScreen(1);
+ break;
+ }
+ if (m < MODES_SCREEN || m == MODE_NewLine)
+ {
+ screen[0]->setMode(m);
+ screen[1]->setMode(m);
+ }
+}
+
+void TEmuVt102::resetMode(int m)
+{
+ currParm.mode[m] = FALSE;
+ switch (m)
+ {
+ case MODE_Mouse1000 : gui->setMouseMarks(TRUE);
+ break;
+ case MODE_AppScreen : screen[0]->clearSelection();
+ setScreen(0);
+ break;
+ }
+ if (m < MODES_SCREEN || m == MODE_NewLine)
+ {
+ screen[0]->resetMode(m);
+ screen[1]->resetMode(m);
+ }
+}
+
+void TEmuVt102::saveMode(int m)
+{
+ saveParm.mode[m] = currParm.mode[m];
+}
+
+void TEmuVt102::restoreMode(int m)
+{
+ if(saveParm.mode[m]) setMode(m); else resetMode(m);
+}
+
+BOOL TEmuVt102::getMode(int m)
+{
+ return currParm.mode[m];
+}
+
+void TEmuVt102::setConnect(bool c)
+{
+ TEmulation::setConnect(c);
+ if (c)
+ { // refresh mouse mode
+ if (getMode(MODE_Mouse1000))
+ setMode(MODE_Mouse1000);
+ else
+ resetMode(MODE_Mouse1000);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Diagnostic */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*! shows the contents of the scan buffer.
+
+ This functions is used for diagnostics. It is called by \e ReportErrorToken
+ to inform about strings that cannot be decoded or handled by the emulation.
+
+ \sa ReportErrorToken
+*/
+
+/*!
+*/
+
+static void hexdump(int* s, int len)
+{ int i;
+ for (i = 0; i < len; i++)
+ {
+ if (s[i] == '\\')
+ printf("\\\\");
+ else
+ if ((s[i]) > 32 && s[i] < 127)
+ printf("%c",s[i]);
+ else
+ printf("\\%04x(hex)",s[i]);
+ }
+}
+
+void TEmuVt102::scan_buffer_report()
+{
+ if (ppos == 0 || ppos == 1 && (pbuf[0] & 0xff) >= 32) return;
+ printf("token: "); hexdump(pbuf,ppos); printf("\n");
+}
+
+/*!
+*/
+
+void TEmuVt102::ReportErrorToken()
+{
+ printf("undecodable "); scan_buffer_report();
+}
diff --git a/core/apps/embeddedkonsole/TEmuVt102.h b/core/apps/embeddedkonsole/TEmuVt102.h
new file mode 100644
index 0000000..a448a71
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEmuVt102.h
@@ -0,0 +1,135 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [TEmuVt102.h] X Terminal Emulation */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef VT102EMU_H
+#define VT102EMU_H
+
+#include "TEWidget.h"
+#include "TEScreen.h"
+#include "TEmulation.h"
+#include <qtimer.h>
+#include <stdio.h>
+
+//
+
+#define MODE_AppScreen (MODES_SCREEN+0)
+#define MODE_AppCuKeys (MODES_SCREEN+1)
+#define MODE_AppKeyPad (MODES_SCREEN+2)
+#define MODE_Mouse1000 (MODES_SCREEN+3)
+#define MODE_Ansi (MODES_SCREEN+4)
+#define MODE_total (MODES_SCREEN+5)
+
+struct DECpar
+{
+ BOOL mode[MODE_total];
+};
+
+struct CharCodes
+{
+ // coding info
+ char charset[4]; //
+ int cu_cs; // actual charset.
+ bool graphic; // Some VT100 tricks
+ bool pound ; // Some VT100 tricks
+ bool sa_graphic; // saved graphic
+ bool sa_pound; // saved pound
+};
+
+class TEmuVt102 : public TEmulation
+{ Q_OBJECT
+
+public:
+
+ TEmuVt102(TEWidget* gui);
+ ~TEmuVt102();
+
+public slots: // signals incoming from TEWidget
+
+ void onKeyPress(QKeyEvent*);
+ void onMouse(int cb, int cx, int cy);
+
+signals:
+
+ void changeTitle(int,const QString&);
+ void prevSession();
+ void nextSession();
+
+public:
+
+ void reset();
+
+ void onRcvChar(int cc);
+ void sendString(const char *);
+
+public:
+
+ BOOL getMode (int m);
+
+ void setMode (int m);
+ void resetMode (int m);
+ void saveMode (int m);
+ void restoreMode(int m);
+ void resetModes();
+
+ void setConnect(bool r);
+
+private:
+
+ void resetToken();
+#define MAXPBUF 80
+ void pushToToken(int cc);
+ int pbuf[MAXPBUF]; //FIXME: overflow?
+ int ppos;
+#define MAXARGS 15
+ void addDigit(int dig);
+ void addArgument();
+ int argv[MAXARGS];
+ int argc;
+ void initTokenizer();
+ int tbl[256];
+
+ void scan_buffer_report(); //FIXME: rename
+ void ReportErrorToken(); //FIXME: rename
+
+ void tau(int code, int p, int q);
+ void XtermHack();
+
+ //
+
+ void reportTerminalType();
+ void reportStatus();
+ void reportAnswerBack();
+ void reportCursorPosition();
+ void reportTerminalParms(int p);
+
+protected:
+
+ unsigned short applyCharset(unsigned short c);
+ void setCharset(int n, int cs);
+ void useCharset(int n);
+ void setAndUseCharset(int n, int cs);
+ void saveCursor();
+ void restoreCursor();
+ void resetCharset(int scrno);
+ CharCodes charset[2];
+
+ DECpar currParm;
+ DECpar saveParm;
+};
+
+#endif // ifndef ANSIEMU_H
diff --git a/core/apps/embeddedkonsole/TEmulation.cpp b/core/apps/embeddedkonsole/TEmulation.cpp
new file mode 100644
index 0000000..6f3ad32
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEmulation.cpp
@@ -0,0 +1,363 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [TEmulation.cpp] Terminal Emulation Decoder */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+/*! \class TEmulation
+
+ \brief Mediator between TEWidget and TEScreen.
+
+ This class is responsible to scan the escapes sequences of the terminal
+ emulation and to map it to their corresponding semantic complements.
+ Thus this module knows mainly about decoding escapes sequences and
+ is a stateless device w.r.t. the semantics.
+
+ It is also responsible to refresh the TEWidget by certain rules.
+
+ \sa TEWidget \sa TEScreen
+
+ \par A note on refreshing
+
+ Although the modifications to the current screen image could immediately
+ be propagated via `TEWidget' to the graphical surface, we have chosen
+ another way here.
+
+ The reason for doing so is twofold.
+
+ First, experiments show that directly displaying the operation results
+ in slowing down the overall performance of emulations. Displaying
+ individual characters using X11 creates a lot of overhead.
+
+ Second, by using the following refreshing method, the screen operations
+ can be completely separated from the displaying. This greatly simplifies
+ the programmer's task of coding and maintaining the screen operations,
+ since one need not worry about differential modifications on the
+ display affecting the operation of concern.
+
+ We use a refreshing algorithm here that has been adoped from rxvt/kvt.
+
+ By this, refreshing is driven by a timer, which is (re)started whenever
+ a new bunch of data to be interpreted by the emulation arives at `onRcvBlock'.
+ As soon as no more data arrive for `BULK_TIMEOUT' milliseconds, we trigger
+ refresh. This rule suits both bulk display operation as done by curses as
+ well as individual characters typed.
+ (BULK_TIMEOUT < 1000 / max characters received from keyboard per second).
+
+ Additionally, we trigger refreshing by newlines comming in to make visual
+ snapshots of lists as produced by `cat', `ls' and likely programs, thereby
+ producing the illusion of a permanent and immediate display operation.
+
+ As a sort of catch-all needed for cases where none of the above
+ conditions catch, the screen refresh is also triggered by a count
+ of incoming bulks (`bulk_incnt').
+*/
+
+/* FIXME
+ - evtl. the bulk operations could be made more transparent.
+*/
+
+#include "TEmulation.h"
+#include "TEWidget.h"
+#include "TEScreen.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <qkeycode.h>
+
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* TEmulation */
+/* */
+/* ------------------------------------------------------------------------- */
+
+#define CNTL(c) ((c)-'@')
+
+/*!
+*/
+
+TEmulation::TEmulation(TEWidget* gui)
+: decoder((QTextDecoder*)NULL)
+{
+ this->gui = gui;
+
+ screen[0] = new TEScreen(gui->Lines(),gui->Columns());
+ screen[1] = new TEScreen(gui->Lines(),gui->Columns());
+ scr = screen[0];
+
+ bulk_nlcnt = 0; // reset bulk newline counter
+ bulk_incnt = 0; // reset bulk counter
+ connected = FALSE;
+
+ QObject::connect(&bulk_timer, SIGNAL(timeout()), this, SLOT(showBulk()) );
+ QObject::connect(gui,SIGNAL(changedImageSizeSignal(int,int)),
+ this,SLOT(onImageSizeChange(int,int)));
+ QObject::connect(gui,SIGNAL(changedHistoryCursor(int)),
+ this,SLOT(onHistoryCursorChange(int)));
+ QObject::connect(gui,SIGNAL(keyPressedSignal(QKeyEvent*)),
+ this,SLOT(onKeyPress(QKeyEvent*)));
+ QObject::connect(gui,SIGNAL(beginSelectionSignal(const int,const int)),
+ this,SLOT(onSelectionBegin(const int,const int)) );
+ QObject::connect(gui,SIGNAL(extendSelectionSignal(const int,const int)),
+ this,SLOT(onSelectionExtend(const int,const int)) );
+ QObject::connect(gui,SIGNAL(endSelectionSignal(const BOOL)),
+ this,SLOT(setSelection(const BOOL)) );
+ QObject::connect(gui,SIGNAL(clearSelectionSignal()),
+ this,SLOT(clearSelection()) );
+}
+
+/*!
+*/
+
+TEmulation::~TEmulation()
+{
+ delete screen[0];
+ delete screen[1];
+ bulk_timer.stop();
+}
+
+/*! change between primary and alternate screen
+*/
+
+void TEmulation::setScreen(int n)
+{
+ scr = screen[n&1];
+}
+
+void TEmulation::setHistory(bool on)
+{
+ screen[0]->setScroll(on);
+ if (!connected) return;
+ showBulk();
+}
+
+bool TEmulation::history()
+{
+ return screen[0]->hasScroll();
+}
+
+void TEmulation::setCodec(int c)
+{
+ //FIXME: check whether we have to free codec
+ codec = c ? QTextCodec::codecForName("utf8")
+ : QTextCodec::codecForLocale();
+ if (decoder) delete decoder;
+ decoder = codec->makeDecoder();
+}
+
+void TEmulation::setKeytrans(int no)
+{
+ keytrans = KeyTrans::find(no);
+}
+
+void TEmulation::setKeytrans(const char * no)
+{
+ keytrans = KeyTrans::find(no);
+}
+
+// Interpreting Codes ---------------------------------------------------------
+
+/*
+ This section deals with decoding the incoming character stream.
+ Decoding means here, that the stream is first seperated into `tokens'
+ which are then mapped to a `meaning' provided as operations by the
+ `Screen' class.
+*/
+
+/*!
+*/
+
+void TEmulation::onRcvChar(int c)
+// process application unicode input to terminal
+// this is a trivial scanner
+{
+ c &= 0xff;
+ switch (c)
+ {
+ case '\b' : scr->BackSpace(); break;
+ case '\t' : scr->Tabulate(); break;
+ case '\n' : scr->NewLine(); break;
+ case '\r' : scr->Return(); break;
+ case 0x07 : gui->Bell(); break;
+ default : scr->ShowCharacter(c); break;
+ };
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Keyboard Handling */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*!
+*/
+
+void TEmulation::onKeyPress( QKeyEvent* ev )
+{
+ if (!connected) return; // someone else gets the keys
+ if (scr->getHistCursor() != scr->getHistLines());
+ scr->setHistCursor(scr->getHistLines());
+ if (!ev->text().isEmpty())
+ { // A block of text
+ // Note that the text is proper unicode.
+ // We should do a conversion here, but since this
+ // routine will never be used, we simply emit plain ascii.
+ emit sndBlock(ev->text().ascii(),ev->text().length());
+ }
+ else if (ev->ascii()>0)
+ { unsigned char c[1];
+ c[0] = ev->ascii();
+ emit sndBlock((char*)c,1);
+ }
+}
+
+// Unblocking, Byte to Unicode translation --------------------------------- --
+
+/*
+ We are doing code conversion from locale to unicode first.
+*/
+
+void TEmulation::onRcvBlock(const char *s, int len)
+{
+ bulkStart();
+ bulk_incnt += 1;
+ for (int i = 0; i < len; i++)
+ {
+ QString result = decoder->toUnicode(&s[i],1);
+ int reslen = result.length();
+ for (int j = 0; j < reslen; j++)
+ onRcvChar(result[j].unicode());
+ if (s[i] == '\n') bulkNewline();
+ }
+ bulkEnd();
+}
+
+// Selection --------------------------------------------------------------- --
+
+void TEmulation::onSelectionBegin(const int x, const int y) {
+ if (!connected) return;
+ scr->setSelBeginXY(x,y);
+ showBulk();
+}
+
+void TEmulation::onSelectionExtend(const int x, const int y) {
+ if (!connected) return;
+ scr->setSelExtentXY(x,y);
+ showBulk();
+}
+
+void TEmulation::setSelection(const BOOL preserve_line_breaks) {
+ if (!connected) return;
+ QString t = scr->getSelText(preserve_line_breaks);
+ if (!t.isNull()) gui->setSelection(t);
+}
+
+void TEmulation::clearSelection() {
+ if (!connected) return;
+ scr->clearSelection();
+ showBulk();
+}
+
+// Refreshing -------------------------------------------------------------- --
+
+#define BULK_TIMEOUT 20
+
+/*!
+ called when \n comes in. Evtl. triggers showBulk at endBulk
+*/
+
+void TEmulation::bulkNewline()
+{
+ bulk_nlcnt += 1;
+ bulk_incnt = 0; // reset bulk counter since `nl' rule applies
+}
+
+/*!
+*/
+
+void TEmulation::showBulk()
+{
+ bulk_nlcnt = 0; // reset bulk newline counter
+ bulk_incnt = 0; // reset bulk counter
+ if (connected)
+ {
+ ca* image = scr->getCookedImage(); // get the image
+ gui->setImage(image,
+ scr->getLines(),
+ scr->getColumns()); // actual refresh
+ free(image);
+ //FIXME: check that we do not trigger other draw event here.
+ gui->setScroll(scr->getHistCursor(),scr->getHistLines());
+ }
+}
+
+void TEmulation::bulkStart()
+{
+ if (bulk_timer.isActive()) bulk_timer.stop();
+}
+
+void TEmulation::bulkEnd()
+{
+ if ( bulk_nlcnt > gui->Lines() || bulk_incnt > 20 )
+ showBulk(); // resets bulk_??cnt to 0, too.
+ else
+ bulk_timer.start(BULK_TIMEOUT,TRUE);
+}
+
+void TEmulation::setConnect(bool c)
+{
+ connected = c;
+ if ( connected)
+ {
+ onImageSizeChange(gui->Lines(), gui->Columns());
+ showBulk();
+ }
+ else
+ {
+ scr->clearSelection();
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+/*! triggered by image size change of the TEWidget `gui'.
+
+ This event is simply propagated to the attached screens
+ and to the related serial line.
+*/
+
+void TEmulation::onImageSizeChange(int lines, int columns)
+{
+ if (!connected) return;
+ screen[0]->resizeImage(lines,columns);
+ screen[1]->resizeImage(lines,columns);
+ showBulk();
+ emit ImageSizeChanged(lines,columns); // propagate event to serial line
+}
+
+void TEmulation::onHistoryCursorChange(int cursor)
+{
+ if (!connected) return;
+ scr->setHistCursor(cursor);
+ showBulk();
+}
+
+void TEmulation::setColumns(int columns)
+{
+ //FIXME: this goes strange ways.
+ // Can we put this straight or explain it at least?
+ emit changeColumns(columns);
+}
diff --git a/core/apps/embeddedkonsole/TEmulation.h b/core/apps/embeddedkonsole/TEmulation.h
new file mode 100644
index 0000000..ec15e7a
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEmulation.h
@@ -0,0 +1,117 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [emulation.h] Fundamental Terminal Emulation */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EMULATION_H
+#define EMULATION_H
+
+#include "TEWidget.h"
+#include "TEScreen.h"
+#include <qtimer.h>
+#include <stdio.h>
+#include <qtextcodec.h>
+#include "keytrans.h"
+
+class TEmulation : public QObject
+{ Q_OBJECT
+
+public:
+
+ TEmulation(TEWidget* gui);
+ ~TEmulation();
+
+public:
+ virtual void setHistory(bool on);
+ virtual bool history();
+
+public slots: // signals incoming from TEWidget
+
+ virtual void onImageSizeChange(int lines, int columns);
+ virtual void onHistoryCursorChange(int cursor);
+ virtual void onKeyPress(QKeyEvent*);
+
+ virtual void clearSelection();
+ virtual void onSelectionBegin(const int x, const int y);
+ virtual void onSelectionExtend(const int x, const int y);
+ virtual void setSelection(const BOOL preserve_line_breaks);
+
+public slots: // signals incoming from data source
+
+ void onRcvBlock(const char* txt,int len);
+
+signals:
+
+ void sndBlock(const char* txt,int len);
+ void ImageSizeChanged(int lines, int columns);
+ void changeColumns(int columns);
+ void changeTitle(int arg, const char* str);
+
+public:
+
+ virtual void onRcvChar(int);
+
+ virtual void setMode (int) = 0;
+ virtual void resetMode(int) = 0;
+
+ virtual void sendString(const char*) = 0;
+
+ virtual void setConnect(bool r);
+ void setColumns(int columns);
+
+ void setKeytrans(int no);
+ void setKeytrans(const char * no);
+
+protected:
+
+ TEWidget* gui;
+ TEScreen* scr; // referes to one `screen'
+ TEScreen* screen[2]; // 0 = primary, 1 = alternate
+ void setScreen(int n); // set `scr' to `screen[n]'
+
+ bool connected; // communicate with widget
+
+ void setCodec(int c); // codec number, 0 = locale, 1=utf8
+
+ QTextCodec* codec;
+ QTextCodec* localeCodec;
+ QTextDecoder* decoder;
+
+ KeyTrans* keytrans;
+
+// refreshing related material.
+// this is localized in the class.
+private slots: // triggered by timer
+
+ void showBulk();
+
+private:
+
+ void bulkNewline();
+ void bulkStart();
+ void bulkEnd();
+
+private:
+
+ QTimer bulk_timer;
+ int bulk_nlcnt; // bulk newline counter
+ char* SelectedText;
+ int bulk_incnt; // bulk counter
+
+
+};
+
+#endif // ifndef EMULATION_H
diff --git a/core/apps/embeddedkonsole/default.keytab.h b/core/apps/embeddedkonsole/default.keytab.h
new file mode 100644
index 0000000..503ea46
--- a/dev/null
+++ b/core/apps/embeddedkonsole/default.keytab.h
@@ -0,0 +1,103 @@
+ /* generated by '../tests/quote ../other/default.Keytab' */
+
+ "# [default.Keytab] Buildin Keyboard Table\n"
+ "\n"
+ "# --------------------------------------------------------------\n"
+ "#\n"
+ "# This file in included only for reference purposes. \n"
+ "#\n"
+ "# Modifying it does not have any effect (unless you\n"
+ "# derive the default.keytab.h and recompile konsole).\n"
+ "#\n"
+ "# To customize your keyboard, copy this file to something\n"
+ "# ending with .keytab and change it to meet you needs.\n"
+ "#\n"
+ "# --------------------------------------------------------------\n"
+ "\n"
+ "keyboard \"xterm (default)\"\n"
+ "\n"
+ "# --------------------------------------------------------------\n"
+ "#\n"
+ "# The syntax of each entry has the form\n"
+ "#\n"
+ "# \"key\" Keyname { (\"+\"|\"-\") Modename } \":\" (String|Operation)\n"
+ "#\n"
+ "# Keynames are those defined in <qnamespace.h>\n"
+ "# with the \"Qt::Key_\" prefix removed.\n"
+ "#\n"
+ "# Mode names are: Shift, Alt, Control.\n"
+ "#\n"
+ "# If the key is not found here, the text of the\n"
+ "# key event as provided by QT is emitted, possibly\n"
+ "# preceeded by ESC if the Alt key is pressed.\n"
+ "#\n"
+ "# --------------------------------------------------------------\n"
+ "#\n"
+ "# Note that this particular table is a \"risc\" version made to\n"
+ "# ease customization without bothering with obsolete details.\n"
+ "# See VT100.keytab for the more hairy stuff.\n"
+ "#\n"
+ "# --------------------------------------------------------------\n"
+ "\n"
+ "# common keys\n"
+ "\n"
+ "key Escape : \"\\E\"\n"
+ "key Tab : \"\\t\"\n"
+ "\n"
+ "key Return-Alt : \"\\r\"\n"
+ "key Return+Alt : \"\\E\\r\"\n"
+ "\n"
+ "# Backspace and Delete codes are preserving CTRL-H.\n"
+ "\n"
+ "key Backspace : \"\\x7f\"\n"
+ "\n"
+ "# cursor keys\n"
+ "\n"
+ "key Up -Shift : \"\\EOA\"\n"
+ "key Down -Shift : \"\\EOB\"\n"
+ "key Right -Shift : \"\\EOC\"\n"
+ "key Left -Shift : \"\\EOD\"\n"
+ "\n"
+ "# other grey PC keys\n"
+ "\n"
+ "key Enter : \"\\r\"\n"
+ "\n"
+ "key Home : \"\\E[1~\"\n"
+ "key Insert-Shift : \"\\E[2~\"\n"
+ "key Delete : \"\\E[3~\"\n"
+ "key End : \"\\E[4~\"\n"
+ "key Prior -Shift : \"\\E[5~\"\n"
+ "key Next -Shift : \"\\E[6~\"\n"
+ "\n"
+ "# function keys\n"
+ "\n"
+ "key F1 : \"\\E[11~\"\n"
+ "key F2 : \"\\E[12~\"\n"
+ "key F3 : \"\\E[13~\"\n"
+ "key F4 : \"\\E[14~\"\n"
+ "key F5 : \"\\E[15~\"\n"
+ "key F6 : \"\\E[17~\"\n"
+ "key F7 : \"\\E[18~\"\n"
+ "key F8 : \"\\E[19~\"\n"
+ "key F9 : \"\\E[20~\"\n"
+ "key F10 : \"\\E[21~\"\n"
+ "key F11 : \"\\E[23~\"\n"
+ "key F12 : \"\\E[24~\"\n"
+ "\n"
+ "# Work around dead keys\n"
+ "\n"
+ "key Space +Control : \"\\x00\"\n"
+ "\n"
+ "# Some keys are used by konsole to cause operations.\n"
+ "# The scroll* operations refer to the history buffer.\n"
+ "\n"
+ "key Left +Shift : prevSession\n"
+ "key Right +Shift : nextSession\n"
+ "key Up +Shift : scrollLineUp\n"
+ "key Prior +Shift : scrollPageUp\n"
+ "key Down +Shift : scrollLineDown\n"
+ "key Next +Shift : scrollPageDown\n"
+ "key Insert+Shift : emitSelection\n"
+ "\n"
+ "# keypad characters are not offered differently by Qt.\n"
+ ""
diff --git a/core/apps/embeddedkonsole/embeddedkonsole.pro b/core/apps/embeddedkonsole/embeddedkonsole.pro
new file mode 100755
index 0000000..b757ea5
--- a/dev/null
+++ b/core/apps/embeddedkonsole/embeddedkonsole.pro
@@ -0,0 +1,38 @@
+TEMPLATE = app
+
+CONFIG += qt warn_on release
+
+DESTDIR = $(QPEDIR)/bin
+
+HEADERS = TEWidget.h \
+ TEScreen.h \
+ TECommon.h \
+ TEHistory.h \
+ TEmulation.h \
+ TEmuVt102.h \
+ session.h \
+ keytrans.h \
+ konsole.h \
+ MyPty.h
+
+SOURCES = TEScreen.cpp \
+ TEWidget.cpp \
+ TEHistory.cpp \
+ TEmulation.cpp \
+ TEmuVt102.cpp \
+ session.cpp \
+ keytrans.cpp \
+ konsole.cpp \
+ main.cpp \
+ MyPty.cpp
+
+TARGET = embeddedkonsole
+
+INCLUDEPATH += $(QPEDIR)/include
+
+DEPENDPATH += $(QPEDIR)/include
+
+LIBS += -lqpe
+
+REQUIRES = embeddedkonsole
+
diff --git a/core/apps/embeddedkonsole/faded_bg.png b/core/apps/embeddedkonsole/faded_bg.png
new file mode 100644
index 0000000..7dbf6b4
--- a/dev/null
+++ b/core/apps/embeddedkonsole/faded_bg.png
Binary files differ
diff --git a/core/apps/embeddedkonsole/keytrans.cpp b/core/apps/embeddedkonsole/keytrans.cpp
new file mode 100644
index 0000000..d569ae0
--- a/dev/null
+++ b/core/apps/embeddedkonsole/keytrans.cpp
@@ -0,0 +1,706 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [keytrans.C] Keyboard Translation */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+/*
+ The keyboard translation table allows to configure konsoles behavior
+ on key strokes.
+
+ FIXME: some bug crept in, disallowing '\0' to be emitted.
+*/
+
+#include "keytrans.h"
+
+#include <qpe/qpeapplication.h>
+
+#include <qnamespace.h>
+#include <qbuffer.h>
+#include <qobject.h>
+#include <qdict.h>
+#include <qintdict.h>
+#include <qfile.h>
+#include <qglobal.h>
+#include <qdir.h>
+
+//#include <kstddirs.h>
+//nclude <klocale.h>
+
+#include <stdio.h>
+
+
+#undef USE_APPDATA_DIR
+
+
+#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
+
+/* KeyEntry
+
+ instances represent the individual assignments
+*/
+
+KeyTrans::KeyEntry::KeyEntry(int _ref, int _key, int _bits, int _mask, int _cmd, QString _txt)
+: ref(_ref), key(_key), bits(_bits), mask(_mask), cmd(_cmd), txt(_txt)
+{
+}
+
+KeyTrans::KeyEntry::~KeyEntry()
+{
+}
+
+bool KeyTrans::KeyEntry::matches(int _key, int _bits, int _mask)
+{ int m = mask & _mask;
+ return _key == key && (bits & m) == (_bits & m);
+}
+
+QString KeyTrans::KeyEntry::text()
+{
+ return txt;
+}
+
+/* KeyTrans
+
+ combines the individual assignments to a proper map
+ Takes part in a collection themself.
+*/
+
+KeyTrans::KeyTrans()
+{
+ path = "";
+ numb = 0;
+}
+
+KeyTrans::~KeyTrans()
+{
+}
+
+KeyTrans::KeyEntry* KeyTrans::addEntry(int ref, int key, int bits, int mask, int cmd, QString txt)
+// returns conflicting entry
+{
+ for (QListIterator<KeyEntry> it(table); it.current(); ++it)
+ {
+ if (it.current()->matches(key,bits,mask))
+ {
+ return it.current();
+ }
+ }
+ table.append(new KeyEntry(ref,key,bits,mask,cmd,txt));
+ return (KeyEntry*)NULL;
+}
+
+bool KeyTrans::findEntry(int key, int bits, int* cmd, const char** txt, int* len)
+{
+ for (QListIterator<KeyEntry> it(table); it.current(); ++it)
+ if (it.current()->matches(key,bits,0xffff))
+ {
+ *cmd = it.current()->cmd;
+ *txt = it.current()->txt.ascii();
+ *len = it.current()->txt.length();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Scanner for keyboard configuration */
+/* */
+/* ------------------------------------------------------------------------- */
+
+// regular tokenizer
+/* Tokens
+ - Spaces
+ - Name (A-Za-z0-9)+
+ - String
+ - Opr on of +-:
+*/
+
+#define SYMName 0
+#define SYMString 1
+#define SYMEol 2
+#define SYMEof 3
+#define SYMOpr 4
+#define SYMError 5
+
+#define inRange(L,X,H) ((L <= X) && (X <= H))
+#define isNibble(X) (inRange('A',X,'F')||inRange('a',X,'f')||inRange('0',X,'9'))
+#define convNibble(X) (inRange('0',X,'9')?X-'0':X+10-(inRange('A',X,'F')?'A':'a'))
+
+class KeytabReader
+{
+public:
+ KeytabReader(QString p, QIODevice &d);
+public:
+ void getCc();
+ void getSymbol();
+ void parseTo(KeyTrans* kt);
+ void ReportError(const char* msg);
+ void ReportToken(); // diagnostic
+private:
+ int sym;
+ QString res;
+ int len;
+ int slinno;
+ int scolno;
+private:
+ int cc;
+ int linno;
+ int colno;
+ QIODevice* buf;
+ QString path;
+};
+
+
+KeytabReader::KeytabReader(QString p, QIODevice &d)
+{
+ path = p;
+ buf = &d;
+ cc = 0;
+}
+
+void KeytabReader::getCc()
+{
+ if (cc == '\n') { linno += 1; colno = 0; }
+ if (cc < 0) return;
+ cc = buf->getch();
+ colno += 1;
+}
+
+void KeytabReader::getSymbol()
+{
+ res = ""; len = 0; sym = SYMError;
+ while (cc == ' ') getCc(); // skip spaces
+ if (cc == '#') // skip comment
+ {
+ while (cc != '\n' && cc > 0) getCc();
+ }
+ slinno = linno;
+ scolno = colno;
+ if (cc <= 0)
+ {
+ sym = SYMEof; return; // eos
+ }
+ if (cc == '\n')
+ {
+ getCc();
+ sym = SYMEol; return; // eol
+ }
+ if (inRange('A',cc,'Z')||inRange('a',cc,'z')||inRange('0',cc,'9'))
+ {
+ while (inRange('A',cc,'Z') || inRange('a',cc,'z') || inRange('0',cc,'9'))
+ {
+ res = res + (char)cc;
+ getCc();
+ }
+ sym = SYMName;
+ return;
+ }
+ if (strchr("+-:",cc))
+ {
+ res = "";
+ res = res + (char)cc;
+ getCc();
+ sym = SYMOpr; return;
+ }
+ if (cc == '"')
+ {
+ getCc();
+ while (cc >= ' ' && cc != '"')
+ { int sc;
+ if (cc == '\\') // handle quotation
+ {
+ getCc();
+ switch (cc)
+ {
+ case 'E' : sc = 27; getCc(); break;
+ case 'b' : sc = 8; getCc(); break;
+ case 'f' : sc = 12; getCc(); break;
+ case 't' : sc = 9; getCc(); break;
+ case 'r' : sc = 13; getCc(); break;
+ case 'n' : sc = 10; getCc(); break;
+ case '\\' : // fall thru
+ case '"' : sc = cc; getCc(); break;
+ case 'x' : getCc();
+ sc = 0;
+ if (!isNibble(cc)) return; sc = 16*sc + convNibble(cc); getCc();
+ if (!isNibble(cc)) return; sc = 16*sc + convNibble(cc); getCc();
+ break;
+ default : return;
+ }
+ }
+ else
+ {
+ // regular char
+ sc = cc; getCc();
+ }
+ res = res + (char)sc;
+ len = len + 1;
+ }
+ if (cc != '"') return;
+ getCc();
+ sym = SYMString; return;
+ }
+}
+
+void KeytabReader::ReportToken() // diagnostic
+{
+ printf("sym(%d): ",slinno);
+ switch(sym)
+ {
+ case SYMEol : printf("End of line"); break;
+ case SYMEof : printf("End of file"); break;
+ case SYMName : printf("Name: %s",res.latin1()); break;
+ case SYMOpr : printf("Opr : %s",res.latin1()); break;
+ case SYMString : printf("String len %d,%d ",res.length(),len);
+ for (unsigned i = 0; i < res.length(); i++)
+ printf(" %02x(%c)",res.latin1()[i],res.latin1()[i]>=' '?res.latin1()[i]:'?');
+ break;
+ }
+ printf("\n");
+}
+
+void KeytabReader::ReportError(const char* msg) // diagnostic
+{
+ fprintf(stderr,"%s(%d,%d):error: %s.\n",path.ascii(),slinno,scolno,msg);
+}
+
+// local symbol tables ---------------------------------------------------------------------
+
+class KeyTransSymbols
+{
+public:
+ KeyTransSymbols();
+protected:
+ void defOprSyms();
+ void defModSyms();
+ void defKeySyms();
+ void defKeySym(const char* key, int val);
+ void defOprSym(const char* key, int val);
+ void defModSym(const char* key, int val);
+public:
+ QDict<QObject> keysyms;
+ QDict<QObject> modsyms;
+ QDict<QObject> oprsyms;
+};
+
+static KeyTransSymbols * syms = 0L;
+
+// parser ----------------------------------------------------------------------------------
+/* Syntax
+ - Line :: [KeyName { ("+" | "-") ModeName } ":" (String|CommandName)] "\n"
+ - Comment :: '#' (any but \n)*
+*/
+
+KeyTrans* KeyTrans::fromDevice(QString path, QIODevice &buf)
+{
+ KeyTrans* kt = new KeyTrans;
+ kt->path = path;
+ KeytabReader ktr(path,buf); ktr.parseTo(kt);
+ return kt;
+}
+
+
+#define assertSyntax(Cond,Message) if (!(Cond)) { ReportError(Message); goto ERROR; }
+
+void KeytabReader::parseTo(KeyTrans* kt)
+{
+ // Opening sequence
+
+ buf->open(IO_ReadOnly);
+ getCc();
+ linno = 1;
+ colno = 1;
+ getSymbol();
+
+Loop:
+ // syntax: ["key" KeyName { ("+" | "-") ModeName } ":" String/CommandName] ["#" Comment]
+ if (sym == SYMName && !strcmp(res.latin1(),"keyboard"))
+ {
+ getSymbol(); assertSyntax(sym == SYMString, "Header expected")
+ kt->hdr = res.latin1();
+ getSymbol(); assertSyntax(sym == SYMEol, "Text unexpected")
+ getSymbol(); // eoln
+ goto Loop;
+ }
+ if (sym == SYMName && !strcmp(res.latin1(),"key"))
+ {
+//printf("line %3d: ",startofsym);
+ getSymbol(); assertSyntax(sym == SYMName, "Name expected")
+ assertSyntax(syms->keysyms[res], "Unknown key name")
+ int key = (int)syms->keysyms[res]-1;
+//printf(" key %s (%04x)",res.latin1(),(int)syms->keysyms[res]-1);
+ getSymbol(); // + - :
+ int mode = 0;
+ int mask = 0;
+ while (sym == SYMOpr && (!strcmp(res.latin1(),"+") || !strcmp(res.latin1(),"-")))
+ {
+ bool on = !strcmp(res.latin1(),"+");
+ getSymbol();
+ // mode name
+ assertSyntax(sym == SYMName, "Name expected")
+ assertSyntax(syms->modsyms[res], "Unknown mode name")
+ int bits = (int)syms->modsyms[res]-1;
+ if (mask & (1 << bits))
+ {
+ fprintf(stderr,"%s(%d,%d): mode name used multible times.\n",path.ascii(),slinno,scolno);
+ }
+ else
+ {
+ mode |= (on << bits);
+ mask |= (1 << bits);
+ }
+//printf(", mode %s(%d) %s",res.latin1(),(int)syms->modsyms[res]-1,on?"on":"off");
+ getSymbol();
+ }
+ assertSyntax(sym == SYMOpr && !strcmp(res.latin1(),":"), "':' expected")
+ getSymbol();
+ // string or command
+ assertSyntax(sym == SYMName || sym == SYMString,"Command or string expected")
+ int cmd = 0;
+ if (sym == SYMName)
+ {
+ assertSyntax(syms->oprsyms[res], "Unknown operator name")
+ cmd = (int)syms->oprsyms[res]-1;
+//printf(": do %s(%d)",res.latin1(),(int)syms->oprsyms[res]-1);
+ }
+ if (sym == SYMString)
+ {
+ cmd = CMD_send;
+//printf(": send");
+//for (unsigned i = 0; i < res.length(); i++)
+//printf(" %02x(%c)",res.latin1()[i],res.latin1()[i]>=' '?res.latin1()[i]:'?');
+ }
+//printf(". summary %04x,%02x,%02x,%d\n",key,mode,mask,cmd);
+ KeyTrans::KeyEntry* ke = kt->addEntry(slinno,key,mode,mask,cmd,res);
+ if (ke)
+ {
+ fprintf(stderr,"%s(%d): keystroke already assigned in line %d.\n",path.ascii(),slinno,ke->ref);
+ }
+ getSymbol();
+ assertSyntax(sym == SYMEol, "Unexpected text")
+ goto Loop;
+ }
+ if (sym == SYMEol)
+ {
+ getSymbol();
+ goto Loop;
+ }
+
+ assertSyntax(sym == SYMEof, "Undecodable Line")
+
+ buf->close();
+ return;
+
+ERROR:
+ while (sym != SYMEol && sym != SYMEof) getSymbol(); // eoln
+ goto Loop;
+}
+
+
+KeyTrans* KeyTrans::defaultKeyTrans()
+{
+ QCString txt =
+#include "default.keytab.h"
+ ;
+ QBuffer buf(txt);
+ return fromDevice("[buildin]",buf);
+}
+
+KeyTrans* KeyTrans::fromFile(const char* path)
+{
+ QFile file(path);
+ return fromDevice(path,file);
+}
+
+// local symbol tables ---------------------------------------------------------------------
+// material needed for parsing the config file.
+// This is incomplete work.
+
+void KeyTransSymbols::defKeySym(const char* key, int val)
+{
+ keysyms.insert(key,(QObject*)(val+1));
+}
+
+void KeyTransSymbols::defOprSym(const char* key, int val)
+{
+ oprsyms.insert(key,(QObject*)(val+1));
+}
+
+void KeyTransSymbols::defModSym(const char* key, int val)
+{
+ modsyms.insert(key,(QObject*)(val+1));
+}
+
+void KeyTransSymbols::defOprSyms()
+{
+ // Modifier
+ defOprSym("scrollLineUp", CMD_scrollLineUp );
+ defOprSym("scrollLineDown",CMD_scrollLineDown);
+ defOprSym("scrollPageUp", CMD_scrollPageUp );
+ defOprSym("scrollPageDown",CMD_scrollPageDown);
+ defOprSym("emitSelection", CMD_emitSelection );
+ defOprSym("prevSession", CMD_prevSession );
+ defOprSym("nextSession", CMD_nextSession );
+}
+
+void KeyTransSymbols::defModSyms()
+{
+ // Modifier
+ defModSym("Shift", BITS_Shift );
+ defModSym("Control", BITS_Control );
+ defModSym("Alt", BITS_Alt );
+ // Modes
+ defModSym("BsHack", BITS_BsHack ); // deprecated
+ defModSym("Ansi", BITS_Ansi );
+ defModSym("NewLine", BITS_NewLine );
+ defModSym("AppCuKeys", BITS_AppCuKeys );
+}
+
+void KeyTransSymbols::defKeySyms()
+{
+ // Grey keys
+ defKeySym("Escape", Qt::Key_Escape );
+ defKeySym("Tab", Qt::Key_Tab );
+ defKeySym("Backtab", Qt::Key_Backtab );
+ defKeySym("Backspace", Qt::Key_Backspace );
+ defKeySym("Return", Qt::Key_Return );
+ defKeySym("Enter", Qt::Key_Enter );
+ defKeySym("Insert", Qt::Key_Insert );
+ defKeySym("Delete", Qt::Key_Delete );
+ defKeySym("Pause", Qt::Key_Pause );
+ defKeySym("Print", Qt::Key_Print );
+ defKeySym("SysReq", Qt::Key_SysReq );
+ defKeySym("Home", Qt::Key_Home );
+ defKeySym("End", Qt::Key_End );
+ defKeySym("Left", Qt::Key_Left );
+ defKeySym("Up", Qt::Key_Up );
+ defKeySym("Right", Qt::Key_Right );
+ defKeySym("Down", Qt::Key_Down );
+ defKeySym("Prior", Qt::Key_Prior );
+ defKeySym("Next", Qt::Key_Next );
+ defKeySym("Shift", Qt::Key_Shift );
+ defKeySym("Control", Qt::Key_Control );
+ defKeySym("Meta", Qt::Key_Meta );
+ defKeySym("Alt", Qt::Key_Alt );
+ defKeySym("CapsLock", Qt::Key_CapsLock );
+ defKeySym("NumLock", Qt::Key_NumLock );
+ defKeySym("ScrollLock", Qt::Key_ScrollLock );
+ defKeySym("F1", Qt::Key_F1 );
+ defKeySym("F2", Qt::Key_F2 );
+ defKeySym("F3", Qt::Key_F3 );
+ defKeySym("F4", Qt::Key_F4 );
+ defKeySym("F5", Qt::Key_F5 );
+ defKeySym("F6", Qt::Key_F6 );
+ defKeySym("F7", Qt::Key_F7 );
+ defKeySym("F8", Qt::Key_F8 );
+ defKeySym("F9", Qt::Key_F9 );
+ defKeySym("F10", Qt::Key_F10 );
+ defKeySym("F11", Qt::Key_F11 );
+ defKeySym("F12", Qt::Key_F12 );
+ defKeySym("F13", Qt::Key_F13 );
+ defKeySym("F14", Qt::Key_F14 );
+ defKeySym("F15", Qt::Key_F15 );
+ defKeySym("F16", Qt::Key_F16 );
+ defKeySym("F17", Qt::Key_F17 );
+ defKeySym("F18", Qt::Key_F18 );
+ defKeySym("F19", Qt::Key_F19 );
+ defKeySym("F20", Qt::Key_F20 );
+ defKeySym("F21", Qt::Key_F21 );
+ defKeySym("F22", Qt::Key_F22 );
+ defKeySym("F23", Qt::Key_F23 );
+ defKeySym("F24", Qt::Key_F24 );
+ defKeySym("F25", Qt::Key_F25 );
+ defKeySym("F26", Qt::Key_F26 );
+ defKeySym("F27", Qt::Key_F27 );
+ defKeySym("F28", Qt::Key_F28 );
+ defKeySym("F29", Qt::Key_F29 );
+ defKeySym("F30", Qt::Key_F30 );
+ defKeySym("F31", Qt::Key_F31 );
+ defKeySym("F32", Qt::Key_F32 );
+ defKeySym("F33", Qt::Key_F33 );
+ defKeySym("F34", Qt::Key_F34 );
+ defKeySym("F35", Qt::Key_F35 );
+ defKeySym("Super_L", Qt::Key_Super_L );
+ defKeySym("Super_R", Qt::Key_Super_R );
+ defKeySym("Menu", Qt::Key_Menu );
+ defKeySym("Hyper_L", Qt::Key_Hyper_L );
+ defKeySym("Hyper_R", Qt::Key_Hyper_R );
+
+ // Regular keys
+ defKeySym("Space", Qt::Key_Space );
+ defKeySym("Exclam", Qt::Key_Exclam );
+ defKeySym("QuoteDbl", Qt::Key_QuoteDbl );
+ defKeySym("NumberSign", Qt::Key_NumberSign );
+ defKeySym("Dollar", Qt::Key_Dollar );
+ defKeySym("Percent", Qt::Key_Percent );
+ defKeySym("Ampersand", Qt::Key_Ampersand );
+ defKeySym("Apostrophe", Qt::Key_Apostrophe );
+ defKeySym("ParenLeft", Qt::Key_ParenLeft );
+ defKeySym("ParenRight", Qt::Key_ParenRight );
+ defKeySym("Asterisk", Qt::Key_Asterisk );
+ defKeySym("Plus", Qt::Key_Plus );
+ defKeySym("Comma", Qt::Key_Comma );
+ defKeySym("Minus", Qt::Key_Minus );
+ defKeySym("Period", Qt::Key_Period );
+ defKeySym("Slash", Qt::Key_Slash );
+ defKeySym("0", Qt::Key_0 );
+ defKeySym("1", Qt::Key_1 );
+ defKeySym("2", Qt::Key_2 );
+ defKeySym("3", Qt::Key_3 );
+ defKeySym("4", Qt::Key_4 );
+ defKeySym("5", Qt::Key_5 );
+ defKeySym("6", Qt::Key_6 );
+ defKeySym("7", Qt::Key_7 );
+ defKeySym("8", Qt::Key_8 );
+ defKeySym("9", Qt::Key_9 );
+ defKeySym("Colon", Qt::Key_Colon );
+ defKeySym("Semicolon", Qt::Key_Semicolon );
+ defKeySym("Less", Qt::Key_Less );
+ defKeySym("Equal", Qt::Key_Equal );
+ defKeySym("Greater", Qt::Key_Greater );
+ defKeySym("Question", Qt::Key_Question );
+ defKeySym("At", Qt::Key_At );
+ defKeySym("A", Qt::Key_A );
+ defKeySym("B", Qt::Key_B );
+ defKeySym("C", Qt::Key_C );
+ defKeySym("D", Qt::Key_D );
+ defKeySym("E", Qt::Key_E );
+ defKeySym("F", Qt::Key_F );
+ defKeySym("G", Qt::Key_G );
+ defKeySym("H", Qt::Key_H );
+ defKeySym("I", Qt::Key_I );
+ defKeySym("J", Qt::Key_J );
+ defKeySym("K", Qt::Key_K );
+ defKeySym("L", Qt::Key_L );
+ defKeySym("M", Qt::Key_M );
+ defKeySym("N", Qt::Key_N );
+ defKeySym("O", Qt::Key_O );
+ defKeySym("P", Qt::Key_P );
+ defKeySym("Q", Qt::Key_Q );
+ defKeySym("R", Qt::Key_R );
+ defKeySym("S", Qt::Key_S );
+ defKeySym("T", Qt::Key_T );
+ defKeySym("U", Qt::Key_U );
+ defKeySym("V", Qt::Key_V );
+ defKeySym("W", Qt::Key_W );
+ defKeySym("X", Qt::Key_X );
+ defKeySym("Y", Qt::Key_Y );
+ defKeySym("Z", Qt::Key_Z );
+ defKeySym("BracketLeft", Qt::Key_BracketLeft );
+ defKeySym("Backslash", Qt::Key_Backslash );
+ defKeySym("BracketRight", Qt::Key_BracketRight);
+ defKeySym("AsciiCircum", Qt::Key_AsciiCircum );
+ defKeySym("Underscore", Qt::Key_Underscore );
+ defKeySym("QuoteLeft", Qt::Key_QuoteLeft );
+ defKeySym("BraceLeft", Qt::Key_BraceLeft );
+ defKeySym("Bar", Qt::Key_Bar );
+ defKeySym("BraceRight", Qt::Key_BraceRight );
+ defKeySym("AsciiTilde", Qt::Key_AsciiTilde );
+}
+
+KeyTransSymbols::KeyTransSymbols()
+{
+ defModSyms();
+ defOprSyms();
+ defKeySyms();
+}
+
+// Global material -----------------------------------------------------------
+
+static int keytab_serial = 0; //FIXME: remove,localize
+
+static QIntDict<KeyTrans> * numb2keymap = 0L;
+static QDict<KeyTrans> * path2keymap = 0L;
+
+KeyTrans* KeyTrans::find(int numb)
+{
+ KeyTrans* res = numb2keymap->find(numb);
+ return res ? res : numb2keymap->find(0);
+}
+
+KeyTrans* KeyTrans::find(const char* path)
+{
+ KeyTrans* res = path2keymap->find(path);
+ return res ? res : numb2keymap->find(0);
+}
+
+int KeyTrans::count()
+{
+ return numb2keymap->count();
+}
+
+void KeyTrans::addKeyTrans()
+{
+ this->numb = keytab_serial ++;
+ numb2keymap->insert(numb,this);
+ path2keymap->insert(path,this);
+}
+
+void KeyTrans::loadAll()
+{
+ if (!numb2keymap)
+ numb2keymap = new QIntDict<KeyTrans>;
+ if (!path2keymap)
+ path2keymap = new QDict<KeyTrans>;
+ if (!syms)
+ syms = new KeyTransSymbols;
+
+ defaultKeyTrans()->addKeyTrans();
+
+
+ QString path = QPEApplication::qpeDir() + "etc/keytabs";
+ QDir dir(path);
+ QStringList lst = dir.entryList("*.keytab");
+
+ for(QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) {
+ QFile file(path + "/" + *it);
+ KeyTrans* sc = KeyTrans::fromDevice(*it, file);
+ if (sc) {
+ sc->addKeyTrans();
+ }
+ }
+
+}
+
+// Debugging material -----------------------------------------------------------
+/*
+void TestTokenizer(QBuffer &buf)
+{
+ // opening sequence
+
+ buf.open(IO_ReadOnly);
+ cc = buf.getch();
+ lineno = 1;
+
+ // Test tokenizer
+
+ while (getSymbol(buf)) ReportToken();
+
+ buf.close();
+}
+
+void test()
+{
+ // Opening sequence
+
+ QCString txt =
+#include "default.keytab.h"
+ ;
+ QBuffer buf(txt);
+ if (0) TestTokenizer(buf);
+ if (1) { KeyTrans kt; kt.scanTable(buf); }
+}
+*/
diff --git a/core/apps/embeddedkonsole/keytrans.h b/core/apps/embeddedkonsole/keytrans.h
new file mode 100644
index 0000000..ef6ed15
--- a/dev/null
+++ b/core/apps/embeddedkonsole/keytrans.h
@@ -0,0 +1,93 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [keytrans.h] X Terminal Emulation */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole - an X terminal for KDE */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef KEYTRANS_H
+#define KEYTRANS_H
+
+#include <qstring.h>
+#include <qlist.h>
+#include <qiodevice.h>
+
+#define BITS_NewLine 0
+#define BITS_BsHack 1
+#define BITS_Ansi 2
+#define BITS_AppCuKeys 3
+#define BITS_Control 4
+#define BITS_Shift 5
+#define BITS_Alt 6
+#define BITS_COUNT 7
+
+#define CMD_send 0
+#define CMD_emitSelection 1
+#define CMD_scrollPageUp 2
+#define CMD_scrollPageDown 3
+#define CMD_scrollLineUp 4
+#define CMD_scrollLineDown 5
+#define CMD_prevSession 6
+#define CMD_nextSession 7
+
+#define BITS(x,v) ((((v)!=0)<<(x)))
+
+
+class KeyTrans
+{
+public:
+ KeyTrans();
+ ~KeyTrans();
+ static KeyTrans* defaultKeyTrans();
+ static KeyTrans* fromFile(const char* path);
+ static KeyTrans* find(int numb);
+ static KeyTrans* find(const char* path);
+public:
+ static int count();
+ static void loadAll();
+public:
+ bool findEntry(int key, int bits, int* cmd, const char** txt, int* len);
+private:
+ void addKeyTrans();
+ static KeyTrans* fromDevice(QString path, QIODevice &buf);
+public:
+ class KeyEntry
+ {
+ public:
+ KeyEntry(int ref, int key, int bits, int mask, int cmd, QString txt);
+ ~KeyEntry();
+ public:
+ bool matches(int key, int bits, int mask);
+ QString text();
+ public:
+ int ref;
+ private:
+ int key;
+ int bits;
+ int mask;
+ public:
+ int cmd;
+ QString txt;
+ };
+public:
+ KeyEntry* addEntry(int ref, int key, int bits, int mask, int cmd, QString txt);
+private:
+ QList<KeyEntry> table;
+public: //FIXME: we'd do better
+ QString hdr;
+ int numb;
+ QString path;
+};
+
+#endif
diff --git a/core/apps/embeddedkonsole/konsole.cpp b/core/apps/embeddedkonsole/konsole.cpp
new file mode 100644
index 0000000..7253baf
--- a/dev/null
+++ b/core/apps/embeddedkonsole/konsole.cpp
@@ -0,0 +1,512 @@
+/* ---------------------------------------------------------------------- */
+/* */
+/* [main.C] Konsole */
+/* */
+/* ---------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole, an X terminal. */
+/* */
+/* The material contained in here more or less directly orginates from */
+/* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */
+/* */
+/* ---------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#include <qpe/resource.h>
+
+#include <qdir.h>
+#include <qevent.h>
+#include <qdragobject.h>
+#include <qobjectlist.h>
+#include <qtoolbutton.h>
+#include <qpe/qpetoolbar.h>
+#include <qpushbutton.h>
+#include <qfontdialog.h>
+#include <qglobal.h>
+#include <qpainter.h>
+#include <qpe/qpemenubar.h>
+#include <qmessagebox.h>
+#include <qaction.h>
+#include <qapplication.h>
+#include <qfontmetrics.h>
+#include <qcombobox.h>
+#include <qevent.h>
+#include <qtabwidget.h>
+#include <qtabbar.h>
+#include <qpe/config.h>
+
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "konsole.h"
+#include "keytrans.h"
+
+class EKNumTabBar : public QTabBar {
+public:
+ void numberTabs()
+ {
+ // Yes, it really is this messy. QTabWidget needs functions
+ // that provide acces to tabs in a sequential way.
+ int m=INT_MIN;
+ for (int i=0; i<count(); i++) {
+ QTab* left=0;
+ QListIterator<QTab> it(*tabList());
+ int x=INT_MAX;
+ for( QTab* t; (t=it.current()); ++it ) {
+ int tx = t->rect().x();
+ if ( tx<x && tx>m ) {
+ x = tx;
+ left = t;
+ }
+ }
+ if ( left ) {
+ left->setText(QString::number(i+1));
+ m = left->rect().x();
+ }
+ }
+ }
+};
+
+class EKNumTabWidget : public QTabWidget {
+public:
+ EKNumTabWidget(QWidget* parent) : QTabWidget(parent)
+ {
+ }
+
+ void addTab(QWidget* w)
+ {
+ QTab* t = new QTab(QString::number(tabBar()->count()+1));
+ QTabWidget::addTab(w,t);
+ }
+
+ void removeTab(QWidget* w)
+ {
+ removePage(w);
+ ((EKNumTabBar*)tabBar())->numberTabs();
+ }
+};
+
+// This could be configurable or dynamicly generated from the bash history
+// file of the user
+static const char *commonCmds[] =
+{
+ "ls ",
+ //"ls -la ",
+ "cd ",
+ "pwd",
+ //"cat",
+ //"less ",
+ //"vi ",
+ //"man ",
+ "echo ",
+ "set ",
+ //"ps",
+ "ps aux",
+ //"tar",
+ //"tar -zxf",
+ "grep ",
+ //"grep -i",
+ //"mkdir",
+ "cp ",
+ "mv ",
+ "rm ",
+ "rmdir ",
+ //"chmod",
+ //"su",
+// "top",
+ //"find",
+ //"make",
+ //"tail",
+ "cardctl eject",
+ "ifconfig ",
+// "iwconfig eth0 ",
+ "nc localhost 7777",
+ "nc localhost 7776",
+ //"mount /dev/hda1",
+
+/*
+ "gzip",
+ "gunzip",
+ "chgrp",
+ "chown",
+ "date",
+ "dd",
+ "df",
+ "dmesg",
+ "fuser",
+ "hostname",
+ "kill",
+ "killall",
+ "ln",
+ "ping",
+ "mount",
+ "more",
+ "sort",
+ "touch",
+ "umount",
+ "mknod",
+ "netstat",
+*/
+
+ "exit",
+ NULL
+};
+
+
+Konsole::Konsole(QWidget* parent, const char* name, WFlags fl) :
+ QMainWindow(parent, name, fl)
+{
+ QStrList args;
+ init("/bin/sh",args);
+}
+
+Konsole::Konsole(const char* name, const char* _pgm, QStrList & _args, int)
+ : QMainWindow(0, name)
+{
+ init(_pgm,_args);
+}
+
+void Konsole::init(const char* _pgm, QStrList & _args)
+{
+ b_scroll = TRUE; // histon;
+ n_keytab = 0;
+ n_render = 0;
+
+ setCaption( tr("Terminal") );
+ setIcon( Resource::loadPixmap( "konsole" ) );
+
+ Config cfg("Konsole");
+ cfg.setGroup("Konsole");
+
+ // initialize the list of allowed fonts ///////////////////////////////////
+ cfont = cfg.readNumEntry("FontID", 1);
+ QFont f = QFont("Micro", 4, QFont::Normal);
+ f.setFixedPitch(TRUE);
+ fonts.append(new VTFont(tr("Micro"), f));
+
+ f = QFont("Fixed", 7, QFont::Normal);
+ f.setFixedPitch(TRUE);
+ fonts.append(new VTFont(tr("Small Fixed"), f));
+
+ f = QFont("Fixed", 12, QFont::Normal);
+ f.setFixedPitch(TRUE);
+ fonts.append(new VTFont(tr("Medium Fixed"), f));
+
+ // create terminal emulation framework ////////////////////////////////////
+ nsessions = 0;
+ tab = new EKNumTabWidget(this);
+ tab->setTabPosition(QTabWidget::Bottom);
+ connect(tab, SIGNAL(currentChanged(QWidget*)), this, SLOT(switchSession(QWidget*)));
+
+ // create terminal toolbar ////////////////////////////////////////////////
+ setToolBarsMovable( FALSE );
+ QPEToolBar *menuToolBar = new QPEToolBar( this );
+ menuToolBar->setHorizontalStretchable( TRUE );
+
+ QPEMenuBar *menuBar = new QPEMenuBar( menuToolBar );
+
+ fontList = new QPopupMenu( this );
+ for(uint i = 0; i < fonts.count(); i++) {
+ VTFont *fnt = fonts.at(i);
+ fontList->insertItem(fnt->getName(), i);
+ }
+ fontChanged(cfont);
+
+ connect( fontList, SIGNAL( activated(int) ), this, SLOT( fontChanged(int) ));
+
+ menuBar->insertItem( tr("Font"), fontList );
+
+ QPEToolBar *toolbar = new QPEToolBar( this );
+
+ QAction *a;
+
+ // Button Commands
+ a = new QAction( tr("New"), Resource::loadPixmap( "konsole" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( newSession() ) ); a->addTo( toolbar );
+ a = new QAction( tr("Enter"), Resource::loadPixmap( "konsole/enter" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( hitEnter() ) ); a->addTo( toolbar );
+ a = new QAction( tr("Space"), Resource::loadPixmap( "konsole/space" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( hitSpace() ) ); a->addTo( toolbar );
+ a = new QAction( tr("Tab"), Resource::loadPixmap( "konsole/tab" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( hitTab() ) ); a->addTo( toolbar );
+ a = new QAction( tr("Up"), Resource::loadPixmap( "konsole/up" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar );
+ a = new QAction( tr("Down"), Resource::loadPixmap( "konsole/down" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar );
+ a = new QAction( tr("Paste"), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( hitPaste() ) ); a->addTo( toolbar );
+/*
+ a = new QAction( tr("Up"), Resource::loadPixmap( "up" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar );
+ a = new QAction( tr("Down"), Resource::loadPixmap( "down" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar );
+*/
+
+ QPEToolBar *secondToolBar = new QPEToolBar( this );
+ secondToolBar->setHorizontalStretchable( TRUE );
+
+ QComboBox *commonCombo = new QComboBox( secondToolBar );
+// commonCombo->setEditable( TRUE );
+ for (int i = 0; commonCmds[i] != NULL; i++)
+ commonCombo->insertItem( commonCmds[i], i );
+ connect( commonCombo, SIGNAL( activated(int) ), this, SLOT( enterCommand(int) ));
+
+ // create applications /////////////////////////////////////////////////////
+ setCentralWidget(tab);
+
+ // load keymaps ////////////////////////////////////////////////////////////
+ KeyTrans::loadAll();
+ for (int i = 0; i < KeyTrans::count(); i++)
+ { KeyTrans* s = KeyTrans::find(i);
+ assert( s );
+ }
+
+ se_pgm = _pgm;
+ se_args = _args;
+
+ // read and apply default values ///////////////////////////////////////////
+ resize(321, 321); // Dummy.
+ QSize currentSize = size();
+ if (currentSize != size())
+ defaultSize = size();
+}
+
+void Konsole::show()
+{
+ if ( !nsessions ) {
+ newSession();
+ }
+ QMainWindow::show();
+}
+
+void Konsole::initSession(const char*, QStrList &)
+{
+ QMainWindow::show();
+}
+
+Konsole::~Konsole()
+{
+ while (nsessions > 0) {
+ doneSession(getTe()->currentSession, 0);
+ }
+
+ Config cfg("Konsole");
+ cfg.setGroup("Konsole");
+ cfg.writeEntry("FontID", cfont);
+}
+
+void Konsole::fontChanged(int f)
+{
+ VTFont* font = fonts.at(f);
+ if (font != 0) {
+ for(uint i = 0; i < fonts.count(); i++) {
+ fontList->setItemChecked(i, (i == (uint) f) ? TRUE : FALSE);
+ }
+
+ cfont = f;
+
+ TEWidget* te = getTe();
+ if (te != 0) {
+ te->setVTFont(font->getFont());
+ }
+ }
+}
+
+void Konsole::enterCommand(int c)
+{
+ TEWidget* te = getTe();
+ if (te != 0) {
+ QString text = commonCmds[c];
+ te->emitText(text);
+ }
+}
+
+void Konsole::hitEnter()
+{
+ TEWidget* te = getTe();
+ if (te != 0) {
+ te->emitText(QString("\r"));
+ }
+}
+
+void Konsole::hitSpace()
+{
+ TEWidget* te = getTe();
+ if (te != 0) {
+ te->emitText(QString(" "));
+ }
+}
+
+void Konsole::hitTab()
+{
+ TEWidget* te = getTe();
+ if (te != 0) {
+ te->emitText(QString("\t"));
+ }
+}
+
+void Konsole::hitPaste()
+{
+ TEWidget* te = getTe();
+ if (te != 0) {
+ te->pasteClipboard();
+ }
+}
+
+void Konsole::hitUp()
+{
+ TEWidget* te = getTe();
+ if (te != 0) {
+ QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Up, 0, 0);
+ QApplication::sendEvent( te, &ke );
+ }
+}
+
+void Konsole::hitDown()
+{
+ TEWidget* te = getTe();
+ if (te != 0) {
+ QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Down, 0, 0);
+ QApplication::sendEvent( te, &ke );
+ }
+}
+
+/**
+ This function calculates the size of the external widget
+ needed for the internal widget to be
+ */
+QSize Konsole::calcSize(int columns, int lines) {
+ TEWidget* te = getTe();
+ if (te != 0) {
+ QSize size = te->calcSize(columns, lines);
+ return size;
+ } else {
+ QSize size;
+ return size;
+ }
+}
+
+/**
+ sets application window to a size based on columns X lines of the te
+ guest widget. Call with (0,0) for setting default size.
+*/
+
+void Konsole::setColLin(int columns, int lines)
+{
+ if ((columns==0) || (lines==0))
+ {
+ if (defaultSize.isEmpty()) // not in config file : set default value
+ {
+ defaultSize = calcSize(80,24);
+ // notifySize(24,80); // set menu items (strange arg order !)
+ }
+ resize(defaultSize);
+ } else {
+ resize(calcSize(columns, lines));
+ // notifySize(lines,columns); // set menu items (strange arg order !)
+ }
+}
+
+/*
+void Konsole::setFont(int fontno)
+{
+ QFont f;
+ if (fontno == 0)
+ f = defaultFont = QFont( "Helvetica", 12 );
+ else
+ if (fonts[fontno][0] == '-')
+ f.setRawName( fonts[fontno] );
+ else
+ {
+ f.setFamily(fonts[fontno]);
+ f.setRawMode( TRUE );
+ }
+ if ( !f.exactMatch() && fontno != 0)
+ {
+ QString msg = i18n("Font `%1' not found.\nCheck README.linux.console for help.").arg(fonts[fontno]);
+ QMessageBox(this, msg);
+ return;
+ }
+ if (se) se->setFontNo(fontno);
+ te->setVTFont(f);
+ n_font = fontno;
+}
+*/
+
+// --| color selection |-------------------------------------------------------
+
+void Konsole::changeColumns(int columns)
+{
+ TEWidget* te = getTe();
+ if (te != 0) {
+ setColLin(columns,te->Lines());
+ te->update();
+ }
+}
+
+//FIXME: If a child dies during session swap,
+// this routine might be called before
+// session swap is completed.
+
+void Konsole::doneSession(TESession*, int )
+{
+ TEWidget *te = getTe();
+ if (te != 0) {
+ te->currentSession->setConnect(FALSE);
+ tab->removeTab(te);
+ delete te->currentSession;
+ delete te;
+ nsessions--;
+ }
+
+ if (nsessions == 0) {
+ close();
+ }
+}
+
+
+void Konsole::newSession() {
+ TEWidget* te = new TEWidget(tab);
+ te->setBackgroundMode(PaletteBase);
+ te->setVTFont(fonts.at(cfont)->getFont());
+ tab->addTab(te);
+ TESession* se = new TESession(this, te, se_pgm, se_args, "xterm");
+ te->currentSession = se;
+ connect( se, SIGNAL(done(TESession*,int)), this, SLOT(doneSession(TESession*,int)) );
+ se->run();
+ se->setConnect(TRUE);
+ se->setHistory(b_scroll);
+ tab->setCurrentPage(nsessions);
+ nsessions++;
+}
+
+TEWidget* Konsole::getTe() {
+ if (nsessions) {
+ return (TEWidget *) tab->currentPage();
+ } else {
+ return 0;
+ }
+ }
+
+void Konsole::switchSession(QWidget* w) {
+ TEWidget* te = (TEWidget *) w;
+
+ QFont teFnt = te->getVTFont();
+ for(uint i = 0; i < fonts.count(); i++) {
+ VTFont *fnt = fonts.at(i);
+ bool cf = fnt->getFont() == teFnt;
+ fontList->setItemChecked(i, cf);
+ if (cf) {
+ cfont = i;
+ }
+ }
+}
diff --git a/core/apps/embeddedkonsole/konsole.h b/core/apps/embeddedkonsole/konsole.h
new file mode 100644
index 0000000..819ea5d
--- a/dev/null
+++ b/core/apps/embeddedkonsole/konsole.h
@@ -0,0 +1,125 @@
+/* ----------------------------------------------------------------------- */
+/* */
+/* [konsole.h] Konsole */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole, an X terminal. */
+/* */
+/* The material contained in here more or less directly orginates from */
+/* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef KONSOLE_H
+#define KONSOLE_H
+
+
+#include <qmainwindow.h>
+#include <qaction.h>
+#include <qpopupmenu.h>
+#include <qstrlist.h>
+#include <qintdict.h>
+#include <qptrdict.h>
+#include <qtabwidget.h>
+
+#include "MyPty.h"
+#include "TEWidget.h"
+#include "TEmuVt102.h"
+#include "session.h"
+
+class EKNumTabWidget;
+
+class Konsole : public QMainWindow
+{
+Q_OBJECT
+
+public:
+
+ Konsole(QWidget* parent = 0, const char* name = 0, WFlags fl = 0);
+ Konsole(const char * name, const char* pgm, QStrList & _args, int histon);
+ ~Konsole();
+ void setColLin(int columns, int lines);
+
+ void show();
+
+private slots:
+ void doneSession(TESession*,int);
+ void changeColumns(int);
+ void fontChanged(int);
+ void enterCommand(int);
+ void hitEnter();
+ void hitSpace();
+ void hitTab();
+ void hitPaste();
+ void hitUp();
+ void hitDown();
+ void switchSession(QWidget *);
+ void newSession();
+
+private:
+ void init(const char* _pgm, QStrList & _args);
+ void initSession(const char* _pgm, QStrList & _args);
+ void runSession(TESession* s);
+ void setColorPixmaps();
+ void setHistory(bool);
+ QSize calcSize(int columns, int lines);
+ TEWidget* getTe();
+
+private:
+ class VTFont
+ {
+ public:
+ VTFont(QString name, QFont& font)
+ {
+ this->name = name;
+ this->font = font;
+ }
+
+ QFont& getFont()
+ {
+ return font;
+ }
+
+ QString getName()
+ {
+ return name;
+ }
+
+ private:
+ QString name;
+ QFont font;
+ };
+
+ EKNumTabWidget* tab;
+ int nsessions;
+ QList<VTFont> fonts;
+ int cfont;
+ QCString se_pgm;
+ QStrList se_args;
+
+ QPopupMenu* fontList;
+
+ // history scrolling I think
+ bool b_scroll;
+
+ int n_keytab;
+ int n_scroll;
+ int n_render;
+ QString pmPath; // pixmap path
+ QString dropText;
+ QFont defaultFont;
+ QSize defaultSize;
+
+};
+
+#endif
+
diff --git a/core/apps/embeddedkonsole/main.cpp b/core/apps/embeddedkonsole/main.cpp
new file mode 100644
index 0000000..e3ba346
--- a/dev/null
+++ b/core/apps/embeddedkonsole/main.cpp
@@ -0,0 +1,60 @@
+/* ---------------------------------------------------------------------- */
+/* */
+/* [main.C] Konsole */
+/* */
+/* ---------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole, an X terminal. */
+/* */
+/* The material contained in here more or less directly orginates from */
+/* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */
+/* */
+/* ---------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#include "konsole.h"
+
+#include <qpe/qpeapplication.h>
+
+#include <qfile.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/* --| main |------------------------------------------------------ */
+int main(int argc, char* argv[])
+{
+ setuid(getuid()); setgid(getgid()); // drop privileges
+
+ QPEApplication a( argc, argv );
+
+#ifdef FAKE_CTRL_AND_ALT
+ QPEApplication::grabKeyboard(); // for CTRL and ALT
+#endif
+
+ QStrList tmp;
+ const char* shell = getenv("SHELL");
+ if (shell == NULL || *shell == '\0')
+ shell = "/bin/sh";
+
+ // sh is completely broken on familiar. Let's try to get something better
+ if ( qstrcmp( shell, "/bin/shell" ) == 0 && QFile::exists( "/bin/bash" ) )
+ shell = "/bin/bash";
+
+ putenv((char*)"COLORTERM="); // to trigger mc's color detection
+
+ Konsole m( "test", shell, tmp, TRUE );
+ m.setCaption( Konsole::tr("Terminal") );
+ a.showMainWidget( &m );
+
+ return a.exec();
+}
diff --git a/core/apps/embeddedkonsole/qpe-embeddedkonsole.control b/core/apps/embeddedkonsole/qpe-embeddedkonsole.control
new file mode 100644
index 0000000..9b7c355
--- a/dev/null
+++ b/core/apps/embeddedkonsole/qpe-embeddedkonsole.control
@@ -0,0 +1,9 @@
+Files: bin/embeddedkonsole apps/Applications/embeddedkonsole.desktop pics/konsole etc/keytabs/*
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-4
+Depends: qpe-base ($QPE_VERSION), ptydevs
+Description: KDE's konsole (shell terminal)
+ Ported to the Qtopia environment.
diff --git a/core/apps/embeddedkonsole/session.cpp b/core/apps/embeddedkonsole/session.cpp
new file mode 100644
index 0000000..520af86
--- a/dev/null
+++ b/core/apps/embeddedkonsole/session.cpp
@@ -0,0 +1,157 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+#include "session.h"
+#include <qpushbutton.h>
+// #include <kdebug.h>
+
+#include <stdlib.h>
+
+#define HERE fprintf(stderr,"%s(%d): here\n",__FILE__,__LINE__)
+
+/*! \class TESession
+
+ Sessions are combinations of TEPTy and Emulations.
+
+ The stuff in here does not belong to the terminal emulation framework,
+ but to main.C. It serves it's duty by providing a single reference
+ to TEPTy/Emulation pairs. In fact, it is only there to demonstrate one
+ of the abilities of the framework - multible sessions.
+*/
+
+TESession::TESession(QMainWindow* main, TEWidget* te, const char* _pgm, QStrList & _args, const char *_term) : schema_no(0), font_no(3), pgm(_pgm), args(_args)
+{
+ // sh = new TEPty();
+ sh = new MyPty();
+ em = new TEmuVt102(te);
+
+ term = _term;
+
+ sh->setSize(te->Lines(),te->Columns()); // not absolutely nessesary
+ QObject::connect( sh,SIGNAL(block_in(const char*,int)),
+ em,SLOT(onRcvBlock(const char*,int)) );
+ QObject::connect( em,SIGNAL(ImageSizeChanged(int,int)),
+ sh,SLOT(setSize(int,int)));
+
+ // 'main' should do those connects itself, somehow.
+ // These aren't KTMW's slots, but konsole's.(David)
+
+/*
+ QObject::connect( em,SIGNAL(ImageSizeChanged(int,int)),
+ main,SLOT(notifySize(int,int)));
+*/
+ QObject::connect( em,SIGNAL(sndBlock(const char*,int)),
+ sh,SLOT(send_bytes(const char*,int)) );
+ QObject::connect( em,SIGNAL(changeColumns(int)),
+ main,SLOT(changeColumns(int)) );
+/*
+ QObject::connect( em,SIGNAL(changeTitle(int, const QString&)),
+ main,SLOT(changeTitle(int, const QString&)) );
+*/
+ QObject::connect( sh,SIGNAL(done(int)), this,SLOT(done(int)) );
+}
+
+
+
+void TESession::run()
+{
+ //kdDebug() << "Running the session!" << pgm << "\n";
+ sh->run(pgm,args,term.data(),FALSE);
+}
+
+void TESession::kill(int ) // signal)
+{
+// sh->kill(signal);
+}
+
+TESession::~TESession()
+{
+ QObject::disconnect( sh, SIGNAL( done( int ) ),
+ this, SLOT( done( int ) ) );
+ delete em;
+ delete sh;
+}
+
+void TESession::setConnect(bool c)
+{
+ em->setConnect(c);
+}
+
+void TESession::done(int status)
+{
+ emit done(this,status);
+}
+
+void TESession::terminate()
+{
+ delete this;
+}
+
+TEmulation* TESession::getEmulation()
+{
+ return em;
+}
+
+// following interfaces might be misplaced ///
+
+int TESession::schemaNo()
+{
+ return schema_no;
+}
+
+int TESession::keymap()
+{
+ return keymap_no;
+}
+
+int TESession::fontNo()
+{
+ return font_no;
+}
+
+const char* TESession::emuName()
+{
+ return term.data();
+}
+
+void TESession::setSchemaNo(int sn)
+{
+ schema_no = sn;
+}
+
+void TESession::setKeymapNo(int kn)
+{
+ keymap_no = kn;
+ em->setKeytrans(kn);
+}
+
+void TESession::setFontNo(int fn)
+{
+ font_no = fn;
+}
+
+void TESession::setTitle(const QString& title)
+{
+ this->title = title;
+}
+
+const QString& TESession::Title()
+{
+ return title;
+}
+
+void TESession::setHistory(bool on)
+{
+ em->setHistory( on );
+}
+
+bool TESession::history()
+{
+ return em->history();
+}
+
+// #include "session.moc"
diff --git a/core/apps/embeddedkonsole/session.h b/core/apps/embeddedkonsole/session.h
new file mode 100644
index 0000000..4a61569
--- a/dev/null
+++ b/core/apps/embeddedkonsole/session.h
@@ -0,0 +1,93 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [session.h] Testbed for TE framework */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole, an X terminal. */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef SESSION_H
+#define SESSION_H
+
+#include <qapplication.h>
+#include <qmainwindow.h>
+#include <qstrlist.h>
+
+#include "MyPty.h"
+#include "TEWidget.h"
+#include "TEmuVt102.h"
+
+class TESession : public QObject
+{ Q_OBJECT
+
+public:
+
+ TESession(QMainWindow* main, TEWidget* w,
+ const char* pgm, QStrList & _args,
+ const char* term);
+ ~TESession();
+
+public:
+
+ void setConnect(bool r);
+ TEmulation* getEmulation(); // to control emulation
+ bool isSecure();
+
+public:
+
+ int schemaNo();
+ int fontNo();
+ const char* emuName();
+ const QString& Title();
+ bool history();
+ int keymap();
+
+ void setHistory(bool on);
+ void setSchemaNo(int sn);
+ void setKeymapNo(int kn);
+ void setFontNo(int fn);
+ void setTitle(const QString& title);
+ void kill(int signal);
+
+public slots:
+
+ void run();
+ void done(int status);
+ void terminate();
+
+signals:
+
+ void done(TESession*, int);
+
+private:
+
+ // TEPty* sh;
+ MyPty* sh;
+ TEWidget* te;
+ TEmulation* em;
+
+ //FIXME: using the indices here
+ // is propably very bad. We should
+ // use a persistent reference instead.
+ int schema_no;
+ int font_no;
+ int keymap_no;
+ QString title;
+
+ const char* pgm;
+ QStrList args;
+
+ QCString term;
+};
+
+#endif
diff --git a/core/apps/helpbrowser/.cvsignore b/core/apps/helpbrowser/.cvsignore
new file mode 100644
index 0000000..6fe2396
--- a/dev/null
+++ b/core/apps/helpbrowser/.cvsignore
@@ -0,0 +1,2 @@
+moc_*
+Makefile
diff --git a/core/apps/helpbrowser/Makefile.in b/core/apps/helpbrowser/Makefile.in
new file mode 100644
index 0000000..8f0ce0e
--- a/dev/null
+++ b/core/apps/helpbrowser/Makefile.in
@@ -0,0 +1,119 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = helpbrowser
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = helpbrowser.h
+SOURCES = helpbrowser.cpp \
+ main.cpp
+OBJECTS = helpbrowser.o \
+ main.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_helpbrowser.cpp
+OBJMOC = moc_helpbrowser.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake helpbrowser.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+helpbrowser.o: helpbrowser.cpp \
+ helpbrowser.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+main.o: main.cpp \
+ helpbrowser.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+moc_helpbrowser.o: moc_helpbrowser.cpp \
+ helpbrowser.h
+
+moc_helpbrowser.cpp: helpbrowser.h
+ $(MOC) helpbrowser.h -o moc_helpbrowser.cpp
+
+
diff --git a/core/apps/helpbrowser/helpbrowser.cpp b/core/apps/helpbrowser/helpbrowser.cpp
new file mode 100644
index 0000000..d32fc0b
--- a/dev/null
+++ b/core/apps/helpbrowser/helpbrowser.cpp
@@ -0,0 +1,227 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "helpbrowser.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/resource.h>
+#include <qpe/global.h>
+
+#include <qstatusbar.h>
+#include <qdragobject.h>
+#include <qpixmap.h>
+#include <qpopupmenu.h>
+#include <qpe/qpemenubar.h>
+#include <qpe/qpetoolbar.h>
+#include <qtoolbutton.h>
+#include <qiconset.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qstylesheet.h>
+#include <qmessagebox.h>
+#include <qfiledialog.h>
+#include <qevent.h>
+#include <qlineedit.h>
+#include <qobjectlist.h>
+#include <qfileinfo.h>
+#include <qfile.h>
+#include <qdatastream.h>
+#include <qprinter.h>
+#include <qsimplerichtext.h>
+#include <qpaintdevicemetrics.h>
+#include <qaction.h>
+
+#include <ctype.h>
+
+
+HelpBrowser::HelpBrowser( QWidget* parent, const char *name, WFlags f )
+ : QMainWindow( parent, name, f ),
+ selectedURL()
+{
+ init( "index.html" );
+}
+
+void HelpBrowser::init( const QString& _home )
+{
+ setIcon( Resource::loadPixmap( "help_icon" ) );
+
+ browser = new QTextBrowser( this );
+ browser->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ connect( browser, SIGNAL( textChanged() ),
+ this, SLOT( textChanged() ) );
+
+ setCentralWidget( browser );
+ setToolBarsMovable( FALSE );
+
+ if ( !_home.isEmpty() )
+ browser->setSource( _home );
+
+ QPEToolBar* toolbar = new QPEToolBar( this );
+ toolbar->setHorizontalStretchable( TRUE );
+ QPEMenuBar *menu = new QPEMenuBar( toolbar );
+
+ toolbar = new QPEToolBar( this );
+ // addToolBar( toolbar, "Toolbar");
+
+ //QPopupMenu* go = new QPopupMenu( this );
+ backAction = new QAction( tr( "Backward" ), Resource::loadIconSet( "back" ), QString::null, 0, this, 0 );
+ connect( backAction, SIGNAL( activated() ), browser, SLOT( backward() ) );
+ connect( browser, SIGNAL( backwardAvailable( bool ) ),
+ backAction, SLOT( setEnabled( bool ) ) );
+ //backAction->addTo( go );
+ backAction->addTo( toolbar );
+ backAction->setEnabled( FALSE );
+
+ forwardAction = new QAction( tr( "Forward" ), Resource::loadIconSet( "forward" ), QString::null, 0, this, 0 );
+ connect( forwardAction, SIGNAL( activated() ), browser, SLOT( forward() ) );
+ connect( browser, SIGNAL( forwardAvailable( bool ) ),
+ forwardAction, SLOT( setEnabled( bool ) ) );
+ //forwardAction->addTo( go );
+ forwardAction->addTo( toolbar );
+ forwardAction->setEnabled( FALSE );
+
+ QAction *a = new QAction( tr( "Home" ), Resource::loadPixmap( "home" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), browser, SLOT( home() ) );
+ //a->addTo( go );
+ a->addTo( toolbar );
+
+ bookm = new QPopupMenu( this );
+ bookm->insertItem( tr( "Add Bookmark" ), this, SLOT( addBookmark() ) );
+ bookm->insertItem( tr( "Remove from Bookmarks" ), this, SLOT( removeBookmark() ) );
+ bookm->insertSeparator();
+ connect( bookm, SIGNAL( activated( int ) ),
+ this, SLOT( bookmChosen( int ) ) );
+
+ readBookmarks();
+
+ //menu->insertItem( tr("Go"), go );
+ menu->insertItem( tr( "Bookmarks" ), bookm );
+
+ resize( 240, 300 );
+ browser->setFocus();
+
+ connect( qApp, SIGNAL(appMessage(const QCString&, const QByteArray&)),
+ this, SLOT(appMessage(const QCString&, const QByteArray&)) );
+}
+
+void HelpBrowser::appMessage(const QCString& msg, const QByteArray& data)
+{
+ if ( msg == "showFile(QString)" ) {
+ QDataStream ds(data,IO_ReadOnly);
+ QString fn;
+ ds >> fn;
+ setDocument( fn );
+ }
+}
+
+void HelpBrowser::setDocument( const QString &doc )
+{
+ if ( !doc.isEmpty() )
+ browser->setSource( doc );
+ raise();
+}
+
+
+void HelpBrowser::textChanged()
+{
+ if ( browser->documentTitle().isNull() )
+ setCaption( tr("Help Browser") );
+ else
+ setCaption( browser->documentTitle() ) ;
+
+ selectedURL = caption();
+}
+
+HelpBrowser::~HelpBrowser()
+{
+ QStringList bookmarks;
+ QMap<int, Bookmark>::Iterator it2 = mBookmarks.begin();
+ for ( ; it2 != mBookmarks.end(); ++it2 )
+ bookmarks.append( (*it2).name + "=" + (*it2).file );
+
+ QFile f2( Global::applicationFileName("helpbrowser", "bookmarks") );
+ if ( f2.open( IO_WriteOnly ) ) {
+ QDataStream s2( &f2 );
+ s2 << bookmarks;
+ f2.close();
+ }
+}
+
+void HelpBrowser::pathSelected( const QString &_path )
+{
+ browser->setSource( _path );
+}
+
+void HelpBrowser::readBookmarks()
+{
+ QString file = Global::applicationFileName("helpbrowser", "bookmarks");
+ if ( QFile::exists( file ) ) {
+ QStringList bookmarks;
+ QFile f( file );
+ if ( f.open( IO_ReadOnly ) ) {
+ QDataStream s( &f );
+ s >> bookmarks;
+ f.close();
+ }
+ QStringList::Iterator it = bookmarks.begin();
+ for ( ; it != bookmarks.end(); ++it ) {
+ Bookmark b;
+ QString current = *it;
+ int equal = current.find( "=" );
+ if ( equal < 1 || equal == (int)current.length() - 1 )
+ continue;
+ b.name = current.left( equal );
+ b.file = current.mid( equal + 1 );
+ mBookmarks[ bookm->insertItem( b.name ) ] = b;
+ }
+ }
+}
+
+void HelpBrowser::bookmChosen( int i )
+{
+ if ( mBookmarks.contains( i ) )
+ browser->setSource( mBookmarks[ i ].file );
+}
+
+void HelpBrowser::addBookmark()
+{
+ Bookmark b;
+ b.name = browser->documentTitle();
+ b.file = browser->source();
+ if (b.name.isEmpty() ) {
+ b.name = b.file.left( b.file.length() - 5 ); // remove .html
+ }
+ QMap<int, Bookmark>::Iterator it;
+ for( it = mBookmarks.begin(); it != mBookmarks.end(); ++it )
+ if ( (*it).file == b.file ) return;
+ mBookmarks[ bookm->insertItem( b.name ) ] = b;
+}
+
+void HelpBrowser::removeBookmark()
+{
+ QString file = browser->source();
+ QMap<int, Bookmark>::Iterator it = mBookmarks.begin();
+ for( ; it != mBookmarks.end(); ++it )
+ if ( (*it).file == file ) {
+ bookm->removeItem( it.key() );
+ mBookmarks.remove( it );
+ break;
+ }
+}
diff --git a/core/apps/helpbrowser/helpbrowser.h b/core/apps/helpbrowser/helpbrowser.h
new file mode 100644
index 0000000..2f7153a
--- a/dev/null
+++ b/core/apps/helpbrowser/helpbrowser.h
@@ -0,0 +1,69 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef HELPWINDOW_H
+#define HELPWINDOW_H
+
+#include <qmainwindow.h>
+#include <qtextbrowser.h>
+#include <qstringlist.h>
+#include <qmap.h>
+
+class QPopupMenu;
+class QAction;
+
+class HelpBrowser : public QMainWindow
+{
+ Q_OBJECT
+public:
+ HelpBrowser( QWidget* parent = 0, const char *name=0, WFlags f=0 );
+ ~HelpBrowser();
+
+public slots:
+ void setDocument( const QString &doc );
+
+private slots:
+ void appMessage(const QCString& msg, const QByteArray& data);
+ void textChanged();
+
+ void pathSelected( const QString & );
+ void bookmChosen( int );
+ void addBookmark();
+ void removeBookmark();
+
+private:
+ void init( const QString & );
+ void readBookmarks();
+
+ QTextBrowser* browser;
+ QAction *backAction;
+ QAction *forwardAction;
+ QString selectedURL;
+ struct Bookmark {
+ QString name;
+ QString file;
+ };
+ QMap<int, Bookmark> mBookmarks;
+ QMenuBar *menu;
+ QPopupMenu *bookm;
+};
+
+#endif
+
diff --git a/core/apps/helpbrowser/helpbrowser.pro b/core/apps/helpbrowser/helpbrowser.pro
new file mode 100644
index 0000000..43230f1
--- a/dev/null
+++ b/core/apps/helpbrowser/helpbrowser.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = helpbrowser.h
+SOURCES = helpbrowser.cpp \
+ main.cpp
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+INTERFACES =
+
+TRANSLATIONS = ../i18n/de/helpbrowser.ts
diff --git a/core/apps/helpbrowser/main.cpp b/core/apps/helpbrowser/main.cpp
new file mode 100644
index 0000000..1cb10b7
--- a/dev/null
+++ b/core/apps/helpbrowser/main.cpp
@@ -0,0 +1,34 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "helpbrowser.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char ** argv )
+{
+ QPEApplication a( argc, argv );
+
+ HelpBrowser mw;
+ mw.setCaption( HelpBrowser::tr("HelpBrowser") );
+ a.showMainDocumentWidget( &mw );
+
+ return a.exec();
+}
diff --git a/core/apps/helpbrowser/qpe-helpbrowser.control b/core/apps/helpbrowser/qpe-helpbrowser.control
new file mode 100644
index 0000000..b6e3404
--- a/dev/null
+++ b/core/apps/helpbrowser/qpe-helpbrowser.control
@@ -0,0 +1,10 @@
+Files: bin/helpbrowser apps/Applications/helpbrowser.desktop docs
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Arch: iPAQ
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Browse HTML help documents
+ The HTML help browser for the Qtopia environment.
diff --git a/core/apps/qcop/.cvsignore b/core/apps/qcop/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/core/apps/qcop/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile
diff --git a/core/apps/qcop/Makefile.in b/core/apps/qcop/Makefile.in
new file mode 100644
index 0000000..0a12320
--- a/dev/null
+++ b/core/apps/qcop/Makefile.in
@@ -0,0 +1,102 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = qcop
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS =
+SOURCES = main.cpp
+OBJECTS = main.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC =
+OBJMOC =
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake qcop.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h
+
+
diff --git a/core/apps/qcop/main.cpp b/core/apps/qcop/main.cpp
new file mode 100644
index 0000000..73db0f6
--- a/dev/null
+++ b/core/apps/qcop/main.cpp
@@ -0,0 +1,85 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpe/qcopenvelope_qws.h>
+
+#include <qapplication.h>
+#include <qstringlist.h>
+#include <qdatastream.h>
+#include <qtimer.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+static void usage()
+{
+ fprintf( stderr, "Usage: qcop channel command [parameters]\n" );
+}
+
+static void syntax( const QString &where, const QString &what )
+{
+ fprintf( stderr, "Syntax error in %s: %s\n", where.latin1(), what.latin1() );
+ exit(1);
+}
+
+int main( int argc, char *argv[] )
+{
+ QApplication app( argc, argv );
+
+ if ( argc < 3 ) {
+ usage();
+ exit(1);
+ }
+
+ QString channel = argv[1];
+ QString command = argv[2];
+ command.stripWhiteSpace();
+
+ int paren = command.find( "(" );
+ if ( paren <= 0 )
+ syntax( "command", command );
+
+ QString params = command.mid( paren + 1 );
+ if ( params[params.length()-1] != ')' )
+ syntax( "command", command );
+
+ params.truncate( params.length()-1 );
+ QCopEnvelope env(channel.latin1(), command.latin1());
+
+ int argIdx = 3;
+
+ QStringList paramList = QStringList::split( ",", params );
+ QStringList::Iterator it;
+ for ( it = paramList.begin(); it != paramList.end(); ++it ) {
+ QString arg = argv[argIdx];
+ if ( *it == "QString" ) {
+ env << arg;
+ } else if ( *it == "int" ) {
+ env << arg.toInt();
+ } else {
+ syntax( "paramter type", *it );
+ }
+ argIdx++;
+ }
+
+ QTimer::singleShot( 0, &app, SLOT(quit()) );
+ return app.exec();
+}
+
diff --git a/core/apps/qcop/qcop.pro b/core/apps/qcop/qcop.pro
new file mode 100644
index 0000000..b52bfd8
--- a/dev/null
+++ b/core/apps/qcop/qcop.pro
@@ -0,0 +1,10 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = ../bin
+HEADERS =
+SOURCES = main.cpp
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+INTERFACES =
+TARGET = qcop
diff --git a/core/apps/qcop/qpe-qcop.control b/core/apps/qcop/qpe-qcop.control
new file mode 100644
index 0000000..60107c4
--- a/dev/null
+++ b/core/apps/qcop/qpe-qcop.control
@@ -0,0 +1,9 @@
+Files: bin/qcop
+Priority: required
+Section: qpe/system
+Maintainer: Martin Jones <mjones@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qt-embedded (>=$QTE_VERSION)
+Description: Interprocess communication client
+ Interprocess communication client for the Qtopia environment.
diff --git a/core/apps/textedit/.cvsignore b/core/apps/textedit/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/core/apps/textedit/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile
diff --git a/core/apps/textedit/Makefile.in b/core/apps/textedit/Makefile.in
new file mode 100644
index 0000000..84542bb
--- a/dev/null
+++ b/core/apps/textedit/Makefile.in
@@ -0,0 +1,125 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = textedit
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = textedit.h
+SOURCES = main.cpp \
+ textedit.cpp
+OBJECTS = main.o \
+ textedit.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_textedit.cpp
+OBJMOC = moc_textedit.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake textedit.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ textedit.h \
+ $(QPEDIR)/include/qpe/filemanager.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+textedit.o: textedit.cpp \
+ textedit.h \
+ $(QPEDIR)/include/qpe/filemanager.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/fileselector.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+moc_textedit.o: moc_textedit.cpp \
+ textedit.h \
+ $(QPEDIR)/include/qpe/filemanager.h
+
+moc_textedit.cpp: textedit.h
+ $(MOC) textedit.h -o moc_textedit.cpp
+
+
diff --git a/core/apps/textedit/inserttable.ui b/core/apps/textedit/inserttable.ui
new file mode 100644
index 0000000..09fe3c3
--- a/dev/null
+++ b/core/apps/textedit/inserttable.ui
@@ -0,0 +1,103 @@
+<!DOCTYPE UI><UI>
+<class>InsertTable</class><comment>*********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+*********************************************************************</comment>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>InsertTable</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>165</width>
+ <height>79</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Insert Table</string>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="0" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Rows:</string>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinRows</cstring>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>1</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>1</number>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinColumns</cstring>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>1</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>1</number>
+ </property>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Columns:</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+</UI>
diff --git a/core/apps/textedit/main.cpp b/core/apps/textedit/main.cpp
new file mode 100644
index 0000000..d0d37d2
--- a/dev/null
+++ b/core/apps/textedit/main.cpp
@@ -0,0 +1,35 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "textedit.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char **argv )
+{
+ QPEApplication a( argc, argv );
+
+ TextEdit e;
+ a.showMainDocumentWidget(&e);
+ if ( argc == 3 && argv[1] == QCString("-f") )
+ e.openFile(argv[2]);
+
+ a.exec();
+}
diff --git a/core/apps/textedit/qpe-textedit.control b/core/apps/textedit/qpe-textedit.control
new file mode 100644
index 0000000..b0dad7d
--- a/dev/null
+++ b/core/apps/textedit/qpe-textedit.control
@@ -0,0 +1,9 @@
+Files: bin/textedit apps/Applications/textedit.desktop
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Text Editor
+ The text editor for the Qtopia environment.
diff --git a/core/apps/textedit/qtextedit.h b/core/apps/textedit/qtextedit.h
new file mode 100644
index 0000000..b29a728
--- a/dev/null
+++ b/core/apps/textedit/qtextedit.h
@@ -0,0 +1,282 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef QTEXTEDIT_H
+#define QTEXTEDIT_H
+
+#include <qscrollview.h>
+#include <qstylesheet.h>
+#include <qpainter.h>
+
+class QPainter;
+class QTextDocument;
+class QTextCursor;
+class QKeyEvent;
+class QResizeEvent;
+class QMouseEvent;
+class QTimer;
+class QTextString;
+class QVBox;
+class QListBox;
+class QTextCommand;
+class QTextParag;
+class QTextFormat;
+class QFont;
+class QColor;
+
+class QTextEdit : public QScrollView
+{
+ Q_OBJECT
+
+public:
+ QTextEdit( QWidget *parent, const QString &fn, bool tabify = FALSE );
+ QTextEdit( QWidget *parent = 0, const char *name = 0 );
+ virtual ~QTextEdit();
+
+#if defined(QTEXTEDIT_OPEN_API)
+ QTextDocument *document() const;
+ QTextCursor *textCursor() const;
+#endif
+
+ QString text() const;
+ QString text( int parag, bool formatted = FALSE ) const;
+ Qt::TextFormat textFormat() const;
+ QString fileName() const;
+
+ void cursorPosition( int &parag, int &index );
+ void selection( int &parag_from, int &index_from,
+ int &parag_to, int &index_to );
+ virtual bool find( const QString &expr, bool cs, bool wo, bool forward = TRUE,
+ int *parag = 0, int *index = 0 );
+ void insert( const QString &text, bool indent = FALSE, bool checkNewLine = FALSE );
+
+ int paragraphs() const;
+ int lines() const;
+ int linesOfParagraph( int parag ) const;
+ int lineOfChar( int parag, int chr );
+
+ bool isModified() const;
+
+ bool italic() const;
+ bool bold() const;
+ bool underline() const;
+ QString family() const;
+ int pointSize() const;
+ QColor color() const;
+ QFont font() const;
+ int alignment() const;
+ int maxLines() const;
+
+ const QStyleSheet* styleSheet() const;
+ void setStyleSheet( const QStyleSheet* styleSheet );
+
+ void setPaper( const QBrush& pap);
+ QBrush paper() const;
+
+ void setLinkColor( const QColor& );
+ QColor linkColor() const;
+
+ void setLinkUnderline( bool );
+ bool linkUnderline() const;
+
+ void setMimeSourceFactory( const QMimeSourceFactory* factory );
+ const QMimeSourceFactory* mimeSourceFactory() const;
+
+ int heightForWidth( int w ) const;
+
+ void append( const QString& text );
+
+ bool hasSelectedText() const;
+ QString selectedText() const;
+
+ QString context() const;
+
+ QString documentTitle() const;
+
+ void scrollToAnchor( const QString& name );
+ QString anchorAt(const QPoint& pos);
+
+public slots:
+ virtual void undo();
+ virtual void redo();
+
+ virtual void cut();
+ virtual void copy();
+ virtual void paste();
+
+ virtual void indent();
+
+ virtual void setItalic( bool b );
+ virtual void setBold( bool b );
+ virtual void setUnderline( bool b );
+ virtual void setFamily( const QString &f );
+ virtual void setPointSize( int s );
+ virtual void setColor( const QColor &c );
+ virtual void setFont( const QFont &f );
+
+ virtual void setAlignment( int );
+
+ virtual void setParagType( QStyleSheetItem::DisplayMode, int listStyle );
+
+ virtual void setTextFormat( Qt::TextFormat f );
+ virtual void setText( const QString &txt, const QString &context = QString::null ) { setText( txt, context, FALSE ); }
+ virtual void setText( const QString &txt, const QString &context, bool tabify );
+
+ virtual void load( const QString &fn ) { load( fn, FALSE ); }
+ virtual void load( const QString &fn, bool tabify );
+ virtual void save( bool untabify = FALSE ) { save( QString::null, untabify ); }
+ virtual void save( const QString &fn, bool untabify = FALSE );
+
+ virtual void setCursorPosition( int parag, int index );
+ virtual void setSelection( int parag_from, int index_from,
+ int parag_to, int index_to );
+
+ virtual void setModified( bool m );
+ virtual void selectAll( bool select );
+
+ virtual void setMaxLines( int l );
+ virtual void resetFormat();
+
+signals:
+ void currentFontChanged( const QFont &f );
+ void currentColorChanged( const QColor &c );
+ void currentAlignmentChanged( int );
+ void textChanged();
+ void highlighted( const QString& );
+ void linkClicked( const QString& );
+
+protected:
+ void setFormat( QTextFormat *f, int flags );
+ void drawContents( QPainter *p, int cx, int cy, int cw, int ch );
+ void keyPressEvent( QKeyEvent *e );
+ void resizeEvent( QResizeEvent *e );
+ void contentsMousePressEvent( QMouseEvent *e );
+ void contentsMouseMoveEvent( QMouseEvent *e );
+ void contentsMouseReleaseEvent( QMouseEvent *e );
+ void contentsMouseDoubleClickEvent( QMouseEvent *e );
+#ifndef QT_NO_DRAGANDDROP
+ void contentsDragEnterEvent( QDragEnterEvent *e );
+ void contentsDragMoveEvent( QDragMoveEvent *e );
+ void contentsDragLeaveEvent( QDragLeaveEvent *e );
+ void contentsDropEvent( QDropEvent *e );
+#endif
+ bool eventFilter( QObject *o, QEvent *e );
+ bool focusNextPrevChild( bool next );
+#if !defined(QTEXTEDIT_OPEN_API)
+ QTextDocument *document() const;
+ QTextCursor *textCursor() const;
+#endif
+
+private slots:
+ void formatMore();
+ void doResize();
+ void doAutoScroll();
+ void doChangeInterval();
+ void blinkCursor();
+ void setModified();
+ void startDrag();
+
+private:
+ enum MoveDirection {
+ MoveLeft,
+ MoveRight,
+ MoveUp,
+ MoveDown,
+ MoveHome,
+ MoveEnd,
+ MovePgUp,
+ MovePgDown
+ };
+ enum KeyboardAction {
+ ActionBackspace,
+ ActionDelete,
+ ActionReturn
+ };
+
+ struct UndoRedoInfo {
+ enum Type { Invalid, Insert, Delete, Backspace, Return, RemoveSelected };
+ UndoRedoInfo( QTextDocument *d ) : type( Invalid ), doc( d )
+ { text = QString::null; id = -1; index = -1; }
+ void clear();
+ inline bool valid() const { return !text.isEmpty() && id >= 0&& index >= 0; }
+
+ QString text;
+ int id;
+ int index;
+ Type type;
+ QTextDocument *doc;
+ };
+
+private:
+ virtual bool isReadOnly() const { return FALSE; }
+ virtual bool linksEnabled() const { return TRUE; }
+ void init();
+ void ensureCursorVisible();
+ void drawCursor( bool visible );
+ void placeCursor( const QPoint &pos, QTextCursor *c = 0 );
+ void moveCursor( int direction, bool shift, bool control );
+ void moveCursor( int direction, bool control );
+ void removeSelectedText();
+ void doKeyboardAction( int action );
+ bool doCompletion();
+ void checkUndoRedoInfo( UndoRedoInfo::Type t );
+ void repaintChanged();
+ void updateCurrentFormat();
+ void handleReadOnlyKeyEvent( QKeyEvent *e );
+ void makeParagVisible( QTextParag *p );
+
+private:
+ QTextDocument *doc;
+ QTextCursor *cursor;
+ bool drawAll;
+ bool mousePressed;
+ QTimer *formatTimer, *scrollTimer, *changeIntervalTimer, *blinkTimer, *dragStartTimer, *resizeTimer;
+ QTextParag *lastFormatted;
+ int interval;
+ QVBox *completionPopup;
+ QListBox *completionListBox;
+ int completionOffset;
+ UndoRedoInfo undoRedoInfo;
+ QTextFormat *currentFormat;
+ QPainter painter;
+ int currentAlignment;
+ bool inDoubleClick;
+ QPoint oldMousePos, mousePos;
+ QPixmap *buf_pixmap;
+ bool cursorVisible, blinkCursorVisible;
+ bool readOnly, modified, mightStartDrag;
+ QPoint dragStartPos;
+ int mLines;
+ bool firstResize;
+ QString onLink;
+
+};
+
+inline QTextDocument *QTextEdit::document() const
+{
+ return doc;
+}
+
+inline QTextCursor *QTextEdit::textCursor() const
+{
+ return cursor;
+}
+
+#endif
diff --git a/core/apps/textedit/textedit.cpp b/core/apps/textedit/textedit.cpp
new file mode 100644
index 0000000..867625e
--- a/dev/null
+++ b/core/apps/textedit/textedit.cpp
@@ -0,0 +1,594 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "textedit.h"
+
+#include <qpe/global.h>
+#include <qpe/fileselector.h>
+#include <qpe/applnk.h>
+#include <qpe/resource.h>
+#include <qpe/config.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/qpemenubar.h>
+#include <qpe/qpetoolbar.h>
+//#include <qpe/finddialog.h>
+
+#include <qaction.h>
+#include <qcolordialog.h>
+#include <qfileinfo.h>
+#include <qlineedit.h>
+#include <qmessagebox.h>
+#include <qobjectlist.h>
+#include <qpopupmenu.h>
+#include <qspinbox.h>
+#include <qtoolbutton.h>
+#include <qwidgetstack.h>
+
+#include <stdlib.h> //getenv
+
+
+#if QT_VERSION < 300
+
+class QpeEditor : public QMultiLineEdit
+{
+ // Q_OBJECT
+public:
+ QpeEditor( QWidget *parent, const char * name = 0 )
+ : QMultiLineEdit( parent, name ) {}
+
+ //public slots:
+ void find( const QString &txt, bool caseSensitive,
+ bool backwards );
+ /*
+signals:
+ void notFound();
+ void searchWrapped();
+ */
+
+private:
+
+};
+
+
+void QpeEditor::find ( const QString &txt, bool caseSensitive,
+ bool backwards )
+{
+ static bool wrap = FALSE;
+ int line, col;
+ if ( wrap ) {
+ if ( !backwards )
+ line = col = 0;
+ wrap = FALSE;
+ // emit searchWrapped();
+ } else {
+ getCursorPosition( &line, &col );
+ }
+ //ignore backwards for now....
+ if ( !backwards ) {
+ for ( ; ; ) {
+ if ( line >= numLines() ) {
+ wrap = TRUE;
+ //emit notFound();
+ break;
+ }
+ int findCol = getString( line )->find( txt, col, caseSensitive );
+ if ( findCol >= 0 ) {
+ setCursorPosition( line, findCol, FALSE );
+ col = findCol + txt.length();
+ setCursorPosition( line, col, TRUE );
+
+ //found = TRUE;
+ break;
+ }
+ line++;
+ col = 0;
+ }
+
+ }
+
+}
+
+
+#else
+
+#error "Must make a QpeEditor that inherits QTextEdit"
+
+#endif
+
+
+
+
+static int u_id = 1;
+static int get_unique_id()
+{
+ return u_id++;
+}
+
+static const int nfontsizes = 6;
+static const int fontsize[nfontsizes] = {8,10,12,14,18,24};
+
+TextEdit::TextEdit( QWidget *parent, const char *name, WFlags f )
+ : QMainWindow( parent, name, f ), bFromDocView( FALSE )
+{
+ doc = 0;
+
+ QString lang = getenv( "LANG" );
+
+ setToolBarsMovable( FALSE );
+
+ setIcon( Resource::loadPixmap( "TextEditor" ) );
+
+ QPEToolBar *bar = new QPEToolBar( this );
+ bar->setHorizontalStretchable( TRUE );
+ menu = bar;
+
+ QPEMenuBar *mb = new QPEMenuBar( bar );
+ QPopupMenu *file = new QPopupMenu( this );
+ QPopupMenu *edit = new QPopupMenu( this );
+ QPopupMenu *font = new QPopupMenu( this );
+
+ bar = new QPEToolBar( this );
+ editBar = bar;
+
+ QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) );
+ a->addTo( bar );
+ a->addTo( file );
+
+ a = new QAction( tr( "Open" ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( fileOpen() ) );
+ a->addTo( bar );
+ a->addTo( file );
+
+ a = new QAction( tr( "Cut" ), Resource::loadPixmap( "cut" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( editCut() ) );
+ a->addTo( editBar );
+ a->addTo( edit );
+
+ a = new QAction( tr( "Copy" ), Resource::loadPixmap( "copy" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( editCopy() ) );
+ a->addTo( editBar );
+ a->addTo( edit );
+
+ a = new QAction( tr( "Paste" ), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( editPaste() ) );
+ a->addTo( editBar );
+ a->addTo( edit );
+
+ a = new QAction( tr( "Find..." ), Resource::loadPixmap( "find" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( editFind() ) );
+ edit->insertSeparator();
+ a->addTo( bar );
+ a->addTo( edit );
+
+ int defsize;
+ bool defb, defi, wrap;
+ {
+ Config cfg("TextEdit");
+ cfg.setGroup("View");
+ defsize = cfg.readNumEntry("FontSize",10);
+ defb = cfg.readBoolEntry("Bold",FALSE);
+ defi = cfg.readBoolEntry("Italic",FALSE);
+ wrap = cfg.readBoolEntry("Wrap",TRUE);
+ }
+
+ zin = new QAction( tr("Zoom in"), QString::null, 0, this, 0 );
+ connect( zin, SIGNAL( activated() ), this, SLOT( zoomIn() ) );
+ zin->addTo( font );
+
+ zout = new QAction( tr("Zoom out"), QString::null, 0, this, 0 );
+ connect( zout, SIGNAL( activated() ), this, SLOT( zoomOut() ) );
+ zout->addTo( font );
+
+ font->insertSeparator();
+
+#if 0
+ QAction *ba = new QAction( tr("Bold"), QString::null, 0, this, 0 );
+ connect( ba, SIGNAL( toggled(bool) ), this, SLOT( setBold(bool) ) );
+ ba->setToggleAction(TRUE);
+ ba->addTo( font );
+
+ QAction *ia = new QAction( tr("Italic"), QString::null, 0, this, 0 );
+ connect( ia, SIGNAL( toggled(bool) ), this, SLOT( setItalic(bool) ) );
+ ia->setToggleAction(TRUE);
+ ia->addTo( font );
+
+ ba->setOn(defb);
+ ia->setOn(defi);
+
+ font->insertSeparator();
+#endif
+
+ QAction *wa = new QAction( tr("Wrap lines"), QString::null, 0, this, 0 );
+ connect( wa, SIGNAL( toggled(bool) ), this, SLOT( setWordWrap(bool) ) );
+ wa->setToggleAction(TRUE);
+ wa->addTo( font );
+
+ mb->insertItem( tr( "File" ), file );
+ mb->insertItem( tr( "Edit" ), edit );
+ mb->insertItem( tr( "View" ), font );
+
+ searchBar = new QPEToolBar(this);
+ addToolBar( searchBar, "Search", QMainWindow::Top, TRUE );
+
+ searchBar->setHorizontalStretchable( TRUE );
+
+ searchEdit = new QLineEdit( searchBar, "searchEdit" );
+ searchBar->setStretchableWidget( searchEdit );
+ connect( searchEdit, SIGNAL( textChanged( const QString & ) ),
+ this, SLOT( search() ) );
+
+ a = new QAction( tr( "Find Next" ), Resource::loadPixmap( "next" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( findNext() ) );
+ a->addTo( searchBar );
+ a->addTo( edit );
+
+ a = new QAction( tr( "Close Find" ), Resource::loadPixmap( "close" ), QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( findClose() ) );
+ a->addTo( searchBar );
+
+ searchBar->hide();
+
+ editorStack = new QWidgetStack( this );
+ setCentralWidget( editorStack );
+
+ searchVisible = FALSE;
+
+ fileSelector = new FileSelector( "text/*", editorStack, "fileselector" ,
+ TRUE, FALSE );
+ fileSelector->setCategoriesVisible(TRUE);
+ connect( fileSelector, SIGNAL( closeMe() ), this, SLOT( showEditTools() ) );
+ connect( fileSelector, SIGNAL( newSelected( const DocLnk &) ), this, SLOT( newFile( const DocLnk & ) ) );
+ connect( fileSelector, SIGNAL( fileSelected( const DocLnk &) ), this, SLOT( openFile( const DocLnk & ) ) );
+ fileOpen();
+
+ editor = new QpeEditor( editorStack );
+ editorStack->addWidget( editor, get_unique_id() );
+
+ resize( 200, 300 );
+
+ setFontSize(defsize,TRUE);
+ wa->setOn(wrap);
+}
+
+TextEdit::~TextEdit()
+{
+ save();
+
+ Config cfg("TextEdit");
+ cfg.setGroup("View");
+ QFont f = editor->font();
+ cfg.writeEntry("FontSize",f.pointSize());
+ cfg.writeEntry("Bold",f.bold());
+ cfg.writeEntry("Italic",f.italic());
+ cfg.writeEntry("Wrap",editor->wordWrap() == QMultiLineEdit::WidgetWidth);
+}
+
+void TextEdit::zoomIn()
+{
+ setFontSize(editor->font().pointSize()+1,FALSE);
+}
+
+void TextEdit::zoomOut()
+{
+ setFontSize(editor->font().pointSize()-1,TRUE);
+}
+
+
+void TextEdit::setFontSize(int sz, bool round_down_not_up)
+{
+ int s=10;
+ for (int i=0; i<nfontsizes; i++) {
+ if ( fontsize[i] == sz ) {
+ s = sz;
+ break;
+ } else if ( round_down_not_up ) {
+ if ( fontsize[i] < sz )
+ s = fontsize[i];
+ } else {
+ if ( fontsize[i] > sz ) {
+ s = fontsize[i];
+ break;
+ }
+ }
+ }
+
+ QFont f = editor->font();
+ f.setPointSize(s);
+ editor->setFont(f);
+
+ zin->setEnabled(s != fontsize[nfontsizes-1]);
+ zout->setEnabled(s != fontsize[0]);
+}
+
+void TextEdit::setBold(bool y)
+{
+ QFont f = editor->font();
+ f.setBold(y);
+ editor->setFont(f);
+}
+
+void TextEdit::setItalic(bool y)
+{
+ QFont f = editor->font();
+ f.setItalic(y);
+ editor->setFont(f);
+}
+
+void TextEdit::setWordWrap(bool y)
+{
+ editor->setWordWrap(y ? QMultiLineEdit::WidgetWidth : QMultiLineEdit::NoWrap );
+}
+
+void TextEdit::fileNew()
+{
+ save();
+ newFile(DocLnk());
+}
+
+void TextEdit::fileOpen()
+{
+ if ( !save() ) {
+ if ( QMessageBox::critical( this, tr( "Out of space" ),
+ tr( "Text Editor was unable to\n"
+ "save your changes.\n"
+ "Free some space and try again.\n"
+ "\nContinue anyway?" ),
+ QMessageBox::Yes|QMessageBox::Escape,
+ QMessageBox::No|QMessageBox::Default )
+ != QMessageBox::Yes )
+ return;
+ else {
+ delete doc;
+ doc = 0;
+ }
+ }
+ menu->hide();
+ editBar->hide();
+ searchBar->hide();
+ clearWState (WState_Reserved1 );
+ editorStack->raiseWidget( fileSelector );
+ fileSelector->reread();
+ updateCaption();
+}
+
+
+#if 0
+void TextEdit::slotFind()
+{
+ FindDialog frmFind( "Text Editor", this );
+ connect( &frmFind, SIGNAL(signalFindClicked(const QString &, bool, bool, int)),
+ editor, SLOT(slotDoFind( const QString&,bool,bool)));
+
+ //case sensitive, backwards, [category]
+
+
+ connect( editor, SIGNAL(notFound()),
+ &frmFind, SLOT(slotNotFound()) );
+ connect( editor, SIGNAL(searchWrapped()),
+ &frmFind, SLOT(slotWrapAround()) );
+
+ frmFind.exec();
+
+
+}
+#endif
+
+void TextEdit::fileRevert()
+{
+ clear();
+ fileOpen();
+}
+
+void TextEdit::editCut()
+{
+#ifndef QT_NO_CLIPBOARD
+ editor->cut();
+#endif
+}
+
+void TextEdit::editCopy()
+{
+#ifndef QT_NO_CLIPBOARD
+ editor->copy();
+#endif
+}
+
+void TextEdit::editPaste()
+{
+#ifndef QT_NO_CLIPBOARD
+ editor->paste();
+#endif
+}
+
+void TextEdit::editFind()
+{
+ searchBar->show();
+ searchVisible = TRUE;
+ searchEdit->setFocus();
+}
+
+void TextEdit::findNext()
+{
+ editor->find( searchEdit->text(), FALSE, FALSE );
+
+}
+
+void TextEdit::findClose()
+{
+ searchVisible = FALSE;
+ searchBar->hide();
+}
+
+void TextEdit::search()
+{
+ editor->find( searchEdit->text(), FALSE, FALSE );
+}
+
+void TextEdit::newFile( const DocLnk &f )
+{
+ DocLnk nf = f;
+ nf.setType("text/plain");
+ clear();
+ editorStack->raiseWidget( editor );
+ setWState (WState_Reserved1 );
+ editor->setFocus();
+ doc = new DocLnk(nf);
+ updateCaption();
+}
+
+void TextEdit::openFile( const QString &f )
+{
+ bFromDocView = TRUE;
+ DocLnk nf;
+ nf.setType("text/plain");
+ nf.setFile(f);
+ openFile(nf);
+ showEditTools();
+ // Show filename in caption
+ QString name = f;
+ int sep = name.findRev( '/' );
+ if ( sep > 0 )
+ name = name.mid( sep+1 );
+ updateCaption( name );
+}
+
+void TextEdit::openFile( const DocLnk &f )
+{
+ clear();
+ FileManager fm;
+ QString txt;
+ if ( !fm.loadFile( f, txt ) ) {
+ // ####### could be a new file
+ //qDebug( "Cannot open file" );
+ //return;
+ }
+ fileNew();
+ if ( doc )
+ delete doc;
+ doc = new DocLnk(f);
+ editor->setText(txt);
+ editor->setEdited(FALSE);
+ updateCaption();
+}
+
+void TextEdit::showEditTools()
+{
+ if ( !doc )
+ close();
+ fileSelector->hide();
+ menu->show();
+ editBar->show();
+ if ( searchVisible )
+ searchBar->show();
+ updateCaption();
+}
+
+bool TextEdit::save()
+{
+ // case of nothing to save...
+ if ( !doc )
+ return true;
+ if ( !editor->edited() ) {
+ delete doc;
+ doc = 0;
+ return true;
+ }
+
+ QString rt = editor->text();
+
+ if ( doc->name().isEmpty() ) {
+ QString pt = rt.simplifyWhiteSpace();
+ int i = pt.find( ' ' );
+ QString docname = pt;
+ if ( i > 0 )
+ docname = pt.left( i );
+ // remove "." at the beginning
+ while( docname.startsWith( "." ) )
+ docname = docname.mid( 1 );
+ docname.replace( QRegExp("/"), "_" );
+ // cut the length. filenames longer than that don't make sense and something goes wrong when they get too long.
+ if ( docname.length() > 40 )
+ docname = docname.left(40);
+ if ( docname.isEmpty() )
+ docname = "Empty Text";
+ doc->setName(docname);
+
+ // append .txt to the file name
+ if ( doc->file().find(".txt") == -1 ) {
+ QString file = doc->file() + ".txt";
+ doc->setFile( file );
+ }
+ }
+
+
+ FileManager fm;
+ if ( !fm.saveFile( *doc, rt ) ) {
+ return false;
+ }
+ delete doc;
+ doc = 0;
+ editor->setEdited( false );
+ return true;
+}
+
+void TextEdit::clear()
+{
+ delete doc;
+ doc = 0;
+ editor->clear();
+}
+
+void TextEdit::updateCaption( const QString &name )
+{
+ if ( !doc )
+ setCaption( tr("Text Editor") );
+ else {
+ QString s = name;
+ if ( s.isNull() )
+ s = doc->name();
+ if ( s.isEmpty() )
+ s = tr( "Unnamed" );
+ setCaption( s + " - " + tr("Text Editor") );
+ }
+}
+
+void TextEdit::setDocument(const QString& fileref)
+{
+ bFromDocView = TRUE;
+ openFile(DocLnk(fileref));
+ showEditTools();
+}
+
+void TextEdit::closeEvent( QCloseEvent *e )
+{
+ if ( editorStack->visibleWidget() == editor && !bFromDocView ) {
+ e->ignore();
+ fileRevert();
+ } else {
+ bFromDocView = FALSE;
+ e->accept();
+ }
+}
+
+void TextEdit::accept()
+{
+ fileOpen();
+}
diff --git a/core/apps/textedit/textedit.h b/core/apps/textedit/textedit.h
new file mode 100644
index 0000000..f7d1052
--- a/dev/null
+++ b/core/apps/textedit/textedit.h
@@ -0,0 +1,102 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef TEXTEDIT_H
+#define TEXTEDIT_H
+
+#define QTEXTEDIT_OPEN_API
+
+#include <qpe/filemanager.h>
+
+#include <qmainwindow.h>
+#include <qmultilineedit.h>
+#include <qlist.h>
+#include <qmap.h>
+
+class QWidgetStack;
+class QToolButton;
+class QPopupMenu;
+class QToolBar;
+class QLineEdit;
+class QAction;
+class FileSelector;
+class QpeEditor;
+
+class TextEdit : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ TextEdit( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ ~TextEdit();
+
+ void openFile( const QString & );
+
+protected:
+ void closeEvent( QCloseEvent *e );
+
+private slots:
+ void setDocument(const QString&);
+
+ void fileNew();
+ void fileRevert();
+ void fileOpen();
+
+ void editCut();
+ void editCopy();
+ void editPaste();
+ void editFind();
+
+ void findNext();
+ void findClose();
+
+ void search();
+ void accept();
+
+ void newFile( const DocLnk & );
+ void openFile( const DocLnk & );
+ void showEditTools();
+
+ void zoomIn();
+ void zoomOut();
+ void setBold(bool y);
+ void setItalic(bool y);
+ void setWordWrap(bool y);
+
+private:
+ void colorChanged( const QColor &c );
+ bool save();
+ void clear();
+ void updateCaption( const QString &name=QString::null );
+ void setFontSize(int sz, bool round_down_not_up);
+
+private:
+ QWidgetStack *editorStack;
+ FileSelector *fileSelector;
+ QpeEditor* editor;
+ QToolBar *menu, *editBar, *searchBar;
+ QLineEdit *searchEdit;
+ DocLnk *doc;
+ bool searchVisible;
+ bool bFromDocView;
+ QAction *zin, *zout;
+};
+
+#endif
diff --git a/core/apps/textedit/textedit.po b/core/apps/textedit/textedit.po
new file mode 100644
index 0000000..683a5e3
--- a/dev/null
+++ b/core/apps/textedit/textedit.po
@@ -0,0 +1,108 @@
+# This is a Qt message file in .po format. Each msgid starts with
+# a scope. This scope should *NOT* be translated - eg. translating
+# from French to English, "Foo::Bar" would be translated to "Pub",
+# not "Foo::Pub".
+msgid ""
+msgstr ""
+"Project-Id-Version: PROJECT VERSION\n"
+"POT-Creation-Date: 2001-03-16 14:29:14 EST\n"
+"PO-Revision-Date: YYYY-MM-DD\n"
+"Last-Translator: FULLNAME <EMAIL@ADDRESS>\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+
+#: textedit.cpp:110
+msgid "TextEdit::&Edit"
+msgstr ""
+
+#: textedit.cpp:109
+msgid "TextEdit::&File"
+msgstr ""
+
+#: textedit.cpp:102
+msgid "TextEdit::&Insert"
+msgstr ""
+
+#: textedit.cpp:115
+msgid "TextEdit::Bold"
+msgstr ""
+
+#: textedit.cpp:191
+msgid "TextEdit::Bullet List"
+msgstr ""
+
+#: textedit.cpp:140
+msgid "TextEdit::Center"
+msgstr ""
+
+#: textedit.cpp:170
+msgid "TextEdit::Close Find"
+msgstr ""
+
+#: textedit.cpp:69
+msgid "TextEdit::Close"
+msgstr ""
+
+#: textedit.cpp:79
+msgid "TextEdit::Copy"
+msgstr ""
+
+#: textedit.cpp:74
+msgid "TextEdit::Cut"
+msgstr ""
+
+#: textedit.cpp:194
+msgid "TextEdit::Enumerated List"
+msgstr ""
+
+#: textedit.cpp:94
+msgid "TextEdit::Find Next"
+msgstr ""
+
+#: textedit.cpp:89
+msgid "TextEdit::Find..."
+msgstr ""
+
+#: textedit.cpp:120
+msgid "TextEdit::Italic"
+msgstr ""
+
+#: textedit.cpp:134
+msgid "TextEdit::Left"
+msgstr ""
+
+#: textedit.cpp:61
+msgid "TextEdit::New"
+msgstr ""
+
+#: textedit.cpp:65
+msgid "TextEdit::Open"
+msgstr ""
+
+#: textedit.cpp:84
+msgid "TextEdit::Paste"
+msgstr ""
+
+#: textedit.cpp:145
+msgid "TextEdit::Right"
+msgstr ""
+
+#: textedit.cpp:188
+msgid "TextEdit::Standard"
+msgstr ""
+
+#: textedit.cpp:104
+msgid "TextEdit::Table..."
+msgstr ""
+
+#: textedit.cpp:570
+msgid "TextEdit::Text Editor"
+msgstr ""
+
+#: textedit.cpp:125
+msgid "TextEdit::Underline"
+msgstr ""
+
+#: textedit.cpp:569
+msgid "TextEdit::Unnamed"
+msgstr ""
+
diff --git a/core/apps/textedit/textedit.pro b/core/apps/textedit/textedit.pro
new file mode 100644
index 0000000..3f5473e
--- a/dev/null
+++ b/core/apps/textedit/textedit.pro
@@ -0,0 +1,16 @@
+TEMPLATE = app
+CONFIG += qt warn_on release
+
+DESTDIR = $(QPEDIR)/bin
+
+HEADERS = textedit.h
+
+SOURCES = main.cpp textedit.cpp
+
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TARGET = textedit
+
+TRANSLATIONS = ../i18n/de/textedit.ts
diff --git a/core/launcher/.cvsignore b/core/launcher/.cvsignore
new file mode 100644
index 0000000..1924a2d
--- a/dev/null
+++ b/core/launcher/.cvsignore
@@ -0,0 +1,7 @@
+moc_*
+*.moc
+Makefile
+shutdown.cpp
+shutdown.h
+qimpenprefbase.h
+lnkpropertiesbase.h
diff --git a/core/launcher/Makefile.in b/core/launcher/Makefile.in
new file mode 100644
index 0000000..e129fca
--- a/dev/null
+++ b/core/launcher/Makefile.in
@@ -0,0 +1,867 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include -I$(QPEDIR)/calibrate -I$(QPEDIR)/rsync
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe -lcrypt $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = qpe
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = background.h \
+ desktop.h \
+ info.h \
+ appicons.h \
+ taskbar.h \
+ sidething.h \
+ mrulist.h \
+ stabmon.h \
+ inputmethods.h \
+ systray.h \
+ wait.h \
+ shutdownimpl.h \
+ launcher.h \
+ launcherview.h \
+ ../calibrate/calibrate.h \
+ startmenu.h \
+ transferserver.h \
+ qcopbridge.h \
+ packageslave.h \
+ irserver.h \
+ $(QPEDIR)/rsync/buf.h \
+ $(QPEDIR)/rsync/checksum.h \
+ $(QPEDIR)/rsync/command.h \
+ $(QPEDIR)/rsync/emit.h \
+ $(QPEDIR)/rsync/job.h \
+ $(QPEDIR)/rsync/netint.h \
+ $(QPEDIR)/rsync/protocol.h \
+ $(QPEDIR)/rsync/prototab.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/search.h \
+ $(QPEDIR)/rsync/stream.h \
+ $(QPEDIR)/rsync/sumset.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/types.h \
+ $(QPEDIR)/rsync/util.h \
+ $(QPEDIR)/rsync/whole.h \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/qrsync.h
+SOURCES = background.cpp \
+ desktop.cpp \
+ info.cpp \
+ appicons.cpp \
+ taskbar.cpp \
+ sidething.cpp \
+ mrulist.cpp \
+ stabmon.cpp \
+ inputmethods.cpp \
+ systray.cpp \
+ wait.cpp \
+ shutdownimpl.cpp \
+ launcher.cpp \
+ launcherview.cpp \
+ $(QPEDIR)/calibrate/calibrate.cpp \
+ transferserver.cpp \
+ packageslave.cpp \
+ irserver.cpp \
+ qcopbridge.cpp \
+ startmenu.cpp \
+ main.cpp \
+ $(QPEDIR)/rsync/base64.c \
+ $(QPEDIR)/rsync/buf.c \
+ $(QPEDIR)/rsync/checksum.c \
+ $(QPEDIR)/rsync/command.c \
+ $(QPEDIR)/rsync/delta.c \
+ $(QPEDIR)/rsync/emit.c \
+ $(QPEDIR)/rsync/hex.c \
+ $(QPEDIR)/rsync/job.c \
+ $(QPEDIR)/rsync/mdfour.c \
+ $(QPEDIR)/rsync/mksum.c \
+ $(QPEDIR)/rsync/msg.c \
+ $(QPEDIR)/rsync/netint.c \
+ $(QPEDIR)/rsync/patch.c \
+ $(QPEDIR)/rsync/prototab.c \
+ $(QPEDIR)/rsync/readsums.c \
+ $(QPEDIR)/rsync/scoop.c \
+ $(QPEDIR)/rsync/search.c \
+ $(QPEDIR)/rsync/stats.c \
+ $(QPEDIR)/rsync/stream.c \
+ $(QPEDIR)/rsync/sumset.c \
+ $(QPEDIR)/rsync/trace.c \
+ $(QPEDIR)/rsync/tube.c \
+ $(QPEDIR)/rsync/util.c \
+ $(QPEDIR)/rsync/version.c \
+ $(QPEDIR)/rsync/whole.c \
+ $(QPEDIR)/rsync/qrsync.cpp
+OBJECTS = background.o \
+ desktop.o \
+ info.o \
+ appicons.o \
+ taskbar.o \
+ sidething.o \
+ mrulist.o \
+ stabmon.o \
+ inputmethods.o \
+ systray.o \
+ wait.o \
+ shutdownimpl.o \
+ launcher.o \
+ launcherview.o \
+ $(QPEDIR)/calibrate/calibrate.o \
+ transferserver.o \
+ packageslave.o \
+ irserver.o \
+ qcopbridge.o \
+ startmenu.o \
+ main.o \
+ $(QPEDIR)/rsync/base64.o \
+ $(QPEDIR)/rsync/buf.o \
+ $(QPEDIR)/rsync/checksum.o \
+ $(QPEDIR)/rsync/command.o \
+ $(QPEDIR)/rsync/delta.o \
+ $(QPEDIR)/rsync/emit.o \
+ $(QPEDIR)/rsync/hex.o \
+ $(QPEDIR)/rsync/job.o \
+ $(QPEDIR)/rsync/mdfour.o \
+ $(QPEDIR)/rsync/mksum.o \
+ $(QPEDIR)/rsync/msg.o \
+ $(QPEDIR)/rsync/netint.o \
+ $(QPEDIR)/rsync/patch.o \
+ $(QPEDIR)/rsync/prototab.o \
+ $(QPEDIR)/rsync/readsums.o \
+ $(QPEDIR)/rsync/scoop.o \
+ $(QPEDIR)/rsync/search.o \
+ $(QPEDIR)/rsync/stats.o \
+ $(QPEDIR)/rsync/stream.o \
+ $(QPEDIR)/rsync/sumset.o \
+ $(QPEDIR)/rsync/trace.o \
+ $(QPEDIR)/rsync/tube.o \
+ $(QPEDIR)/rsync/util.o \
+ $(QPEDIR)/rsync/version.o \
+ $(QPEDIR)/rsync/whole.o \
+ $(QPEDIR)/rsync/qrsync.o \
+ shutdown.o \
+ syncdialog.o
+INTERFACES = shutdown.ui \
+ syncdialog.ui
+UICDECLS = shutdown.h \
+ syncdialog.h
+UICIMPLS = shutdown.cpp \
+ syncdialog.cpp
+SRCMOC = moc_background.cpp \
+ moc_desktop.cpp \
+ moc_info.cpp \
+ moc_appicons.cpp \
+ moc_taskbar.cpp \
+ moc_sidething.cpp \
+ moc_inputmethods.cpp \
+ moc_systray.cpp \
+ moc_shutdownimpl.cpp \
+ moc_launcher.cpp \
+ moc_launcherview.cpp \
+ ../calibrate/moc_calibrate.cpp \
+ moc_startmenu.cpp \
+ moc_transferserver.cpp \
+ moc_qcopbridge.cpp \
+ moc_packageslave.cpp \
+ moc_irserver.cpp \
+ appicons.moc \
+ moc_shutdown.cpp \
+ moc_syncdialog.cpp
+OBJMOC = moc_background.o \
+ moc_desktop.o \
+ moc_info.o \
+ moc_appicons.o \
+ moc_taskbar.o \
+ moc_sidething.o \
+ moc_inputmethods.o \
+ moc_systray.o \
+ moc_shutdownimpl.o \
+ moc_launcher.o \
+ moc_launcherview.o \
+ ../calibrate/moc_calibrate.o \
+ moc_startmenu.o \
+ moc_transferserver.o \
+ moc_qcopbridge.o \
+ moc_packageslave.o \
+ moc_irserver.o \
+ moc_shutdown.o \
+ moc_syncdialog.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake taskbar.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+background.o: background.cpp \
+ background.h \
+ desktop.h \
+ shutdownimpl.h \
+ shutdown.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+desktop.o: desktop.cpp \
+ desktop.h \
+ shutdownimpl.h \
+ shutdown.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ info.h \
+ background.h \
+ launcher.h \
+ launcherview.h \
+ $(QPEDIR)/include/qpe/storage.h \
+ mrulist.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ qcopbridge.h \
+ startmenu.h \
+ taskbar.h \
+ $(QPEDIR)/include/qpe/custom.h \
+ transferserver.h \
+ irserver.h \
+ packageslave.h \
+ $(QPEDIR)/include/qpe/mimetype.h \
+ $(QPEDIR)/include/qpe/password.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/power.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
+ $(QPEDIR)/include/qpe/global.h
+
+info.o: info.cpp \
+ info.h \
+ background.h \
+ desktop.h \
+ shutdownimpl.h \
+ shutdown.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/version.h
+
+appicons.o: appicons.cpp \
+ appicons.moc \
+ appicons.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h
+
+taskbar.o: taskbar.cpp \
+ startmenu.h \
+ inputmethods.h \
+ $(QPEDIR)/include/qpe/inputmethodinterface.h \
+ $(QPEDIR)/include/qpe/qcom.h \
+ $(QPEDIR)/include/qpe/quuid.h \
+ mrulist.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ systray.h \
+ $(QPEDIR)/include/qpe/taskbarappletinterface.h \
+ $(QPEDIR)/calibrate/calibrate.h \
+ wait.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ appicons.h \
+ taskbar.h \
+ $(QPEDIR)/include/qpe/custom.h \
+ desktop.h \
+ shutdownimpl.h \
+ shutdown.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
+ $(QPEDIR)/include/qpe/global.h \
+ ../taskbar/apps.h \
+ ../addressbook/addressbook.h \
+ ../datebook/datebook.h \
+ $(QPEDIR)/include/qpe/datebookdb.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ ../helpbrowser/helpbrowser.h \
+ ../minesweep/minesweep.h \
+ ../textedit/textedit.h \
+ $(QPEDIR)/include/qpe/filemanager.h \
+ ../todo/mainwindow.h \
+ ../citytime/citytime.h \
+ ../clock/clock.h \
+ ../calculator/calculatorimpl.h \
+ ../sysinfo/sysinfo.h \
+ ../settings/appearance/settings.h \
+ ../settings/systemtime/settime.h \
+ $(QPEDIR)/include/qpe/timestring.h \
+ ../filebrowser/filebrowser.h \
+ ../solitaire/canvascardwindow.h \
+ ../snake/interface.h \
+ ../parashoot/interface.h \
+ $(QPEDIR)/include/qpe/sound.h \
+ ../mpegplayer/mediaplayer.h \
+ $(QPEDIR)/include/qpe/qlibrary.h \
+ ../embeddedkonsole/konsole.h \
+ ../wordgame/wordgame.h \
+ $(QPEDIR)/include/qpe/qdawg.h
+
+sidething.o: sidething.cpp \
+ sidething.h \
+ startmenu.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+mrulist.o: mrulist.cpp \
+ mrulist.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+stabmon.o: stabmon.cpp \
+ stabmon.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h
+
+inputmethods.o: inputmethods.cpp \
+ inputmethods.h \
+ $(QPEDIR)/include/qpe/inputmethodinterface.h \
+ $(QPEDIR)/include/qpe/qcom.h \
+ $(QPEDIR)/include/qpe/quuid.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/qlibrary.h
+
+systray.o: systray.cpp \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/qlibrary.h \
+ $(QPEDIR)/include/qpe/qcom.h \
+ $(QPEDIR)/include/qpe/quuid.h \
+ $(QPEDIR)/include/qpe/config.h \
+ quicklauncher.h \
+ systray.h \
+ $(QPEDIR)/include/qpe/taskbarappletinterface.h
+
+wait.o: wait.cpp \
+ wait.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+shutdownimpl.o: shutdownimpl.cpp \
+ shutdownimpl.h \
+ shutdown.h \
+ $(QPEDIR)/include/qpe/global.h
+
+launcher.o: launcher.cpp \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/mimetype.h \
+ $(QPEDIR)/include/qpe/storage.h \
+ launcherview.h \
+ launcher.h \
+ $(QPEDIR)/include/qpe/lnkproperties.h \
+ mrulist.h \
+ $(QPEDIR)/rsync/qrsync.h
+
+launcherview.o: launcherview.cpp \
+ launcherview.h \
+ $(QPEDIR)/include/qpe/storage.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ $(QPEDIR)/include/qpe/qpedebug.h \
+ $(QPEDIR)/include/qpe/categories.h \
+ $(QPEDIR)/include/qpe/categoryselect.h \
+ $(QPEDIR)/include/qpe/menubutton.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+$(QPEDIR)/calibrate/calibrate.o: $(QPEDIR)/calibrate/calibrate.cpp \
+ $(QPEDIR)/calibrate/calibrate.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+transferserver.o: transferserver.cpp \
+ $(QPEDIR)/include/qpe/qprocess.h \
+ $(QPEDIR)/include/qpe/process.h \
+ transferserver.h
+
+packageslave.o: packageslave.cpp \
+ packageslave.h \
+ $(QPEDIR)/include/qpe/process.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h
+
+irserver.o: irserver.cpp \
+ irserver.h \
+ $(QPEDIR)/include/qpe/qlibrary.h \
+ $(QPEDIR)/include/qpe/qcom.h \
+ $(QPEDIR)/include/qpe/quuid.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ obexinterface.h
+
+qcopbridge.o: qcopbridge.cpp \
+ qcopbridge.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+startmenu.o: startmenu.cpp \
+ startmenu.h \
+ sidething.h \
+ mrulist.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ info.h \
+ background.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/resource.h
+
+main.o: main.cpp \
+ desktop.h \
+ shutdownimpl.h \
+ shutdown.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ taskbar.h \
+ $(QPEDIR)/include/qpe/custom.h \
+ stabmon.h \
+ $(QPEDIR)/include/qpe/network.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
+ $(QPEDIR)/include/qpe/alarmserver.h \
+ ../calibrate/calibrate.h \
+ ../login/qdmdialogimpl.h \
+ $(QPEDIR)/include/qpe/global.h
+
+$(QPEDIR)/rsync/base64.o: $(QPEDIR)/rsync/base64.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h
+
+$(QPEDIR)/rsync/buf.o: $(QPEDIR)/rsync/buf.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/buf.h \
+ $(QPEDIR)/rsync/util.h
+
+$(QPEDIR)/rsync/checksum.o: $(QPEDIR)/rsync/checksum.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/checksum.h
+
+$(QPEDIR)/rsync/command.o: $(QPEDIR)/rsync/command.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/command.h
+
+$(QPEDIR)/rsync/delta.o: $(QPEDIR)/rsync/delta.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/emit.h \
+ $(QPEDIR)/rsync/stream.h \
+ $(QPEDIR)/rsync/util.h \
+ $(QPEDIR)/rsync/sumset.h \
+ $(QPEDIR)/rsync/job.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/checksum.h \
+ $(QPEDIR)/rsync/search.h \
+ $(QPEDIR)/rsync/types.h
+
+$(QPEDIR)/rsync/emit.o: $(QPEDIR)/rsync/emit.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/command.h \
+ $(QPEDIR)/rsync/protocol.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/emit.h \
+ $(QPEDIR)/rsync/prototab.h \
+ $(QPEDIR)/rsync/netint.h \
+ $(QPEDIR)/rsync/sumset.h \
+ $(QPEDIR)/rsync/job.h
+
+$(QPEDIR)/rsync/hex.o: $(QPEDIR)/rsync/hex.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h
+
+$(QPEDIR)/rsync/job.o: $(QPEDIR)/rsync/job.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/stream.h \
+ $(QPEDIR)/rsync/util.h \
+ $(QPEDIR)/rsync/sumset.h \
+ $(QPEDIR)/rsync/job.h \
+ $(QPEDIR)/rsync/trace.h
+
+$(QPEDIR)/rsync/mdfour.o: $(QPEDIR)/rsync/mdfour.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/types.h
+
+$(QPEDIR)/rsync/mksum.o: $(QPEDIR)/rsync/mksum.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/stream.h \
+ $(QPEDIR)/rsync/util.h \
+ $(QPEDIR)/rsync/sumset.h \
+ $(QPEDIR)/rsync/job.h \
+ $(QPEDIR)/rsync/protocol.h \
+ $(QPEDIR)/rsync/netint.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/checksum.h
+
+$(QPEDIR)/rsync/msg.o: $(QPEDIR)/rsync/msg.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h
+
+$(QPEDIR)/rsync/netint.o: $(QPEDIR)/rsync/netint.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/job.h \
+ $(QPEDIR)/rsync/netint.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/stream.h
+
+$(QPEDIR)/rsync/patch.o: $(QPEDIR)/rsync/patch.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/util.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/protocol.h \
+ $(QPEDIR)/rsync/netint.h \
+ $(QPEDIR)/rsync/command.h \
+ $(QPEDIR)/rsync/sumset.h \
+ $(QPEDIR)/rsync/prototab.h \
+ $(QPEDIR)/rsync/stream.h \
+ $(QPEDIR)/rsync/job.h
+
+$(QPEDIR)/rsync/prototab.o: $(QPEDIR)/rsync/prototab.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/protocol.h \
+ $(QPEDIR)/rsync/command.h \
+ $(QPEDIR)/rsync/prototab.h
+
+$(QPEDIR)/rsync/readsums.o: $(QPEDIR)/rsync/readsums.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/sumset.h \
+ $(QPEDIR)/rsync/job.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/netint.h \
+ $(QPEDIR)/rsync/protocol.h \
+ $(QPEDIR)/rsync/util.h \
+ $(QPEDIR)/rsync/stream.h
+
+$(QPEDIR)/rsync/scoop.o: $(QPEDIR)/rsync/scoop.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/job.h \
+ $(QPEDIR)/rsync/stream.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/util.h
+
+$(QPEDIR)/rsync/search.o: $(QPEDIR)/rsync/search.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/util.h \
+ $(QPEDIR)/rsync/sumset.h \
+ $(QPEDIR)/rsync/search.h \
+ $(QPEDIR)/rsync/checksum.h
+
+$(QPEDIR)/rsync/stats.o: $(QPEDIR)/rsync/stats.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/trace.h
+
+$(QPEDIR)/rsync/stream.o: $(QPEDIR)/rsync/stream.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/stream.h \
+ $(QPEDIR)/rsync/util.h \
+ $(QPEDIR)/rsync/trace.h
+
+$(QPEDIR)/rsync/sumset.o: $(QPEDIR)/rsync/sumset.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/sumset.h \
+ $(QPEDIR)/rsync/util.h \
+ $(QPEDIR)/rsync/trace.h
+
+$(QPEDIR)/rsync/trace.o: $(QPEDIR)/rsync/trace.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/util.h \
+ $(QPEDIR)/rsync/trace.h
+
+$(QPEDIR)/rsync/tube.o: $(QPEDIR)/rsync/tube.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/util.h \
+ $(QPEDIR)/rsync/job.h \
+ $(QPEDIR)/rsync/stream.h
+
+$(QPEDIR)/rsync/util.o: $(QPEDIR)/rsync/util.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/util.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/trace.h
+
+$(QPEDIR)/rsync/version.o: $(QPEDIR)/rsync/version.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h
+
+$(QPEDIR)/rsync/whole.o: $(QPEDIR)/rsync/whole.c \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/config_linux.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/fileutil.h \
+ $(QPEDIR)/rsync/sumset.h \
+ $(QPEDIR)/rsync/job.h \
+ $(QPEDIR)/rsync/buf.h \
+ $(QPEDIR)/rsync/whole.h \
+ $(QPEDIR)/rsync/util.h
+
+$(QPEDIR)/rsync/qrsync.o: $(QPEDIR)/rsync/qrsync.cpp \
+ $(QPEDIR)/rsync/qrsync.h \
+ $(QPEDIR)/rsync/rsync.h
+
+shutdown.h: shutdown.ui
+ $(UIC) shutdown.ui -o $(INTERFACE_DECL_PATH)/shutdown.h
+
+shutdown.cpp: shutdown.ui
+ $(UIC) shutdown.ui -i shutdown.h -o shutdown.cpp
+
+syncdialog.h: syncdialog.ui
+ $(UIC) syncdialog.ui -o $(INTERFACE_DECL_PATH)/syncdialog.h
+
+syncdialog.cpp: syncdialog.ui
+ $(UIC) syncdialog.ui -i syncdialog.h -o syncdialog.cpp
+
+shutdown.o: shutdown.cpp \
+ shutdown.h
+
+syncdialog.o: syncdialog.cpp
+
+moc_background.o: moc_background.cpp \
+ background.h
+
+moc_desktop.o: moc_desktop.cpp \
+ desktop.h \
+ shutdownimpl.h \
+ shutdown.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+moc_info.o: moc_info.cpp \
+ info.h \
+ background.h
+
+moc_appicons.o: moc_appicons.cpp \
+ appicons.h
+
+moc_taskbar.o: moc_taskbar.cpp \
+ taskbar.h \
+ $(QPEDIR)/include/qpe/custom.h
+
+moc_sidething.o: moc_sidething.cpp \
+ sidething.h \
+ startmenu.h
+
+moc_inputmethods.o: moc_inputmethods.cpp \
+ inputmethods.h \
+ $(QPEDIR)/include/qpe/inputmethodinterface.h \
+ $(QPEDIR)/include/qpe/qcom.h \
+ $(QPEDIR)/include/qpe/quuid.h
+
+moc_systray.o: moc_systray.cpp \
+ systray.h \
+ $(QPEDIR)/include/qpe/taskbarappletinterface.h \
+ $(QPEDIR)/include/qpe/qcom.h \
+ $(QPEDIR)/include/qpe/quuid.h
+
+moc_shutdownimpl.o: moc_shutdownimpl.cpp \
+ shutdownimpl.h \
+ shutdown.h
+
+moc_launcher.o: moc_launcher.cpp \
+ launcher.h \
+ launcherview.h \
+ $(QPEDIR)/include/qpe/storage.h
+
+moc_launcherview.o: moc_launcherview.cpp \
+ launcherview.h \
+ $(QPEDIR)/include/qpe/storage.h
+
+../calibrate/moc_calibrate.o: ../calibrate/moc_calibrate.cpp \
+ ../calibrate/calibrate.h
+
+moc_startmenu.o: moc_startmenu.cpp \
+ startmenu.h
+
+moc_transferserver.o: moc_transferserver.cpp \
+ transferserver.h
+
+moc_qcopbridge.o: moc_qcopbridge.cpp \
+ qcopbridge.h
+
+moc_packageslave.o: moc_packageslave.cpp \
+ packageslave.h
+
+moc_irserver.o: moc_irserver.cpp \
+ irserver.h
+
+moc_shutdown.o: appicons.moc \
+ appicons.cpp \
+ appicons.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h
+
+moc_syncdialog.o: moc_shutdown.cpp \
+ shutdown.h
+
+moc_background.cpp: background.h
+ $(MOC) background.h -o moc_background.cpp
+
+moc_desktop.cpp: desktop.h
+ $(MOC) desktop.h -o moc_desktop.cpp
+
+moc_info.cpp: info.h
+ $(MOC) info.h -o moc_info.cpp
+
+moc_appicons.cpp: appicons.h
+ $(MOC) appicons.h -o moc_appicons.cpp
+
+moc_taskbar.cpp: taskbar.h
+ $(MOC) taskbar.h -o moc_taskbar.cpp
+
+moc_sidething.cpp: sidething.h
+ $(MOC) sidething.h -o moc_sidething.cpp
+
+moc_inputmethods.cpp: inputmethods.h
+ $(MOC) inputmethods.h -o moc_inputmethods.cpp
+
+moc_systray.cpp: systray.h
+ $(MOC) systray.h -o moc_systray.cpp
+
+moc_shutdownimpl.cpp: shutdownimpl.h
+ $(MOC) shutdownimpl.h -o moc_shutdownimpl.cpp
+
+moc_launcher.cpp: launcher.h
+ $(MOC) launcher.h -o moc_launcher.cpp
+
+moc_launcherview.cpp: launcherview.h
+ $(MOC) launcherview.h -o moc_launcherview.cpp
+
+../calibrate/moc_calibrate.cpp: ../calibrate/calibrate.h
+ $(MOC) ../calibrate/calibrate.h -o ../calibrate/moc_calibrate.cpp
+
+moc_startmenu.cpp: startmenu.h
+ $(MOC) startmenu.h -o moc_startmenu.cpp
+
+moc_transferserver.cpp: transferserver.h
+ $(MOC) transferserver.h -o moc_transferserver.cpp
+
+moc_qcopbridge.cpp: qcopbridge.h
+ $(MOC) qcopbridge.h -o moc_qcopbridge.cpp
+
+moc_packageslave.cpp: packageslave.h
+ $(MOC) packageslave.h -o moc_packageslave.cpp
+
+moc_irserver.cpp: irserver.h
+ $(MOC) irserver.h -o moc_irserver.cpp
+
+appicons.moc: appicons.cpp
+ $(MOC) appicons.cpp -o appicons.moc
+
+moc_shutdown.cpp: shutdown.h
+ $(MOC) shutdown.h -o moc_shutdown.cpp
+
+moc_syncdialog.cpp: syncdialog.h
+ $(MOC) syncdialog.h -o moc_syncdialog.cpp
+
+
diff --git a/core/launcher/appicons.cpp b/core/launcher/appicons.cpp
new file mode 100644
index 0000000..c51ee5a
--- a/dev/null
+++ b/core/launcher/appicons.cpp
@@ -0,0 +1,129 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#include "appicons.h"
+
+#include <qpe/qcopenvelope_qws.h>
+
+#include <qtooltip.h>
+#include <qpixmap.h>
+
+
+AppIcons::AppIcons( QWidget *parent ) :
+ QHBox(parent)
+{
+ buttons.setAutoDelete(TRUE);
+
+#ifndef QT_NO_COP
+ QCopChannel* channel = new QCopChannel("Qt/Tray", this);
+ connect(channel, SIGNAL(received(const QCString&, const QByteArray&)),
+ this, SLOT(receive(const QCString&, const QByteArray&)));
+#endif
+}
+
+void AppIcons::setIcon(int id, const QPixmap& pm)
+{
+ button(id)->setPixmap(pm);
+}
+
+class FlatButton : public QLabel {
+ Q_OBJECT
+public:
+ FlatButton(QWidget* parent) : QLabel(parent) { }
+
+ void mouseDoubleClickEvent(QMouseEvent* e)
+ {
+ emit clicked(e->pos(),e->button(),TRUE);
+ }
+ void mouseReleaseEvent(QMouseEvent* e)
+ {
+ if ( rect().contains(e->pos()) )
+ emit clicked(e->pos(),e->button(),FALSE);
+ }
+
+signals:
+ void clicked(const QPoint&, int, bool);
+};
+
+QLabel* AppIcons::button(int id)
+{
+ QLabel* f = buttons.find(id);
+ if ( !f ) {
+ buttons.insert(id,f=new FlatButton(this));
+ connect(f,SIGNAL(clicked(const QPoint&, int, bool)),this,SLOT(clicked(const QPoint&, int, bool)));
+ f->show();
+ }
+ return f;
+}
+
+int AppIcons::findId(QLabel* b)
+{
+ QIntDictIterator<QLabel> it(buttons);
+ for ( ; ; ++it )
+ if ( it.current() == b ) return it.currentKey();
+}
+
+void AppIcons::clicked(const QPoint& relpos, int button, bool dbl)
+{
+#ifndef QT_NO_COP
+ QLabel* s = (QLabel*)sender();
+ if ( button == RightButton ) {
+ QCopEnvelope("Qt/Tray","popup(int,QPoint)")
+ << findId(s) << s->mapToGlobal(QPoint(0,0));
+ } else {
+ QCopEnvelope("Qt/Tray",
+ dbl ? "doubleClicked(int,QPoint)" : "clicked(int,QPoint)")
+ << findId(s) << relpos;
+ }
+#endif
+}
+
+void AppIcons::setToolTip(int id, const QString& tip)
+{
+ QToolTip::add(button(id),tip);
+}
+
+void AppIcons::remove(int id)
+{
+ buttons.remove(id);
+}
+
+void AppIcons::receive( const QCString &msg, const QByteArray &data )
+{
+ QDataStream stream( data, IO_ReadOnly );
+ if ( msg == "remove(int)" ) {
+ int id;
+ stream >> id;
+ remove(id);
+ } else if ( msg == "setIcon(int,QPixmap)" ) {
+ int id;
+ QPixmap pm;
+ stream >> id >> pm;
+ setIcon(id,pm);
+ } else if ( msg == "setToolTip(int,QString)" ) {
+ int id;
+ QString s;
+ stream >> id >> s;
+ setToolTip(id,s);
+ }
+}
+
+#include "appicons.moc"
diff --git a/core/launcher/appicons.h b/core/launcher/appicons.h
new file mode 100644
index 0000000..f53f4a7
--- a/dev/null
+++ b/core/launcher/appicons.h
@@ -0,0 +1,51 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef APPICONS_H
+#define APPICONS_H
+
+
+#include <qhbox.h>
+#include <qintdict.h>
+#include <qlabel.h>
+
+
+class AppIcons : public QHBox
+{
+ Q_OBJECT
+
+public:
+ AppIcons( QWidget *parent );
+ void setIcon(int id, const QPixmap&);
+ void setToolTip(int id, const QString&);
+ void remove(int id);
+
+private slots:
+ void receive( const QCString &msg, const QByteArray &data );
+ void clicked(const QPoint& relpos, int button, bool dbl);
+
+private:
+ QIntDict<QLabel> buttons;
+ QLabel* button(int id);
+ int findId(QLabel*);
+};
+
+
+#endif
diff --git a/core/launcher/apps.h b/core/launcher/apps.h
new file mode 100644
index 0000000..6216941
--- a/dev/null
+++ b/core/launcher/apps.h
@@ -0,0 +1,83 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+// To add a new app, include appropriate files and add another APP().
+
+#ifndef APP_INCLUDES
+#define APP_INCLUDES
+
+#include "../addressbook/addressbook.h"
+#include "../datebook/datebook.h"
+#include "../helpbrowser/helpbrowser.h"
+#include "../minesweep/minesweep.h"
+#include "../textedit/textedit.h"
+#include "../todo/mainwindow.h"
+#include "../citytime/citytime.h"
+#include "../clock/clock.h"
+#include "../calculator/calculatorimpl.h"
+#include "../sysinfo/sysinfo.h"
+#include "../settings/appearance/settings.h"
+//#include "../settings/language/settings.h"
+//#include "../settings/light-and-power/settings.h"
+//#include "../settings/rotation/settings.h"
+#include "../settings/systemtime/settime.h"
+#if !defined(QT_QPE_SMALL_BUILD)
+#include "../filebrowser/filebrowser.h"
+#include "../solitaire/canvascardwindow.h"
+#include "../snake/interface.h"
+#include "../parashoot/interface.h"
+#include "../mpegplayer/mediaplayer.h"
+#endif
+#if !defined(QT_DEMO_SINGLE_FLOPPY) && !defined(QT_QPE_SMALL_BUILD)
+#include "../embeddedkonsole/konsole.h"
+#include "../wordgame/wordgame.h"
+#endif
+
+#endif
+
+// app-id class maximize? documentary?
+
+APP( "addressbook", AddressbookWindow, 1, 0 )
+APP( "datebook", DateBook, 1, 0 )
+APP( "helpbrowser", HelpBrowser, 1, 1 )
+APP( "textedit", TextEdit, 1, 1 )
+APP( "todo", TodoWindow, 1, 0 )
+APP( "calculator", CalculatorImpl, 1, 0 )
+APP( "citytime", CityTime, 1, 0 )
+APP( "clock", Clock, 1, 0 )
+APP( "minesweep", MineSweep, 1, 0 )
+APP( "sysinfo", SystemInfo, 1, 0 )
+APP( "appearance", AppearanceSettings, 1, 0 )
+APP( "systemtime", SetDateTime, 1, 0 )
+#if !defined(QT_QPE_SMALL_BUILD)
+//APP( "light-and-power", LightSettings, 1, 0 )
+//APP( "sound", SoundSettings, 1, 0 )
+APP( "filebrowser", FileBrowser, 1, 0 )
+APP( "solitaire", CanvasCardWindow, 1, 0 )
+APP( "snake", SnakeGame, 1, 0 )
+APP( "parashoot", ParaShoot, 1, 0 )
+APP( "mpegplayer", MediaPlayer, 1, 0 )
+#endif
+#if !defined(QT_DEMO_SINGLE_FLOPPY) && !defined(QT_QPE_SMALL_BUILD)
+APP( "embeddedkonsole", Konsole, 1, 0 )
+APP( "wordgame", WordGame, 1, 0 )
+#endif
+
diff --git a/core/launcher/background.cpp b/core/launcher/background.cpp
new file mode 100644
index 0000000..04ebc37
--- a/dev/null
+++ b/core/launcher/background.cpp
@@ -0,0 +1,41 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "background.h"
+#include "desktop.h"
+
+#include <qpe/resource.h>
+
+#include <qpainter.h>
+
+
+Background::Background( Desktop *d ) :
+ QWidget( d, 0, WStyle_Tool | WStyle_Customize )
+{
+/*
+ if ( QPixmap::defaultDepth() < 12 ) {
+ setBackgroundColor(QColor(0x20, 0xb0, 0x50));
+ } else {
+ setBackgroundPixmap( Resource::loadPixmap( "bg" ) );
+ }
+*/
+ setBackgroundMode( PaletteButton );
+}
+
diff --git a/core/launcher/background.h b/core/launcher/background.h
new file mode 100644
index 0000000..0885747
--- a/dev/null
+++ b/core/launcher/background.h
@@ -0,0 +1,40 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef __BACKGROUND_H__
+#define __BACKGROUND_H__
+
+
+#include <qwidget.h>
+
+
+class Desktop;
+
+
+class Background : public QWidget {
+ Q_OBJECT
+public:
+ Background( Desktop *d );
+};
+
+
+#endif // __BACKGROUND_H__
+
+
diff --git a/core/launcher/desktop.cpp b/core/launcher/desktop.cpp
new file mode 100644
index 0000000..d39af25
--- a/dev/null
+++ b/core/launcher/desktop.cpp
@@ -0,0 +1,655 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "desktop.h"
+#include "info.h"
+#include "launcher.h"
+#include "mrulist.h"
+#include "qcopbridge.h"
+#include "shutdownimpl.h"
+#include "startmenu.h"
+#include "taskbar.h"
+#include "transferserver.h"
+#include "irserver.h"
+#include "packageslave.h"
+
+#include <qpe/applnk.h>
+#include <qpe/mimetype.h>
+#include <qpe/password.h>
+#include <qpe/config.h>
+#include <qpe/power.h>
+#include <qpe/qcopenvelope_qws.h>
+#include <qpe/global.h>
+#ifdef QT_QWS_CUSTOM
+#include "qpe/custom.h"
+#endif
+
+#include <qgfx_qws.h>
+#include <qmainwindow.h>
+#include <qmessagebox.h>
+#include <qtimer.h>
+#include <qwindowsystem_qws.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+
+static Desktop* qpedesktop = 0;
+static int loggedin=0;
+static void login(bool at_poweron)
+{
+ if ( !loggedin ) {
+ Global::terminateBuiltin("calibrate");
+ Password::authenticate(at_poweron);
+ loggedin=1;
+ QCopEnvelope e( "QPE/Desktop", "unlocked()" );
+ }
+}
+
+bool Desktop::screenLocked()
+{
+ return loggedin == 0;
+}
+
+/*
+ Priority is number of alerts that are needed to pop up
+ alert.
+ */
+class DesktopPowerAlerter : public QMessageBox
+{
+public:
+ DesktopPowerAlerter( QWidget *parent, const char *name = 0 )
+ : QMessageBox( tr("Battery Status"), "Low Battery",
+ QMessageBox::Critical,
+ QMessageBox::Ok | QMessageBox::Default,
+ QMessageBox::NoButton, QMessageBox::NoButton,
+ parent, name, FALSE )
+ {
+ currentPriority = INT_MAX;
+ alertCount = 0;
+ }
+
+ void alert( const QString &text, int priority );
+ void hideEvent( QHideEvent * );
+private:
+ int currentPriority;
+ int alertCount;
+};
+
+void DesktopPowerAlerter::alert( const QString &text, int priority )
+{
+ alertCount++;
+ if ( alertCount < priority )
+ return;
+ if ( priority > currentPriority )
+ return;
+ currentPriority = priority;
+ setText( text );
+ show();
+}
+
+
+void DesktopPowerAlerter::hideEvent( QHideEvent *e )
+{
+ QMessageBox::hideEvent( e );
+ alertCount = 0;
+ currentPriority = INT_MAX;
+}
+
+
+
+DesktopApplication::DesktopApplication( int& argc, char **argv, Type t )
+ : QPEApplication( argc, argv, t )
+{
+
+ QTimer *t = new QTimer( this );
+ connect( t, SIGNAL(timeout()), this, SLOT(psTimeout()) );
+ t->start( 10000 );
+ ps = new PowerStatus;
+ pa = new DesktopPowerAlerter( 0 );
+}
+
+
+DesktopApplication::~DesktopApplication()
+{
+ delete ps;
+ delete pa;
+}
+
+
+enum MemState { Unknown, VeryLow, Low, Normal } memstate=Unknown;
+
+#ifdef Q_WS_QWS
+bool DesktopApplication::qwsEventFilter( QWSEvent *e )
+{
+ qpedesktop->checkMemory();
+
+ if ( e->type == QWSEvent::Key ) {
+ QWSKeyEvent *ke = (QWSKeyEvent *)e;
+ if ( !loggedin && ke->simpleData.keycode != Key_F34 )
+ return TRUE;
+ bool press = ke->simpleData.is_press;
+ if ( !keyboardGrabbed() ) {
+ if ( ke->simpleData.keycode == Key_F9 ) {
+ if ( press ) emit datebook();
+ return TRUE;
+ }
+ if ( ke->simpleData.keycode == Key_F10 ) {
+ if ( !press && cardSendTimer ) {
+ emit contacts();
+ delete cardSendTimer;
+ } else if ( press ) {
+ cardSendTimer = new QTimer();
+ cardSendTimer->start( 2000, TRUE );
+ connect( cardSendTimer, SIGNAL( timeout() ), this, SLOT( sendCard() ) );
+ }
+ return TRUE;
+ }
+ /* menu key now opens application menu/toolbar
+ if ( ke->simpleData.keycode == Key_F11 ) {
+ if ( press ) emit menu();
+ return TRUE;
+ }
+ */
+ if ( ke->simpleData.keycode == Key_F12 ) {
+ while( activePopupWidget() )
+ activePopupWidget()->close();
+ if ( press ) emit launch();
+ return TRUE;
+ }
+ if ( ke->simpleData.keycode == Key_F13 ) {
+ if ( press ) emit email();
+ return TRUE;
+ }
+ }
+ if ( ke->simpleData.keycode == Key_F34 ) {
+ if ( press ) emit power();
+ return TRUE;
+ }
+ if ( ke->simpleData.keycode == Key_F35 ) {
+ if ( press ) emit backlight();
+ return TRUE;
+ }
+ if ( ke->simpleData.keycode == Key_F32 ) {
+ if ( press ) QCopEnvelope e( "QPE/Desktop", "startSync()" );
+ return TRUE;
+ }
+ if ( ke->simpleData.keycode == Key_F31 && !ke->simpleData.modifiers ) {
+ if ( press ) emit symbol();
+ return TRUE;
+ }
+ if ( ke->simpleData.keycode == Key_NumLock ) {
+ if ( press ) emit numLockStateToggle();
+ }
+ if ( ke->simpleData.keycode == Key_CapsLock ) {
+ if ( press ) emit capsLockStateToggle();
+ }
+ if ( press )
+ qpedesktop->keyClick();
+ } else {
+ if ( e->type == QWSEvent::Mouse ) {
+ QWSMouseEvent *me = (QWSMouseEvent *)e;
+ static bool up = TRUE;
+ if ( me->simpleData.state&LeftButton ) {
+ if ( up ) {
+ up = FALSE;
+ qpedesktop->screenClick();
+ }
+ } else {
+ up = TRUE;
+ }
+ }
+ }
+
+ return QPEApplication::qwsEventFilter( e );
+}
+#endif
+
+void DesktopApplication::psTimeout()
+{
+ qpedesktop->checkMemory(); // in case no events are being generated
+
+ *ps = PowerStatusManager::readStatus();
+
+ if ( (ps->batteryStatus() == PowerStatus::VeryLow ) ) {
+ pa->alert( tr( "Battery is running very low." ), 6 );
+ }
+
+ if ( ps->batteryStatus() == PowerStatus::Critical ) {
+ pa->alert( tr( "Battery level is critical!\n"
+ "Keep power off until power restored!" ), 1 );
+ }
+
+ if ( ps->backupBatteryStatus() == PowerStatus::VeryLow ) {
+ pa->alert( tr( "The Back-up battery is very low.\nPlease charge the back-up battery." ), 3 );
+ }
+}
+
+
+void DesktopApplication::sendCard()
+{
+ delete cardSendTimer;
+ cardSendTimer = 0;
+ QString card = getenv("HOME");
+ card += "/Applications/addressbook/businesscard.vcf";
+
+ if ( QFile::exists( card ) ) {
+ QCopEnvelope e("QPE/Obex", "send(QString,QString,QString)");
+ QString mimetype = "text/x-vCard";
+ e << tr("business card") << card << mimetype;
+ }
+}
+
+#if defined(QPE_HAVE_MEMALERTER)
+QPE_MEMALERTER_IMPL
+#endif
+
+#if defined(CUSTOM_SOUND_IMPL)
+CUSTOM_SOUND_IMPL
+#endif
+
+//===========================================================================
+
+Desktop::Desktop() :
+ QWidget( 0, 0, WStyle_Tool | WStyle_Customize ),
+ qcopBridge( 0 ),
+ transferServer( 0 ),
+ packageSlave( 0 )
+{
+#ifdef CUSTOM_SOUND_INIT
+ CUSTOM_SOUND_INIT;
+#endif
+
+ qpedesktop = this;
+
+// bg = new Info( this );
+ tb = new TaskBar;
+
+ launcher = new Launcher( 0, 0, WStyle_Customize | QWidget::WGroupLeader );
+
+ connect(launcher, SIGNAL(busy()), tb, SLOT(startWait()));
+ connect(launcher, SIGNAL(notBusy(const QString&)), tb, SLOT(stopWait(const QString&)));
+
+ int displayw = qApp->desktop()->width();
+ int displayh = qApp->desktop()->height();
+
+
+ QSize sz = tb->sizeHint();
+
+ setGeometry( 0, displayh-sz.height(), displayw, sz.height() );
+ tb->setGeometry( 0, displayh-sz.height(), displayw, sz.height() );
+
+ tb->show();
+ launcher->showMaximized();
+ launcher->show();
+ launcher->raise();
+#if defined(QPE_HAVE_MEMALERTER)
+ initMemalerter();
+#endif
+ // start services
+ startTransferServer();
+ (void) new IrServer( this );
+ rereadVolumes();
+
+ packageSlave = new PackageSlave( this );
+ connect(qApp, SIGNAL(volumeChanged(bool)), this, SLOT(rereadVolumes()));
+
+ qApp->installEventFilter( this );
+}
+
+void Desktop::show()
+{
+ login(TRUE);
+ QWidget::show();
+}
+
+Desktop::~Desktop()
+{
+ delete launcher;
+ delete tb;
+ delete qcopBridge;
+ delete transferServer;
+}
+
+bool Desktop::recoverMemory()
+{
+ return tb->recoverMemory();
+}
+
+void Desktop::checkMemory()
+{
+#if defined(QPE_HAVE_MEMALERTER)
+ static bool ignoreNormal=FALSE;
+ static bool existingMessage=FALSE;
+
+ if(existingMessage)
+ return; // don't show a second message while still on first
+
+ existingMessage = TRUE;
+ switch ( memstate ) {
+ case Unknown:
+ break;
+ case Low:
+ memstate = Unknown;
+ if ( recoverMemory() )
+ ignoreNormal = TRUE;
+ else
+ QMessageBox::warning( 0 , "Memory Status",
+ "The memory smacks of shortage. \n"
+ "Please save data. " );
+ break;
+ case Normal:
+ memstate = Unknown;
+ if ( ignoreNormal )
+ ignoreNormal = FALSE;
+ else
+ QMessageBox::information ( 0 , "Memory Status",
+ "There is enough memory again." );
+ break;
+ case VeryLow:
+ memstate = Unknown;
+ QMessageBox::critical( 0 , "Memory Status",
+ "The memory is very low. \n"
+ "Please end this application \n"
+ "immediately." );
+ recoverMemory();
+ }
+ existingMessage = FALSE;
+#endif
+}
+
+static bool isVisibleWindow(int wid)
+{
+ const QList<QWSWindow> &list = qwsServer->clientWindows();
+ QWSWindow* w;
+ for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) {
+ if ( w->winId() == wid )
+ return !w->isFullyObscured();
+ }
+ return FALSE;
+}
+
+static bool hasVisibleWindow(const QString& clientname)
+{
+ const QList<QWSWindow> &list = qwsServer->clientWindows();
+ QWSWindow* w;
+ for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) {
+ if ( w->client()->identity() == clientname && !w->isFullyObscured() )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void Desktop::raiseLauncher()
+{
+ if ( isVisibleWindow(launcher->winId()) )
+ launcher->nextView();
+ else
+ launcher->raise();
+}
+
+void Desktop::executeOrModify(const QString& appLnkFile)
+{
+ AppLnk lnk(MimeType::appsFolderName() + "/" + appLnkFile);
+ if ( lnk.isValid() ) {
+ QCString app = lnk.exec().utf8();
+ Global::terminateBuiltin("calibrate");
+ if ( QCopChannel::isRegistered("QPE/Application/" + app) ) {
+ MRUList::addTask(&lnk);
+ if ( hasVisibleWindow(app) )
+ QCopChannel::send("QPE/Application/" + app, "nextView()");
+ else
+ QCopChannel::send("QPE/Application/" + app, "raise()");
+ } else {
+ lnk.execute();
+ }
+ }
+}
+
+void Desktop::raiseDatebook()
+{
+ executeOrModify("Applications/datebook.desktop");
+}
+
+void Desktop::raiseContacts()
+{
+ executeOrModify("Applications/addressbook.desktop");
+}
+
+void Desktop::raiseMenu()
+{
+ Global::terminateBuiltin("calibrate");
+ tb->startMenu()->launch();
+}
+
+void Desktop::raiseEmail()
+{
+ executeOrModify("Applications/qtmail.desktop");
+}
+
+#if defined(QPE_HAVE_TOGGLELIGHT)
+#include <qpe/config.h>
+
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <linux/ioctl.h>
+#include <time.h>
+#endif
+
+static bool blanked=FALSE;
+
+static void blankScreen()
+{
+ if ( !qt_screen ) return;
+ /* Should use a big black window instead.
+ QGfx* g = qt_screen->screenGfx();
+ g->fillRect(0,0,qt_screen->width(),qt_screen->height());
+ delete g;
+ */
+ blanked = TRUE;
+}
+
+static void darkScreen()
+{
+ extern void qpe_setBacklight(int);
+ qpe_setBacklight(0); // force off
+}
+
+
+void Desktop::togglePower()
+{
+ bool wasloggedin = loggedin;
+ loggedin=0;
+ darkScreen();
+ if ( wasloggedin )
+ blankScreen();
+ system("apm --suspend");
+ QWSServer::screenSaverActivate( FALSE );
+ {
+ QCopEnvelope("QPE/Card", "mtabChanged()" ); // might have changed while asleep
+ QCopEnvelope e("QPE/System", "setBacklight(int)");
+ e << -3; // Force on
+ }
+ if ( wasloggedin )
+ login(TRUE);
+ //qcopBridge->closeOpenConnections();
+ //qDebug("called togglePower()!!!!!!");
+}
+
+void Desktop::toggleLight()
+{
+ QCopEnvelope e("QPE/System", "setBacklight(int)");
+ e << -2; // toggle
+}
+
+void Desktop::toggleSymbolInput()
+{
+ tb->toggleSymbolInput();
+}
+
+void Desktop::toggleNumLockState()
+{
+ tb->toggleNumLockState();
+}
+
+void Desktop::toggleCapsLockState()
+{
+ tb->toggleCapsLockState();
+}
+
+void Desktop::styleChange( QStyle &s )
+{
+ QWidget::styleChange( s );
+ int displayw = qApp->desktop()->width();
+ int displayh = qApp->desktop()->height();
+
+ QSize sz = tb->sizeHint();
+
+ tb->setGeometry( 0, displayh-sz.height(), displayw, sz.height() );
+}
+
+void DesktopApplication::shutdown()
+{
+ if ( type() != GuiServer )
+ return;
+ ShutdownImpl *sd = new ShutdownImpl( 0, 0, WDestructiveClose );
+ connect( sd, SIGNAL(shutdown(ShutdownImpl::Type)),
+ this, SLOT(shutdown(ShutdownImpl::Type)) );
+ sd->showMaximized();
+}
+
+void DesktopApplication::shutdown( ShutdownImpl::Type t )
+{
+ switch ( t ) {
+ case ShutdownImpl::ShutdownSystem:
+ execlp("shutdown", "shutdown", "-h", "now", (void*)0);
+ break;
+ case ShutdownImpl::RebootSystem:
+ execlp("shutdown", "shutdown", "-r", "now", (void*)0);
+ break;
+ case ShutdownImpl::RestartDesktop:
+ restart();
+ break;
+ case ShutdownImpl::TerminateDesktop:
+ prepareForTermination(FALSE);
+ quit();
+ break;
+ }
+}
+
+void DesktopApplication::restart()
+{
+ prepareForTermination(TRUE);
+
+#ifdef Q_WS_QWS
+ for ( int fd = 3; fd < 100; fd++ )
+ close( fd );
+#if defined(QT_DEMO_SINGLE_FLOPPY)
+ execl( "/sbin/init", "qpe", 0 );
+#elif defined(QT_QWS_CASSIOPEIA)
+ execl( "/bin/sh", "sh", 0 );
+#else
+ execl( (qpeDir()+"/bin/qpe").latin1(), "qpe", 0 );
+#endif
+ exit(1);
+#endif
+}
+
+void Desktop::startTransferServer()
+{
+ // start qcop bridge server
+ qcopBridge = new QCopBridge( 4243 );
+ if ( !qcopBridge->ok() ) {
+ delete qcopBridge;
+ qcopBridge = 0;
+ }
+ // start transfer server
+ transferServer = new TransferServer( 4242 );
+ if ( !transferServer->ok() ) {
+ delete transferServer;
+ transferServer = 0;
+ }
+ if ( !transferServer || !qcopBridge )
+ startTimer( 2000 );
+}
+
+void Desktop::timerEvent( QTimerEvent *e )
+{
+ killTimer( e->timerId() );
+ startTransferServer();
+}
+
+void Desktop::terminateServers()
+{
+ delete transferServer;
+ delete qcopBridge;
+ transferServer = 0;
+ qcopBridge = 0;
+}
+
+void Desktop::rereadVolumes()
+{
+ Config cfg("Sound");
+ cfg.setGroup("System");
+ touchclick = cfg.readBoolEntry("Touch");
+ keyclick = cfg.readBoolEntry("Key");
+}
+
+void Desktop::keyClick()
+{
+#ifdef CUSTOM_SOUND_KEYCLICK
+ if ( keyclick )
+ CUSTOM_SOUND_KEYCLICK;
+#endif
+}
+
+void Desktop::screenClick()
+{
+#ifdef CUSTOM_SOUND_TOUCH
+ if ( touchclick )
+ CUSTOM_SOUND_TOUCH;
+#endif
+}
+
+void Desktop::soundAlarm()
+{
+#ifdef CUSTOM_SOUND_ALARM
+ CUSTOM_SOUND_ALARM;
+#endif
+}
+
+bool Desktop::eventFilter( QObject *w, QEvent *ev )
+{
+ if ( ev->type() == QEvent::KeyPress ) {
+ QKeyEvent *ke = (QKeyEvent *)ev;
+ if ( ke->key() == Qt::Key_F11 ) { // menu key
+ QWidget *active = qApp->activeWindow();
+ if ( active && active->isPopup() ) {
+ active->close();
+ }
+ raiseMenu();
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
diff --git a/core/launcher/desktop.h b/core/launcher/desktop.h
new file mode 100644
index 0000000..dfdbeab
--- a/dev/null
+++ b/core/launcher/desktop.h
@@ -0,0 +1,129 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef __DESKTOP_H__
+#define __DESKTOP_H__
+
+
+#include "shutdownimpl.h"
+
+#include <qpe/qpeapplication.h>
+
+#include <qwidget.h>
+
+class Background;
+class Launcher;
+class TaskBar;
+class PowerStatus;
+class QCopBridge;
+class TransferServer;
+class DesktopPowerAlerter;
+class PackageSlave;
+
+class DesktopApplication : public QPEApplication
+{
+ Q_OBJECT
+public:
+ DesktopApplication( int& argc, char **argv, Type t );
+ ~DesktopApplication();
+signals:
+ void home();
+ void datebook();
+ void contacts();
+ void launch();
+ void email();
+ void backlight();
+ void power();
+ void symbol();
+ void numLockStateToggle();
+ void capsLockStateToggle();
+ void prepareForRestart();
+
+protected:
+#ifdef Q_WS_QWS
+ bool qwsEventFilter( QWSEvent * );
+#endif
+ void shutdown();
+ void restart();
+
+protected slots:
+ void shutdown(ShutdownImpl::Type);
+ void psTimeout();
+ void sendCard();
+private:
+ DesktopPowerAlerter *pa;
+ PowerStatus *ps;
+ QTimer *cardSendTimer;
+};
+
+
+class Desktop : public QWidget {
+ Q_OBJECT
+public:
+ Desktop();
+ ~Desktop();
+
+ static bool screenLocked();
+
+ void show();
+ void checkMemory();
+
+ void keyClick();
+ void screenClick();
+ static void soundAlarm();
+
+public slots:
+ void raiseDatebook();
+ void raiseContacts();
+ void raiseMenu();
+ void raiseLauncher();
+ void raiseEmail();
+ void togglePower();
+ void toggleLight();
+ void toggleNumLockState();
+ void toggleCapsLockState();
+ void toggleSymbolInput();
+ void terminateServers();
+ void rereadVolumes();
+
+protected:
+ void executeOrModify(const QString& appLnkFile);
+ void styleChange( QStyle & );
+ void timerEvent( QTimerEvent *e );
+ bool eventFilter( QObject *, QEvent * );
+
+ QWidget *bg;
+ Launcher *launcher;
+ TaskBar *tb;
+
+private:
+ void startTransferServer();
+ bool recoverMemory();
+
+ QCopBridge *qcopBridge;
+ TransferServer *transferServer;
+ PackageSlave *packageSlave;
+
+ bool keyclick,touchclick;
+};
+
+
+#endif // __DESKTOP_H__
+
diff --git a/core/launcher/info.cpp b/core/launcher/info.cpp
new file mode 100644
index 0000000..609e9e2
--- a/dev/null
+++ b/core/launcher/info.cpp
@@ -0,0 +1,116 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "info.h"
+#include "desktop.h"
+
+#include <qpe/resource.h>
+#include <qpe/version.h>
+
+#include <qlayout.h>
+#include <qimage.h>
+#include <qpainter.h>
+#include <qsimplerichtext.h>
+
+
+Info *desktopInfo = NULL;
+
+
+Info::Info( Desktop *d ) : Background( d ), needsClear(FALSE), menuHasBeenClicked(FALSE)
+{
+ QString motd;
+ /* eg.
+ =
+ "<table width=100% cellspacing=0 cellpadding=2>"
+ "<tr><td bgcolor=#9090ff><h2>Today&nbsp;&nbsp;&nbsp;&nbsp;<small>June 15, 2001</small></h2></td>"
+ "<tr><td bgcolor=#c0c0ff><big><a href=datebook>Appointments</a></big>"
+ "<tr><td bgcolor=#e0e0ff>"
+ "<b>8:30am</b> Meeting with John<br>"
+ "<b>1:10pm</b> Lunch with Sharon"
+ "<tr><td bgcolor=#c0c0ff><big><a href=todo>Reminders</a></big>"
+ "<tr><td bgcolor=#e0e0ff>"
+ "<b>#1</b> Port XMAME to QPE<br>"
+ "<b>#2</b> Flowers for wife"
+ "<tr><td bgcolor=#c0c0ff><big><a href=channels>Net channels</a></big>"
+ "<tr><td bgcolor=#e0e0ff>"
+ "<b>LinuxDevices:</b><a href=http://www.linuxdevices.com> QPE announcement</a><br>"
+ "<b>Slashdot:</b><a href=http://www.slashdot.org> GPL Examined</a>"
+ "</table>";
+ */
+ info = new QSimpleRichText(motd, QFont("lucidux_sans",10));
+ desktopInfo = this;
+}
+
+
+void Info::mouseReleaseEvent( QMouseEvent * )
+{
+}
+
+
+void Info::menuClicked( )
+{
+ QPainter p(this);
+ if ( needsClear ) {
+ QColor col = colorGroup().color( QColorGroup::Button ).dark( 0 );
+ p.fillRect( 5, height() - 24, width() - 5, 20, col );
+ needsClear = FALSE;
+ menuHasBeenClicked = TRUE;
+ }
+}
+
+
+void Info::paintEvent( QPaintEvent *e )
+{
+ QPainter p(this);
+
+ BrushStyle styles[] = { Dense1Pattern, Dense2Pattern, Dense3Pattern,
+ Dense4Pattern, Dense5Pattern, Dense6Pattern };
+
+ QColor shade = colorGroup().color( QColorGroup::Button ).dark( 110 );
+ int blend = width() * 3 / 4;
+ int step = blend/6;
+ p.fillRect( 0, 0, width()-blend, 30, shade );
+ for ( int i = 0; i < 6; i++ ) {
+ QBrush brush( shade, styles[i] );
+ p.fillRect( width()-blend+i*step, 0, step, 30, brush );
+ }
+ p.setFont( QFont("Helvetica", 24, QFont::Bold) );
+ p.setPen( shade.dark( 140 ) );
+ p.drawText( 5, 24, "QPE" );
+ int pos = 5 + p.fontMetrics().width( "QPE" );
+ QFont f("Helvetica", 10, QFont::Bold);
+ p.setFont( f );
+ p.drawText( pos + 5, 24, QString( "Version " ) + QPE_VERSION );
+
+ if (!menuHasBeenClicked) {
+ p.drawText( 5, height()-10, QString( "Click on the " ) );
+ int pos = 5 + p.fontMetrics().width( "Click on the " );
+ p.drawPixmap( pos, height()-10-14, Resource::loadPixmap( "go" ) );
+ p.drawText( pos + 16, height()-10, QString( " logo to start." ) );
+ needsClear = TRUE;
+ }
+
+ if ( info ) {
+ info->setWidth(&p,width()-10);
+ info->draw(&p, 5, 35, e->region(), colorGroup());
+ }
+}
+
+
diff --git a/core/launcher/info.h b/core/launcher/info.h
new file mode 100644
index 0000000..317dec5
--- a/dev/null
+++ b/core/launcher/info.h
@@ -0,0 +1,55 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef __INFO_H__
+#define __INFO_H__
+
+
+#include <qwidget.h>
+#include <qpainter.h>
+#include "background.h"
+
+class QSimpleRichText;
+
+class Info : public Background {
+ Q_OBJECT
+public:
+ Info( Desktop *d );
+ void menuClicked( );
+
+signals:
+ void giveInfo( );
+
+protected:
+ void mouseReleaseEvent( QMouseEvent *e );
+ void paintEvent( QPaintEvent *pe );
+
+private:
+ QSimpleRichText* info;
+ bool needsClear;
+ bool menuHasBeenClicked;
+};
+
+
+extern Info *desktopInfo;
+
+
+#endif // __INFO_H__
+
diff --git a/core/launcher/inputmethods.cpp b/core/launcher/inputmethods.cpp
new file mode 100644
index 0000000..003dc77
--- a/dev/null
+++ b/core/launcher/inputmethods.cpp
@@ -0,0 +1,297 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "inputmethods.h"
+
+#include <qpe/config.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/inputmethodinterface.h>
+#include <qpe/qlibrary.h>
+
+#include <qpopupmenu.h>
+#include <qpushbutton.h>
+#include <qtoolbutton.h>
+#include <qwidget.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <qdir.h>
+#include <stdlib.h>
+#include <qtranslator.h>
+
+#ifdef Q_WS_QWS
+#include <qwindowsystem_qws.h>
+#include <qwsevent_qws.h>
+#endif
+
+#ifdef SINGLE_APP
+#include "handwritingimpl.h"
+#include "keyboardimpl.h"
+#include "pickboardimpl.h"
+#endif
+
+
+/* XPM */
+static const char * tri_xpm[]={
+"9 9 2 1",
+"a c #000000",
+". c None",
+".........",
+".........",
+".........",
+"....a....",
+"...aaa...",
+"..aaaaa..",
+".aaaaaaa.",
+".........",
+"........."};
+
+static const int inputWidgetStyle = QWidget::WStyle_Customize |
+ QWidget::WStyle_Tool |
+ QWidget::WStyle_StaysOnTop |
+ QWidget::WGroupLeader;
+
+InputMethods::InputMethods( QWidget *parent ) :
+ QWidget( parent, "InputMethods", WStyle_Tool | WStyle_Customize )
+{
+ method = NULL;
+
+ QHBoxLayout *hbox = new QHBoxLayout( this );
+
+ kbdButton = new QToolButton( this );
+ kbdButton->setFocusPolicy(NoFocus);
+ kbdButton->setToggleButton( TRUE );
+ kbdButton->setFixedHeight( 17 );
+ kbdButton->setFixedWidth( 32 );
+ kbdButton->setAutoRaise( TRUE );
+ kbdButton->setUsesBigPixmap( TRUE );
+ hbox->addWidget( kbdButton );
+ connect( kbdButton, SIGNAL(toggled(bool)), this, SLOT(showKbd(bool)) );
+
+ kbdChoice = new QToolButton( this );
+ kbdChoice->setFocusPolicy(NoFocus);
+ kbdChoice->setPixmap( QPixmap( (const char **)tri_xpm ) );
+ kbdChoice->setFixedHeight( 17 );
+ kbdChoice->setFixedWidth( 12 );
+ kbdChoice->setAutoRaise( TRUE );
+ hbox->addWidget( kbdChoice );
+ connect( kbdChoice, SIGNAL(clicked()), this, SLOT(chooseKbd()) );
+
+ connect( (QPEApplication*)qApp, SIGNAL(clientMoused()),
+ this, SLOT(resetStates()) );
+
+ loadInputMethods();
+}
+
+InputMethods::~InputMethods()
+{
+#ifndef SINGLE_APP
+ QValueList<InputMethod>::Iterator mit;
+ for ( mit = inputMethodList.begin(); mit != inputMethodList.end(); ++mit ) {
+ int i = (*mit).interface->release();
+ (*mit).library->unload();
+ delete (*mit).library;
+ }
+#endif
+}
+
+void InputMethods::hideInputMethod()
+{
+ kbdButton->setOn( FALSE );
+}
+
+void InputMethods::showInputMethod()
+{
+ kbdButton->setOn( TRUE );
+}
+
+void InputMethods::showInputMethod(const QString& name)
+{
+ int i = 0;
+ QValueList<InputMethod>::Iterator it;
+ InputMethod *im = 0;
+ for ( it = inputMethodList.begin(); it != inputMethodList.end(); ++it, i++ ) {
+ if ( (*it).interface->name() == name ) {
+ im = &(*it);
+ break;
+ }
+ }
+ if ( im )
+ chooseMethod(im);
+}
+
+void InputMethods::resetStates()
+{
+ if ( method )
+ method->interface->resetState();
+}
+
+QRect InputMethods::inputRect() const
+{
+ if ( !method || !method->widget->isVisible() )
+ return QRect();
+ else
+ return method->widget->geometry();
+}
+
+void InputMethods::loadInputMethods()
+{
+#ifndef SINGLE_APP
+ hideInputMethod();
+ method = 0;
+
+ QValueList<InputMethod>::Iterator mit;
+ for ( mit = inputMethodList.begin(); mit != inputMethodList.end(); ++mit ) {
+ (*mit).interface->release();
+ (*mit).library->unload();
+ delete (*mit).library;
+ }
+ inputMethodList.clear();
+
+ QString path = QPEApplication::qpeDir() + "/plugins/inputmethods";
+ QDir dir( path, "lib*.so" );
+ QStringList list = dir.entryList();
+ QStringList::Iterator it;
+ for ( it = list.begin(); it != list.end(); ++it ) {
+ InputMethodInterface *iface = 0;
+ QLibrary *lib = new QLibrary( path + "/" + *it );
+ if ( lib->queryInterface( IID_InputMethod, (QUnknownInterface**)&iface ) == QS_OK ) {
+ InputMethod input;
+ input.library = lib;
+ input.interface = iface;
+ input.widget = input.interface->inputMethod( 0, inputWidgetStyle );
+ input.interface->onKeyPress( this, SLOT(sendKey(ushort,ushort,ushort,bool,bool)) );
+ inputMethodList.append( input );
+ QString lang = getenv( "LANG" );
+ QTranslator * trans = new QTranslator(qApp);
+ QString type = (*it).left( (*it).find(".") );
+ QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/"+type+".qm";
+ qDebug("tr for inputmethod: %s", tfn.latin1() );
+ if ( trans->load( tfn ))
+ qApp->installTranslator( trans );
+ else
+ delete trans;
+ } else {
+ delete lib;
+ }
+ }
+#else
+ InputMethod input;
+ input.interface = new HandwritingImpl();
+ input.widget = input.interface->inputMethod( 0, inputWidgetStyle );
+ input.interface->onKeyPress( this, SLOT(sendKey(ushort,ushort,ushort,bool,bool)) );
+ inputMethodList.append( input );
+ input.interface = new KeyboardImpl();
+ input.widget = input.interface->inputMethod( 0, inputWidgetStyle );
+ input.interface->onKeyPress( this, SLOT(sendKey(ushort,ushort,ushort,bool,bool)) );
+ inputMethodList.append( input );
+ input.interface = new PickboardImpl();
+ input.widget = input.interface->inputMethod( 0, inputWidgetStyle );
+ input.interface->onKeyPress( this, SLOT(sendKey(ushort,ushort,ushort,bool,bool)) );
+ inputMethodList.append( input );
+#endif
+ if ( !inputMethodList.isEmpty() ) {
+ method = &inputMethodList[0];
+ kbdButton->setPixmap( *method->interface->icon() );
+ }
+ if ( !inputMethodList.isEmpty() )
+ kbdButton->show();
+ else
+ kbdButton->hide();
+ if ( inputMethodList.count() > 1 )
+ kbdChoice->show();
+ else
+ kbdChoice->hide();
+}
+
+void InputMethods::chooseKbd()
+{
+ QPopupMenu pop( this );
+
+ int i = 0;
+ QValueList<InputMethod>::Iterator it;
+ for ( it = inputMethodList.begin(); it != inputMethodList.end(); ++it, i++ ) {
+ pop.insertItem( (*it).interface->name(), i );
+ if ( method == &(*it) )
+ pop.setItemChecked( i, TRUE );
+ }
+
+ QPoint pt = mapToGlobal(kbdChoice->geometry().topRight());
+ QSize s = pop.sizeHint();
+ pt.ry() -= s.height();
+ pt.rx() -= s.width();
+ i = pop.exec( pt );
+ if ( i == -1 )
+ return;
+ InputMethod *im = &inputMethodList[i];
+ chooseMethod(im);
+}
+
+void InputMethods::chooseMethod(InputMethod* im)
+{
+ if ( im != method ) {
+ if ( method && method->widget->isVisible() )
+ method->widget->hide();
+ method = im;
+ kbdButton->setPixmap( *method->interface->icon() );
+ }
+ if ( !kbdButton->isOn() )
+ kbdButton->setOn( TRUE );
+ else
+ showKbd( TRUE );
+}
+
+
+void InputMethods::showKbd( bool on )
+{
+ if ( !method )
+ return;
+
+ if ( on ) {
+ method->interface->resetState();
+ // HACK... Make the texteditor fit with all input methods
+ // Input methods should also never use more than about 40% of the screen
+ int height = QMIN( method->widget->sizeHint().height(), 134 );
+ method->widget->resize( qApp->desktop()->width(), height );
+ method->widget->move( 0, mapToGlobal( QPoint() ).y() - height );
+ method->widget->show();
+ } else {
+ method->widget->hide();
+ }
+
+ emit inputToggled( on );
+}
+
+bool InputMethods::shown() const
+{
+ return method && method->widget->isVisible();
+}
+
+QString InputMethods::currentShown() const
+{
+ return method && method->widget->isVisible()
+ ? method->interface->name() : QString::null;
+}
+
+void InputMethods::sendKey( ushort unicode, ushort scancode, ushort mod, bool press, bool repeat )
+{
+#if defined(Q_WS_QWS)
+ QWSServer::sendKeyEvent( unicode, scancode, mod, press, repeat );
+#endif
+}
diff --git a/core/launcher/inputmethods.h b/core/launcher/inputmethods.h
new file mode 100644
index 0000000..286a818
--- a/dev/null
+++ b/core/launcher/inputmethods.h
@@ -0,0 +1,76 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef __INPUT_METHODS_H__
+#define __INPUT_METHODS_H__
+
+
+#include <qpe/inputmethodinterface.h>
+
+#include <qwidget.h>
+#include <qvaluelist.h>
+
+class QToolButton;
+class QLibrary;
+
+struct InputMethod
+{
+#ifndef QT_NO_COMPONENT
+ QLibrary *library;
+#endif
+ QWidget *widget;
+ InputMethodInterface *interface;
+};
+
+class InputMethods : public QWidget
+{
+ Q_OBJECT
+public:
+ InputMethods( QWidget * );
+ ~InputMethods();
+
+ QRect inputRect() const;
+ bool shown() const;
+ QString currentShown() const; // name of interface
+ void showInputMethod(const QString& id);
+ void showInputMethod();
+ void hideInputMethod();
+ void loadInputMethods();
+
+signals:
+ void inputToggled( bool on );
+
+private slots:
+ void chooseKbd();
+ void showKbd( bool );
+ void resetStates();
+ void sendKey( ushort unicode, ushort scancode, ushort modifiers, bool, bool );
+
+private:
+ void chooseMethod(InputMethod* im);
+ QToolButton *kbdButton;
+ QToolButton *kbdChoice;
+ InputMethod *method;
+ QValueList<InputMethod> inputMethodList;
+};
+
+
+#endif // __INPUT_METHODS_H__
+
diff --git a/core/launcher/irserver.cpp b/core/launcher/irserver.cpp
new file mode 100644
index 0000000..b22e064
--- a/dev/null
+++ b/core/launcher/irserver.cpp
@@ -0,0 +1,50 @@
+#include "irserver.h"
+
+#include <qpe/qlibrary.h>
+#include <qpe/qpeapplication.h>
+
+#include <qtranslator.h>
+#include <stdlib.h>
+
+#include "obexinterface.h"
+
+#include <qdir.h>
+
+IrServer::IrServer( QObject *parent, const char *name )
+ : QObject( parent, name )
+{
+ lib = 0;
+ QString path = QPEApplication::qpeDir() + "/plugins/obex/";
+ QDir dir( path, "lib*.so" );
+ QStringList list = dir.entryList();
+ QStringList::Iterator it;
+ for ( it = list.begin(); it != list.end(); ++it ) {
+ ObexInterface *iface = 0;
+ QLibrary *trylib = new QLibrary( path + *it );
+ qDebug("trying lib %s", (path + (*it)).latin1() );
+ if ( trylib->queryInterface( IID_ObexInterface, (QUnknownInterface**)&iface ) == QS_OK ) {
+ lib = trylib;
+ qDebug("found obex lib" );
+ QString lang = getenv( "LANG" );
+ QTranslator * trans = new QTranslator(qApp);
+ QString type = (*it).left( (*it).find(".") );
+ QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/"+type+".qm";
+ qDebug("tr fpr obex: %s", tfn.latin1() );
+ if ( trans->load( tfn ))
+ qApp->installTranslator( trans );
+ else
+ delete trans;
+
+ break;
+ } else {
+ delete lib;
+ }
+ }
+ if ( !lib )
+ qDebug("could not load IR plugin" );
+}
+
+IrServer::~IrServer()
+{
+ delete lib;
+}
diff --git a/core/launcher/irserver.h b/core/launcher/irserver.h
new file mode 100644
index 0000000..f9f682f
--- a/dev/null
+++ b/core/launcher/irserver.h
@@ -0,0 +1,20 @@
+#ifndef IRSERVER_H
+#define IRSERVER_H
+
+#include <qobject.h>
+
+class QCopChannel;
+class QLibrary;
+
+class IrServer : public QObject
+{
+ Q_OBJECT
+public:
+ IrServer( QObject *parent = 0, const char *name = 0 );
+ ~IrServer();
+
+private:
+ QLibrary *lib;
+};
+
+#endif
diff --git a/core/launcher/launcher.cpp b/core/launcher/launcher.cpp
new file mode 100644
index 0000000..66a2ce5
--- a/dev/null
+++ b/core/launcher/launcher.cpp
@@ -0,0 +1,804 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpe/qcopenvelope_qws.h>
+#include <qpe/resource.h>
+#include <qpe/applnk.h>
+#include <qpe/config.h>
+#include <qpe/global.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/mimetype.h>
+#include <qpe/storage.h>
+#include <qpe/palmtoprecord.h>
+
+#include <qdir.h>
+#include <qwindowsystem_qws.h>
+#include <qtimer.h>
+#include <qcombobox.h>
+#include <qvbox.h>
+#include <qlayout.h>
+#include <qstyle.h>
+#include <qpushbutton.h>
+#include <qtabbar.h>
+#include <qwidgetstack.h>
+#include <qlayout.h>
+#include <qregexp.h>
+#include <qmessagebox.h>
+#include <qframe.h>
+#include <qpainter.h>
+#include <qlabel.h>
+#include <qtextstream.h>
+
+#include "launcherview.h"
+#include "launcher.h"
+#include "syncdialog.h"
+#include "desktop.h"
+#include <qpe/lnkproperties.h>
+#include "mrulist.h"
+#include "qrsync.h"
+#include <stdlib.h>
+#include <unistd.h>
+
+#if defined(_OS_LINUX_) || defined(Q_OS_LINUX)
+#include <stdio.h>
+#include <sys/vfs.h>
+#include <mntent.h>
+#endif
+
+//#define SHOW_ALL
+
+CategoryTabWidget::CategoryTabWidget( QWidget* parent ) :
+ QVBox( parent )
+{
+ categoryBar = 0;
+ stack = 0;
+}
+
+void CategoryTabWidget::prevTab()
+{
+ if ( categoryBar ) {
+ int n = categoryBar->count();
+ int tab = categoryBar->currentTab();
+ if ( tab >= 0 )
+ categoryBar->setCurrentTab( (tab - 1 + n)%n );
+ }
+}
+
+void CategoryTabWidget::nextTab()
+{
+ if ( categoryBar ) {
+ int n = categoryBar->count();
+ int tab = categoryBar->currentTab();
+ categoryBar->setCurrentTab( (tab + 1)%n );
+ }
+}
+
+void CategoryTabWidget::addItem( const QString& linkfile )
+{
+ int i=0;
+ AppLnk *app = new AppLnk(linkfile);
+ if ( !app->isValid() ) {
+ delete app;
+ return;
+ }
+ if ( !app->file().isEmpty() ) {
+ // A document
+ delete app;
+ app = new DocLnk(linkfile);
+ ((LauncherView*)(stack->widget(ids.count()-1)))->addItem(app);
+ return;
+ }
+ for ( QStringList::Iterator it=ids.begin(); it!=ids.end(); ++it) {
+ if ( !(*it).isEmpty() ) {
+ QRegExp tf(*it,FALSE,TRUE);
+ if ( tf.match(app->type()) >= 0 ) {
+ ((LauncherView*)stack->widget(i))->addItem(app);
+ return;
+ }
+ i++;
+ }
+ }
+}
+
+void CategoryTabWidget::initializeCategories(AppLnkSet* rootFolder,
+ AppLnkSet* docFolder, const QList<FileSystem> &fs)
+{
+ delete categoryBar;
+ categoryBar = new CategoryTabBar( this );
+ QPalette pal = categoryBar->palette();
+ pal.setColor( QColorGroup::Light, pal.color(QPalette::Active,QColorGroup::Shadow) );
+ pal.setColor( QColorGroup::Background, pal.active().background().light(110) );
+ categoryBar->setPalette( pal );
+
+ delete stack;
+ stack = new QWidgetStack(this);
+ tabs=0;
+
+ ids.clear();
+
+ QStringList types = rootFolder->types();
+ for ( QStringList::Iterator it=types.begin(); it!=types.end(); ++it) {
+ if ( !(*it).isEmpty() ) {
+ newView(*it,rootFolder->typePixmap(*it),rootFolder->typeName(*it));
+ }
+ }
+ QListIterator<AppLnk> it( rootFolder->children() );
+ AppLnk* l;
+ while ( (l=it.current()) ) {
+ if ( l->type() == "Separator" ) {
+ rootFolder->remove(l);
+ delete l;
+ } else {
+ int i=0;
+ for ( QStringList::Iterator it=types.begin(); it!=types.end(); ++it) {
+ if ( *it == l->type() )
+ ((LauncherView*)stack->widget(i))->addItem(l,FALSE);
+ i++;
+ }
+ }
+ ++it;
+ }
+ rootFolder->detachChildren();
+ for (int i=0; i<tabs; i++)
+ ((LauncherView*)stack->widget(i))->sort();
+
+ // all documents
+ docview = newView( QString::null, Resource::loadPixmap("DocsIcon"), tr("Documents"));
+ docview->populate( docFolder, QString::null );
+ docFolder->detachChildren();
+ docview->setFileSystems(fs);
+ docview->setToolsEnabled(TRUE);
+
+ connect( categoryBar, SIGNAL(selected(int)), stack, SLOT(raiseWidget(int)) );
+
+ ((LauncherView*)stack->widget(0))->setFocus();
+
+ categoryBar->show();
+ stack->show();
+}
+
+void CategoryTabWidget::updateDocs(AppLnkSet* docFolder, const QList<FileSystem> &fs)
+{
+ docview->populate( docFolder, QString::null );
+ docFolder->detachChildren();
+ docview->setFileSystems(fs);
+ docview->updateTools();
+}
+
+LauncherView* CategoryTabWidget::newView( const QString& id, const QPixmap& pm, const QString& label )
+{
+ LauncherView* view = new LauncherView( stack );
+ connect( view, SIGNAL(clicked(const AppLnk*)),
+ this, SIGNAL(clicked(const AppLnk*)));
+ connect( view, SIGNAL(rightPressed(AppLnk*)),
+ this, SIGNAL(rightPressed(AppLnk*)));
+ ids.append(id);
+ categoryBar->addTab( new QTab( pm, label ) );
+ stack->addWidget( view, tabs++ );
+ return view;
+}
+
+void CategoryTabWidget::updateLink(const QString& linkfile)
+{
+ int i=0;
+ LauncherView* view;
+ while ((view = (LauncherView*)stack->widget(i++))) {
+ if ( view->removeLink(linkfile) )
+ break;
+ }
+ addItem(linkfile);
+ docview->updateTools();
+}
+
+void CategoryTabWidget::paletteChange( const QPalette &p )
+{
+ QVBox::paletteChange( p );
+ QPalette pal = palette();
+ pal.setColor( QColorGroup::Light, pal.color(QPalette::Active,QColorGroup::Shadow) );
+ pal.setColor( QColorGroup::Background, pal.active().background().light(110) );
+ categoryBar->setPalette( pal );
+ categoryBar->update();
+}
+
+void CategoryTabWidget::setBusy(bool on)
+{
+ if ( on )
+ ((LauncherView*)stack->visibleWidget())->setBusy(TRUE);
+ else
+ for (int i=0; i<tabs; i++)
+ ((LauncherView*)stack->widget(i))->setBusy(FALSE);
+}
+
+
+CategoryTabBar::CategoryTabBar( QWidget *parent, const char *name )
+ : QTabBar( parent, name )
+{
+ setFocusPolicy( NoFocus );
+ connect( this, SIGNAL( selected(int) ), this, SLOT( layoutTabs() ) );
+}
+
+CategoryTabBar::~CategoryTabBar()
+{
+}
+
+void CategoryTabBar::layoutTabs()
+{
+ if ( !count() )
+ return;
+
+// int percentFalloffTable[] = { 100, 70, 40, 12, 6, 3, 1, 0 };
+ int hiddenTabWidth = -12;
+ int middleTab = currentTab();
+ int hframe, vframe, overlap;
+ style().tabbarMetrics( this, hframe, vframe, overlap );
+ QFontMetrics fm = fontMetrics();
+ int x = 0;
+ QRect r;
+ QTab *t;
+ int available = width()-1;
+ int required = 0;
+ for ( int i = 0; i < count(); i++ ) {
+ t = tab(i);
+ // if (( i < (middleTab - 1) ) || ( i > (middleTab + 1) )) {
+ if ( i != middleTab ) {
+ // required += hiddenTabWidth + hframe - overlap;
+ available -= hiddenTabWidth + hframe - overlap;
+ if ( t->iconSet() != 0 )
+ available -= t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width();
+ } else {
+ required += fm.width( t->text() ) + hframe - overlap;
+ if ( t->iconSet() != 0 )
+ required += t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width();
+ }
+ }
+ for ( int i = 0; i < count(); i++ ) {
+ t = tab(i);
+ // if (( i < (middleTab - 1) ) || ( i > (middleTab + 1) )) {
+ if ( i != middleTab ) {
+ int w = hiddenTabWidth;
+ int ih = 0;
+ if ( t->iconSet() != 0 ) {
+ w += t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width();
+ ih = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height();
+ }
+ int h = QMAX( fm.height(), ih );
+ h = QMAX( h, QApplication::globalStrut().height() );
+
+ h += vframe;
+ w += hframe;
+
+ t->setRect( QRect(x, 0, w, h) );
+ x += t->rect().width() - overlap;
+ r = r.unite( t->rect() );
+ } else {
+ int w = fm.width( t->text() );
+ int ih = 0;
+ if ( t->iconSet() != 0 ) {
+ w += t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width();
+ ih = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height();
+ }
+ int h = QMAX( fm.height(), ih );
+ h = QMAX( h, QApplication::globalStrut().height() );
+
+ h += vframe;
+ w += hframe;
+
+ // t->setRect( QRect(x, 0, w * available/required, h) );
+ t->setRect( QRect(x, 0, available, h) );
+ x += t->rect().width() - overlap;
+ r = r.unite( t->rect() );
+ }
+ }
+
+ QRect rr = tab(count()-1)->rect();
+ rr.setRight(width()-1);
+ tab(count()-1)->setRect( rr );
+
+ for ( t = tabList()->first(); t; t = tabList()->next() ) {
+ QRect tr = t->rect();
+ tr.setHeight( r.height() );
+ t->setRect( tr );
+ }
+
+ update();
+}
+
+
+void CategoryTabBar::paint( QPainter * p, QTab * t, bool selected ) const
+{
+#if QT_VERSION >= 300
+ QStyle::SFlags flags = QStyle::Style_Default;
+ if ( selected )
+ flags |= QStyle::Style_Selected;
+ style().drawControl( QStyle::CE_TabBarTab, p, this, t->rect(),
+ colorGroup(), flags, QStyleOption(t) );
+#else
+ style().drawTab( p, this, t, selected );
+#endif
+
+ QRect r( t->rect() );
+ QFont f( font() );
+ if ( selected )
+ f.setBold( TRUE );
+ p->setFont( f );
+
+ int iw = 0;
+ int ih = 0;
+ if ( t->iconSet() != 0 ) {
+ iw = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 2;
+ ih = t->iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height();
+ }
+ int w = iw + p->fontMetrics().width( t->text() ) + 4;
+ int h = QMAX(p->fontMetrics().height() + 4, ih );
+ paintLabel( p, QRect( r.left() + (r.width()-w)/2 - 3,
+ r.top() + (r.height()-h)/2, w, h ), t,
+#if QT_VERSION >= 300
+ t->identifier() == keyboardFocusTab()
+#else
+ t->identitifer() == keyboardFocusTab()
+#endif
+ );
+}
+
+
+void CategoryTabBar::paintLabel( QPainter* p, const QRect&,
+ QTab* t, bool has_focus ) const
+{
+ QRect r = t->rect();
+ // if ( t->id != currentTab() )
+ //r.moveBy( 1, 1 );
+ //
+ if ( t->iconSet() ) {
+ // the tab has an iconset, draw it in the right mode
+ QIconSet::Mode mode = (t->isEnabled() && isEnabled()) ? QIconSet::Normal : QIconSet::Disabled;
+ if ( mode == QIconSet::Normal && has_focus )
+ mode = QIconSet::Active;
+ QPixmap pixmap = t->iconSet()->pixmap( QIconSet::Small, mode );
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ p->drawPixmap( r.left() + 6, r.center().y() - pixh / 2 + 1, pixmap );
+ r.setLeft( r.left() + pixw + 5 );
+ }
+
+ QRect tr = r;
+
+ if ( r.width() < 20 )
+ return;
+
+ if ( t->isEnabled() && isEnabled() ) {
+#if defined(_WS_WIN32_)
+ if ( colorGroup().brush( QColorGroup::Button ) == colorGroup().brush( QColorGroup::Background ) )
+ p->setPen( colorGroup().buttonText() );
+ else
+ p->setPen( colorGroup().foreground() );
+#else
+ p->setPen( colorGroup().foreground() );
+#endif
+ p->drawText( tr, AlignCenter | AlignVCenter | ShowPrefix, t->text() );
+ } else {
+ p->setPen( palette().disabled().foreground() );
+ p->drawText( tr, AlignCenter | AlignVCenter | ShowPrefix, t->text() );
+ }
+}
+
+//---------------------------------------------------------------------------
+
+Launcher::Launcher( QWidget* parent, const char* name, WFlags fl )
+ : QMainWindow( parent, name, fl )
+{
+ setCaption( tr("Launcher") );
+
+ syncDialog = 0;
+
+ // we have a pretty good idea how big we'll be
+ setGeometry( 0, 0, qApp->desktop()->width(), qApp->desktop()->height() );
+
+ tabs = 0;
+ rootFolder = 0;
+ docsFolder = 0;
+
+ tabs = new CategoryTabWidget( this );
+ tabs->setMaximumWidth( qApp->desktop()->width() );
+ setCentralWidget( tabs );
+
+ connect( tabs, SIGNAL(selected(const QString&)),
+ this, SLOT(viewSelected(const QString&)) );
+ connect( tabs, SIGNAL(clicked(const AppLnk*)),
+ this, SLOT(select(const AppLnk*)));
+ connect( tabs, SIGNAL(rightPressed(AppLnk*)),
+ this, SLOT(properties(AppLnk*)));
+
+#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
+ QCopChannel* sysChannel = new QCopChannel( "QPE/System", this );
+ connect( sysChannel, SIGNAL(received(const QCString &, const QByteArray &)),
+ this, SLOT(systemMessage( const QCString &, const QByteArray &)) );
+#endif
+
+ storage = new StorageInfo( this );
+ connect( storage, SIGNAL( disksChanged() ), SLOT( storageChanged() ) );
+
+ updateTabs();
+
+ preloadApps();
+
+ in_lnk_props = FALSE;
+ got_lnk_change = FALSE;
+}
+
+Launcher::~Launcher()
+{
+}
+
+static bool isVisibleWindow(int wid)
+{
+ const QList<QWSWindow> &list = qwsServer->clientWindows();
+ QWSWindow* w;
+ for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) {
+ if ( w->winId() == wid )
+ return !w->isFullyObscured();
+ }
+ return FALSE;
+}
+
+void Launcher::showMaximized()
+{
+ if ( isVisibleWindow( winId() ) )
+ doMaximize();
+ else
+ QTimer::singleShot( 20, this, SLOT(doMaximize()) );
+}
+
+void Launcher::doMaximize()
+{
+ QMainWindow::showMaximized();
+}
+
+void Launcher::updateMimeTypes()
+{
+ MimeType::clear();
+ updateMimeTypes(rootFolder);
+}
+
+void Launcher::updateMimeTypes(AppLnkSet* folder)
+{
+ for ( QListIterator<AppLnk> it( folder->children() ); it.current(); ++it ) {
+ AppLnk *app = it.current();
+ if ( app->type() == "Folder" )
+ updateMimeTypes((AppLnkSet *)app);
+ else {
+ MimeType::registerApp(*app);
+ }
+ }
+}
+
+void Launcher::loadDocs()
+{
+ delete docsFolder;
+ docsFolder = new DocLnkSet;
+ Global::findDocuments(docsFolder);
+}
+
+void Launcher::updateTabs()
+{
+ MimeType::updateApplications(); // ### reads all applnks twice
+
+ delete rootFolder;
+ rootFolder = new AppLnkSet( MimeType::appsFolderName() );
+
+ loadDocs();
+
+ tabs->initializeCategories(rootFolder, docsFolder, storage->fileSystems());
+}
+
+void Launcher::updateDocs()
+{
+ loadDocs();
+ tabs->updateDocs(docsFolder,storage->fileSystems());
+}
+
+void Launcher::viewSelected(const QString& s)
+{
+ setCaption( s + tr(" - Launcher") );
+}
+
+void Launcher::nextView()
+{
+ tabs->nextTab();
+}
+
+
+void Launcher::select( const AppLnk *appLnk )
+{
+ if ( appLnk->type() == "Folder" ) {
+ // Not supported: flat is simpler for the user
+ } else {
+ if ( appLnk->exec().isNull() ) {
+ QMessageBox::information(this,tr("No application"),
+ tr("<p>No application is defined for this document."
+ "<p>Type is %1.").arg(appLnk->type()));
+ return;
+ }
+ tabs->setBusy(TRUE);
+ emit executing( appLnk );
+ appLnk->execute();
+ }
+}
+
+void Launcher::externalSelected(const AppLnk *appLnk)
+{
+ tabs->setBusy(TRUE);
+ emit executing( appLnk );
+}
+
+void Launcher::properties( AppLnk *appLnk )
+{
+ if ( appLnk->type() == "Folder" ) {
+ // Not supported: flat is simpler for the user
+ } else {
+ in_lnk_props = TRUE;
+ got_lnk_change = FALSE;
+ LnkProperties prop(appLnk);
+ connect(&prop, SIGNAL(select(const AppLnk *)), this, SLOT(externalSelected(const AppLnk *)));
+ prop.showMaximized();
+ prop.exec();
+ in_lnk_props = FALSE;
+ if ( got_lnk_change ) {
+ updateLink(lnk_change);
+ }
+ }
+}
+
+void Launcher::updateLink(const QString& link)
+{
+ if (link.isNull())
+ updateTabs();
+ else if (link.isEmpty())
+ updateDocs();
+ else
+ tabs->updateLink(link);
+}
+
+void Launcher::systemMessage( const QCString &msg, const QByteArray &data)
+{
+ QDataStream stream( data, IO_ReadOnly );
+ if ( msg == "linkChanged(QString)" ) {
+ QString link;
+ stream >> link;
+ if ( in_lnk_props ) {
+ got_lnk_change = TRUE;
+ lnk_change = link;
+ } else {
+ updateLink(link);
+ }
+ } else if ( msg == "busy()" ) {
+ emit busy();
+ } else if ( msg == "notBusy(QString)" ) {
+ QString app;
+ stream >> app;
+ tabs->setBusy(FALSE);
+ emit notBusy(app);
+ } else if ( msg == "mkdir(QString)" ) {
+ QString dir;
+ stream >> dir;
+ if ( !dir.isEmpty() )
+ mkdir( dir );
+ } else if ( msg == "rdiffGenSig(QString,QString)" ) {
+ QString baseFile, sigFile;
+ stream >> baseFile >> sigFile;
+ QRsync::generateSignature( baseFile, sigFile );
+ } else if ( msg == "rdiffGenDiff(QString,QString,QString)" ) {
+ QString baseFile, sigFile, deltaFile;
+ stream >> baseFile >> sigFile >> deltaFile;
+ QRsync::generateDiff( baseFile, sigFile, deltaFile );
+ } else if ( msg == "rdiffApplyPatch(QString,QString)" ) {
+ QString baseFile, deltaFile;
+ stream >> baseFile >> deltaFile;
+ if ( !QFile::exists( baseFile ) ) {
+ QFile f( baseFile );
+ f.open( IO_WriteOnly );
+ f.close();
+ }
+ QRsync::applyDiff( baseFile, deltaFile );
+ QCopEnvelope e( "QPE/Desktop", "patchApplied(QString)" );
+ e << baseFile;
+ } else if ( msg == "rdiffCleanup()" ) {
+ mkdir( "/tmp/rdiff" );
+ QDir dir;
+ dir.setPath( "/tmp/rdiff" );
+ QStringList entries = dir.entryList();
+ for ( QStringList::Iterator it = entries.begin(); it != entries.end(); ++it )
+ dir.remove( *it );
+ } else if ( msg == "sendHandshakeInfo()" ) {
+ QString home = getenv( "HOME" );
+ QCopEnvelope e( "QPE/Desktop", "handshakeInfo(QString,bool)" );
+ e << home;
+ int locked = (int) Desktop::screenLocked();
+ e << locked;
+ } else if ( msg == "sendCardInfo()" ) {
+ QCopEnvelope e( "QPE/Desktop", "cardInfo(QString)" );
+ const QList<FileSystem> &fs = storage->fileSystems();
+ QListIterator<FileSystem> it ( fs );
+ QString s;
+ QString homeDir = getenv("HOME");
+ QString hardDiskHome;
+ for ( ; it.current(); ++it ) {
+ if ( (*it)->isRemovable() )
+ s += (*it)->name() + "=" + (*it)->path() + "/Documents "
+ + QString::number( (*it)->availBlocks() * (*it)->blockSize() )
+ + " " + (*it)->options() + ";";
+ else if ( (*it)->disk() == "/dev/mtdblock1" ||
+ (*it)->disk() == "/dev/mtdblock/1" )
+ s += (*it)->name() + "=" + homeDir + "/Documents "
+ + QString::number( (*it)->availBlocks() * (*it)->blockSize() )
+ + " " + (*it)->options() + ";";
+ else if ( (*it)->name().contains( "Hard Disk") &&
+ homeDir.contains( (*it)->path() ) &&
+ (*it)->path().length() > hardDiskHome.length() )
+ hardDiskHome =
+ (*it)->name() + "=" + homeDir + "/Documents "
+ + QString::number( (*it)->availBlocks() * (*it)->blockSize() )
+ + " " + (*it)->options() + ";";
+ }
+ if ( !hardDiskHome.isEmpty() )
+ s += hardDiskHome;
+
+ e << s;
+ } else if ( msg == "sendSyncDate(QString)" ) {
+ QString app;
+ stream >> app;
+ Config cfg( "qpe" );
+ cfg.setGroup("SyncDate");
+ QCopEnvelope e( "QPE/Desktop", "syncDate(QString,QString)" );
+ e << app << cfg.readEntry( app );
+ //qDebug("QPE/System sendSyncDate for %s: response %s", app.latin1(),
+ //cfg.readEntry( app ).latin1() );
+ } else if ( msg == "setSyncDate(QString,QString)" ) {
+ QString app, date;
+ stream >> app >> date;
+ Config cfg( "qpe" );
+ cfg.setGroup("SyncDate");
+ cfg.writeEntry( app, date );
+ //qDebug("setSyncDate(QString,QString) %s %s", app.latin1(), date.latin1());
+ } else if ( msg == "startSync(QString)" ) {
+ QString what;
+ stream >> what;
+ delete syncDialog; syncDialog = 0;
+ syncDialog = new SyncDialog( this, "syncProgress", FALSE,
+ WStyle_Tool | WStyle_Customize |
+ Qt::WStyle_StaysOnTop );
+ syncDialog->showMaximized();
+ syncDialog->whatLabel->setText( "<b>" + what + "</b>" );
+ connect( syncDialog->buttonCancel, SIGNAL( clicked() ),
+ SLOT( cancelSync() ) );
+ }
+ else if ( msg == "stopSync()") {
+ delete syncDialog; syncDialog = 0;
+ } else if ( msg == "getAllDocLinks()" ) {
+ loadDocs();
+
+ QString contents;
+
+ for ( QListIterator<DocLnk> it( docsFolder->children() ); it.current(); ++it ) {
+ DocLnk *doc = it.current();
+ QString lfn = doc->linkFile();
+ QFileInfo fi( doc->file() );
+ if ( !fi.exists() )
+ continue;
+
+
+
+ QFile f( lfn );
+ if ( f.open( IO_ReadOnly ) ) {
+ QTextStream ts( &f );
+ ts.setEncoding( QTextStream::UnicodeUTF8 );
+ contents += ts.read();
+ f.close();
+ } else {
+ contents += "[Desktop Entry]\n";
+ contents += "Categories = " + Qtopia::Record::idsToString( doc->categories() ) + "\n";
+ contents += "File = "+doc->file()+"\n";
+ contents += "Name = "+doc->name()+"\n";
+ contents += "Type = "+doc->type()+"\n";
+ }
+ contents += QString("Size = %1\n").arg( fi.size() );
+ }
+
+ //qDebug( "sending length %d", contents.length() );
+ QCopEnvelope e( "QPE/Desktop", "docLinks(QString)" );
+ e << contents;
+
+ //qDebug( "================ \n\n%s\n\n===============",
+ //contents.latin1() );
+
+ delete docsFolder;
+ docsFolder = 0;
+ }
+}
+
+void Launcher::cancelSync()
+{
+ QCopEnvelope e( "QPE/Desktop", "cancelSync()" );
+}
+
+void Launcher::storageChanged()
+{
+ if ( in_lnk_props ) {
+ got_lnk_change = TRUE;
+ lnk_change = "";
+ } else {
+ updateDocs();
+ }
+}
+
+
+bool Launcher::mkdir(const QString &localPath)
+{
+ QDir fullDir(localPath);
+ if (fullDir.exists())
+ return true;
+
+ // at this point the directory doesn't exist
+ // go through the directory tree and start creating the direcotories
+ // that don't exist; if we can't create the directories, return false
+
+ QString dirSeps = "/";
+ int dirIndex = localPath.find(dirSeps);
+ QString checkedPath;
+
+ // didn't find any seps; weird, use the cur dir instead
+ if (dirIndex == -1) {
+ //qDebug("No seperators found in path %s", localPath.latin1());
+ checkedPath = QDir::currentDirPath();
+ }
+
+ while (checkedPath != localPath) {
+ // no more seperators found, use the local path
+ if (dirIndex == -1)
+ checkedPath = localPath;
+ else {
+ // the next directory to check
+ checkedPath = localPath.left(dirIndex) + "/";
+ // advance the iterator; the next dir seperator
+ dirIndex = localPath.find(dirSeps, dirIndex+1);
+ }
+
+ QDir checkDir(checkedPath);
+ if (!checkDir.exists()) {
+ //qDebug("mkdir making dir %s", checkedPath.latin1());
+
+ if (!checkDir.mkdir(checkedPath)) {
+ qDebug("Unable to make directory %s", checkedPath.latin1());
+ return FALSE;
+ }
+ }
+
+ }
+ return TRUE;
+}
+
+void Launcher::preloadApps()
+{
+ Config cfg("Launcher");
+ cfg.setGroup("Preload");
+ QStringList apps = cfg.readListEntry("Apps",',');
+ for (QStringList::ConstIterator it=apps.begin(); it!=apps.end(); ++it) {
+ QCopEnvelope e("QPE/Application/"+(*it).local8Bit(), "enablePreload()");
+ }
+}
diff --git a/core/launcher/launcher.h b/core/launcher/launcher.h
new file mode 100644
index 0000000..00ae980
--- a/dev/null
+++ b/core/launcher/launcher.h
@@ -0,0 +1,136 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef LAUNCHER_H
+#define LAUNCHER_H
+
+#include <qmainwindow.h>
+#include <qtabbar.h>
+#include <qstringlist.h>
+#include <qvbox.h>
+#include <qlist.h>
+#include "launcherview.h"
+
+class AppLnk;
+class AppLnkSet;
+class DocLnkSet;
+class QWidgetStack;
+class StorageInfo;
+class SyncDialog;
+
+class CategoryTabBar : public QTabBar
+{
+ Q_OBJECT
+public:
+ CategoryTabBar( QWidget *parent=0, const char *name=0 );
+ ~CategoryTabBar();
+
+protected slots:
+ virtual void layoutTabs();
+
+protected:
+ void paint ( QPainter *p, QTab *t, bool f ) const;
+ void paintLabel( QPainter* p, const QRect& br, QTab* t, bool has_focus ) const;
+};
+
+class CategoryTabWidget : public QVBox {
+ // can't use a QTabWidget, since it won't let us set the frame style.
+ Q_OBJECT
+public:
+ CategoryTabWidget( QWidget* parent );
+ void initializeCategories(AppLnkSet* rootFolder, AppLnkSet* docFolder,
+ const QList<FileSystem> &);
+ void updateDocs(AppLnkSet* docFolder, const QList<FileSystem> &fs);
+ void updateLink(const QString& linkfile);
+ void setBusy(bool on);
+
+signals:
+ void selected(const QString&);
+ void clicked(const AppLnk*);
+ void rightPressed(AppLnk*);
+
+public slots:
+ void nextTab();
+ void prevTab();
+
+protected:
+ void paletteChange( const QPalette &p );
+
+private:
+ CategoryTabBar* categoryBar;
+ QWidgetStack* stack;
+ LauncherView* docview;
+ QStringList ids;
+ int tabs;
+ LauncherView* newView( const QString&, const QPixmap& pm, const QString& label );
+ void addItem( const QString& );
+};
+
+class Launcher : public QMainWindow
+{
+ Q_OBJECT
+ friend class LauncherPrivate;
+public:
+ Launcher( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~Launcher();
+
+ static QString appsFolderName();
+
+ virtual void showMaximized();
+ static bool mkdir(const QString &path);
+
+public slots:
+ void viewSelected(const QString&);
+ void select( const AppLnk * );
+ void externalSelected( const AppLnk *);
+ void properties( AppLnk * );
+ void nextView();
+
+signals:
+ void executing( const AppLnk * );
+ void busy();
+ void notBusy(const QString&);
+
+private slots:
+ void doMaximize();
+ void systemMessage( const QCString &, const QByteArray &);
+ void storageChanged();
+ void cancelSync();
+
+private:
+ void updateApps();
+ void loadDocs();
+ void updateDocs();
+ void updateTabs();
+ void updateMimeTypes();
+ void updateMimeTypes(AppLnkSet*);
+ void preloadApps();
+ AppLnkSet *rootFolder;
+ DocLnkSet *docsFolder;
+ CategoryTabWidget *tabs;
+ StorageInfo *storage;
+ SyncDialog *syncDialog;
+
+ void updateLink(const QString& link);
+ bool in_lnk_props;
+ bool got_lnk_change;
+ QString lnk_change;
+};
+
+#endif // LAUNCHERVIEW_H
diff --git a/core/launcher/launcher.pro b/core/launcher/launcher.pro
new file mode 100644
index 0000000..7d7c9ac
--- a/dev/null
+++ b/core/launcher/launcher.pro
@@ -0,0 +1,110 @@
+TEMPLATE = app
+
+CONFIG = qt warn_on release
+
+DESTDIR = $(QPEDIR)/bin
+
+HEADERS = background.h \
+ desktop.h \
+ info.h \
+ appicons.h \
+ taskbar.h \
+ sidething.h \
+ mrulist.h \
+ stabmon.h \
+ inputmethods.h \
+ systray.h \
+ wait.h \
+ shutdownimpl.h \
+ launcher.h \
+ launcherview.h \
+ ../calibrate/calibrate.h \
+ startmenu.h \
+ transferserver.h \
+ qcopbridge.h \
+ packageslave.h \
+ irserver.h \
+ $(QPEDIR)/rsync/buf.h \
+ $(QPEDIR)/rsync/checksum.h \
+ $(QPEDIR)/rsync/command.h \
+ $(QPEDIR)/rsync/emit.h \
+ $(QPEDIR)/rsync/job.h \
+ $(QPEDIR)/rsync/netint.h \
+ $(QPEDIR)/rsync/protocol.h \
+ $(QPEDIR)/rsync/prototab.h \
+ $(QPEDIR)/rsync/rsync.h \
+ $(QPEDIR)/rsync/search.h \
+ $(QPEDIR)/rsync/stream.h \
+ $(QPEDIR)/rsync/sumset.h \
+ $(QPEDIR)/rsync/trace.h \
+ $(QPEDIR)/rsync/types.h \
+ $(QPEDIR)/rsync/util.h \
+ $(QPEDIR)/rsync/whole.h \
+ $(QPEDIR)/rsync/config_rsync.h \
+ $(QPEDIR)/rsync/qrsync.h
+# quicklauncher.h \
+
+SOURCES = background.cpp \
+ desktop.cpp \
+ info.cpp \
+ appicons.cpp \
+ taskbar.cpp \
+ sidething.cpp \
+ mrulist.cpp \
+ stabmon.cpp \
+ inputmethods.cpp \
+ systray.cpp \
+ wait.cpp \
+ shutdownimpl.cpp \
+ launcher.cpp \
+ launcherview.cpp \
+ $(QPEDIR)/calibrate/calibrate.cpp \
+ transferserver.cpp \
+ packageslave.cpp \
+ irserver.cpp \
+ qcopbridge.cpp \
+ startmenu.cpp \
+ main.cpp \
+ $(QPEDIR)/rsync/base64.c \
+ $(QPEDIR)/rsync/buf.c \
+ $(QPEDIR)/rsync/checksum.c \
+ $(QPEDIR)/rsync/command.c \
+ $(QPEDIR)/rsync/delta.c \
+ $(QPEDIR)/rsync/emit.c \
+ $(QPEDIR)/rsync/hex.c \
+ $(QPEDIR)/rsync/job.c \
+ $(QPEDIR)/rsync/mdfour.c \
+ $(QPEDIR)/rsync/mksum.c \
+ $(QPEDIR)/rsync/msg.c \
+ $(QPEDIR)/rsync/netint.c \
+ $(QPEDIR)/rsync/patch.c \
+ $(QPEDIR)/rsync/prototab.c \
+ $(QPEDIR)/rsync/readsums.c \
+ $(QPEDIR)/rsync/scoop.c \
+ $(QPEDIR)/rsync/search.c \
+ $(QPEDIR)/rsync/stats.c \
+ $(QPEDIR)/rsync/stream.c \
+ $(QPEDIR)/rsync/sumset.c \
+ $(QPEDIR)/rsync/trace.c \
+ $(QPEDIR)/rsync/tube.c \
+ $(QPEDIR)/rsync/util.c \
+ $(QPEDIR)/rsync/version.c \
+ $(QPEDIR)/rsync/whole.c \
+ $(QPEDIR)/rsync/qrsync.cpp
+
+INTERFACES = shutdown.ui syncdialog.ui
+
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include .
+
+INCLUDEPATH += $(QPEDIR)/calibrate
+DEPENDPATH += $(QPEDIR)/calibrate
+
+INCLUDEPATH += $(QPEDIR)/rsync
+DEPENDPATH += $(QPEDIR)/rsync
+
+TARGET = qpe
+
+LIBS += -lqpe -lcrypt
+
+TRANSLATIONS = ../i18n/de/qpe.ts
diff --git a/core/launcher/launcherview.cpp b/core/launcher/launcherview.cpp
new file mode 100644
index 0000000..68e3245
--- a/dev/null
+++ b/core/launcher/launcherview.cpp
@@ -0,0 +1,596 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "launcherview.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/applnk.h>
+#include <qpe/qpedebug.h>
+#include <qpe/categories.h>
+#include <qpe/categoryselect.h>
+#include <qpe/menubutton.h>
+#include <qpe/resource.h>
+#include <qpe/qpetoolbar.h>
+
+#include <qtimer.h>
+#include <qdict.h>
+#include <qfile.h>
+#include <qfileinfo.h>
+#include <qhbox.h>
+#include <qiconview.h>
+#include <qpainter.h>
+#include <qregexp.h>
+#include <qtoolbutton.h>
+
+class LauncherIconView : public QIconView {
+public:
+ LauncherIconView( QWidget* parent, const char* name=0 ) :
+ QIconView(parent,name),
+ tf(""),
+ cf(0),
+ bsy(0)
+ {
+ sortmeth = Name;
+ hidden.setAutoDelete(TRUE);
+ ike = FALSE;
+ }
+
+ ~LauncherIconView()
+ {
+#if 0 // debuggery
+ QListIterator<AppLnk> it(hidden);
+ AppLnk* l;
+ while ((l=it.current())) {
+ ++it;
+ //qDebug("%p: hidden (should remove)",l);
+ }
+#endif
+ }
+
+ QIconViewItem* busyItem() const { return bsy; }
+
+ void updateCategoriesAndMimeTypes();
+
+ void doAutoScroll()
+ {
+ // We don't want rubberbanding (yet)
+ }
+
+ void setBusy(bool on)
+ {
+ QIconViewItem *c = on ? currentItem() : 0;
+ if ( bsy != c ) {
+ QIconViewItem* o = bsy;
+ bsy = c;
+ if ( o ) o->repaint();
+ if ( c ) c->repaint();
+ }
+ }
+
+ bool inKeyEvent() const { return ike; }
+ void keyPressEvent(QKeyEvent* e)
+ {
+ ike = TRUE;
+ if ( e->key() == Key_F33 ) {
+ // "OK" button
+ returnPressed(currentItem());
+ }
+ QIconView::keyPressEvent(e);
+ ike = FALSE;
+ }
+
+ void addItem(AppLnk* app, bool resort=TRUE);
+ bool removeLink(const QString& linkfile);
+
+ QStringList mimeTypes() const;
+ QStringList categories() const;
+
+ void clear()
+ {
+ mimes.clear();
+ cats.clear();
+ QIconView::clear();
+ hidden.clear();
+ }
+
+ void addCatsAndMimes(AppLnk* app)
+ {
+ // QStringList c = app->categories();
+ // for (QStringList::ConstIterator cit=c.begin(); cit!=c.end(); ++cit) {
+ // cats.replace(*cit,(void*)1);
+ // }
+ QString maj=app->type();
+ int sl=maj.find('/');
+ if (sl>=0) {
+ QString k = maj.left(sl);
+ mimes.replace(k,(void*)1);
+ }
+ }
+
+ void drawBackground( QPainter *p, const QRect &r )
+ {
+ // int backgroundMode = QPixmap::defaultDepth() >= 12 ? 1 : 0;
+ int backgroundMode = 2;
+
+ if ( backgroundMode == 1 ) {
+
+ // Double buffer the background
+ static QPixmap *bg = NULL;
+ static QColor bgColor;
+
+ if ( (bg == NULL) || (bgColor != colorGroup().button()) ) {
+ // Create a new background double buffer
+ if (bg == NULL)
+ bg = new QPixmap( width(), height() );
+ bgColor = colorGroup().button();
+ QPainter painter( bg );
+
+ painter.fillRect( QRect( 0, 0, width(), height() ), QBrush( white ) );
+
+ // Overlay the Qtopia logo in the center
+ QImage logo = Resource::loadImage( "qpe-logo" );
+ if ( !logo.isNull() )
+ painter.drawImage( (width() - logo.width()) / 2,
+ (height() - logo.height()) / 2, logo );
+ }
+
+ // Draw the double buffer to the widget (it is tiled for when the icon view is large)
+ p->drawTiledPixmap( r, *bg, QPoint( (r.x() + contentsX()) % bg->width(),
+ (r.y() + contentsY()) % bg->height() ) );
+ } else if ( backgroundMode == 2 ) {
+ static QPixmap *bg = 0;
+ static QColor bgColor;
+ if ( !bg || (bgColor != colorGroup().background()) ) {
+ bgColor = colorGroup().background();
+ bg = new QPixmap( width(), 9 );
+ QPainter painter( bg );
+ for ( int i = 0; i < 3; i++ ) {
+ painter.setPen( white );
+ painter.drawLine( 0, i*3, width()-1, i*3 );
+ painter.drawLine( 0, i*3+1, width()-1, i*3+1 );
+ painter.setPen( colorGroup().background().light(105) );
+ painter.drawLine( 0, i*3+2, width()-1, i*3+2 );
+ }
+ }
+ p->drawTiledPixmap( r, *bg, QPoint( (r.x() + contentsX()) % bg->width(),
+ (r.y() + contentsY()) % bg->height() ) );
+ } else {
+ p->fillRect( r, QBrush( white ) );
+ }
+ }
+
+ void hideOrShowItems(bool resort);
+
+ void setTypeFilter(const QString& typefilter, bool resort)
+ {
+ tf = QRegExp(typefilter,FALSE,TRUE);
+ hideOrShowItems(resort);
+ }
+
+ void setCategoryFilter( int catfilter, bool resort )
+ {
+ Categories cat;
+ cat.load( categoryFileName() );
+ QString str;
+ if ( catfilter == -2 )
+ cf = 0;
+ else
+ cf = catfilter;
+ hideOrShowItems(resort);
+ }
+
+ enum SortMethod { Name, Date, Type };
+
+ void setSortMethod( SortMethod m )
+ {
+ if ( sortmeth != m ) {
+ sortmeth = m;
+ sort();
+ }
+ }
+
+ int compare(const AppLnk* a, const AppLnk* b)
+ {
+ switch (sortmeth) {
+ case Name:
+ return a->name().compare(b->name());
+ case Date: {
+ QFileInfo fa(a->linkFile());
+ if ( !fa.exists() ) fa.setFile(a->file());
+ QFileInfo fb(b->linkFile());
+ if ( !fb.exists() ) fb.setFile(b->file());
+ return fa.lastModified().secsTo(fb.lastModified());
+ }
+ case Type:
+ return a->type().compare(b->type());
+ }
+ return 0;
+ }
+
+protected:
+
+ void styleChange( QStyle &old )
+ {
+ QIconView::styleChange( old );
+ //### duplicated code from LauncherView constructor
+ int dw = QApplication::desktop()->width();
+ setGridX( (dw-13-style().scrollBarExtent().width())/3 ); // tweaked for 8pt+dw=176 and 10pt+dw=240
+ }
+
+private:
+ QList<AppLnk> hidden;
+ QDict<void> mimes;
+ QDict<void> cats;
+ SortMethod sortmeth;
+ QRegExp tf;
+ int cf;
+ QIconViewItem* bsy;
+ bool ike;
+
+};
+
+
+bool LauncherView::bsy=FALSE;
+
+void LauncherView::setBusy(bool on)
+{
+ icons->setBusy(on);
+}
+
+class LauncherItem : public QIconViewItem
+{
+public:
+ LauncherItem( QIconView *parent, AppLnk* applnk );
+ ~LauncherItem()
+ {
+ LauncherIconView* liv = (LauncherIconView*)iconView();
+ if ( liv->busyItem() == this )
+ liv->setBusy(FALSE);
+ delete app;
+ }
+
+ AppLnk* appLnk() const { return app; }
+ AppLnk* takeAppLnk() { AppLnk* r=app; app=0; return r; }
+
+ virtual int compare ( QIconViewItem * i ) const;
+
+ void paintItem( QPainter *p, const QColorGroup &cg )
+ {
+ LauncherIconView* liv = (LauncherIconView*)iconView();
+ QBrush oldBrush( liv->itemTextBackground() );
+ QColorGroup mycg( cg );
+ if ( liv->currentItem() == this ) {
+ liv->setItemTextBackground( cg.brush( QColorGroup::Highlight ) );
+ mycg.setColor( QColorGroup::Text, cg.color( QColorGroup::HighlightedText ) );
+ }
+ QIconViewItem::paintItem(p,mycg);
+ if ( liv->currentItem() == this )
+ liv->setItemTextBackground( oldBrush );
+ if ( liv->busyItem() == this ) {
+ static QPixmap* busypm=0;
+ if ( !busypm )
+ busypm = new QPixmap(Resource::loadPixmap("launching"));
+ p->drawPixmap(x()+(width()-busypm->width())/2, y(),*busypm);
+ }
+ }
+
+protected:
+ AppLnk* app;
+};
+
+
+LauncherItem::LauncherItem( QIconView *parent, AppLnk *applnk )
+ : QIconViewItem( parent, applnk->name(), applnk->bigPixmap() ),
+ app(applnk) // Takes ownership
+{
+}
+
+int LauncherItem::compare ( QIconViewItem * i ) const
+{
+ LauncherIconView* view = (LauncherIconView*)iconView();
+ return view->compare(app,((LauncherItem *)i)->appLnk());
+}
+
+QStringList LauncherIconView::mimeTypes() const
+{
+ QStringList r;
+ QDictIterator<void> it(mimes);
+ while (it.current()) {
+ r.append(it.currentKey());
+ ++it;
+ }
+ r.sort();
+ return r;
+}
+
+void LauncherIconView::addItem(AppLnk* app, bool resort)
+{
+ addCatsAndMimes(app);
+
+ if ( (tf.isEmpty() || tf.match(app->type()) >= 0)
+ && (cf == 0 || app->categories().contains(cf)
+ || cf == -1 && app->categories().count() == 0 ) )
+ (void) new LauncherItem( this, app );
+ else
+ hidden.append(app);
+ if ( resort )
+ sort();
+}
+
+void LauncherIconView::updateCategoriesAndMimeTypes()
+{
+ mimes.clear();
+ cats.clear();
+ LauncherItem* item = (LauncherItem*)firstItem();
+ while (item) {
+ addCatsAndMimes(item->appLnk());
+ item = (LauncherItem*)item->nextItem();
+ }
+ QListIterator<AppLnk> it(hidden);
+ AppLnk* l;
+ while ((l=it.current())) {
+ addCatsAndMimes(l);
+ ++it;
+ }
+}
+
+void LauncherIconView::hideOrShowItems(bool resort)
+{
+ hidden.setAutoDelete(FALSE);
+ QList<AppLnk> links=hidden;
+ hidden.clear();
+ hidden.setAutoDelete(TRUE);
+ LauncherItem* item = (LauncherItem*)firstItem();
+ while (item) {
+ links.append(item->takeAppLnk());
+ item = (LauncherItem*)item->nextItem();
+ }
+ clear();
+ QListIterator<AppLnk> it(links);
+ AppLnk* l;
+ while ((l=it.current())) {
+ addItem(l,FALSE);
+ ++it;
+ }
+ if ( resort )
+ sort();
+}
+
+bool LauncherIconView::removeLink(const QString& linkfile)
+{
+ LauncherItem* item = (LauncherItem*)firstItem();
+ while (item) {
+ if ( item->appLnk()->linkFile() == linkfile ) {
+ delete item;
+ return TRUE;
+ }
+ item = (LauncherItem*)item->nextItem();
+ }
+ QListIterator<AppLnk> it(hidden);
+ AppLnk* l;
+ while ((l=it.current())) {
+ ++it;
+ if ( l->linkFile() == linkfile ) {
+ hidden.removeRef(l);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+LauncherView::LauncherView( QWidget* parent, const char* name, WFlags fl )
+ : QVBox( parent, name, fl )
+{
+ icons = new LauncherIconView( this );
+ setFocusProxy(icons);
+ QPEApplication::setStylusOperation( icons->viewport(), QPEApplication::RightOnHold );
+
+ int dw = QApplication::desktop()->width();
+ icons->setItemsMovable( FALSE );
+ icons->setAutoArrange( TRUE );
+ icons->setSorting( TRUE );
+ icons->setGridX( (dw-13-style().scrollBarExtent().width())/3 ); // tweaked for 8pt+dw=176 and 10pt+dw=240
+ icons->setGridY( fontMetrics().height()*2+24 );
+ icons->setFrameStyle( QFrame::NoFrame );
+ icons->setSpacing( 4 );
+ icons->setMargin( 0 );
+ icons->setSelectionMode( QIconView::Multi );
+ icons->setBackgroundMode( PaletteBase );
+
+ connect( icons, SIGNAL(mouseButtonClicked(int, QIconViewItem *, const QPoint&)),
+ SLOT(itemClicked(int, QIconViewItem *)) );
+ connect( icons, SIGNAL(selectionChanged()),
+ SLOT(selectionChanged()) );
+ connect( icons, SIGNAL(returnPressed(QIconViewItem *)),
+ SLOT(returnPressed(QIconViewItem *)) );
+ connect( icons, SIGNAL(mouseButtonPressed(int, QIconViewItem *, const QPoint&)),
+ SLOT(itemPressed(int, QIconViewItem *)) );
+
+ tools = 0;
+}
+
+LauncherView::~LauncherView()
+{
+}
+
+void LauncherView::setToolsEnabled(bool y)
+{
+ if ( !y != !tools ) {
+ if ( y ) {
+ tools = new QHBox(this);
+
+ // Type filter
+ typemb = new MenuButton(tools);
+ typemb->setLabel(tr("Type: %1"));
+
+ // Category filter
+ catmb = new CategorySelect(tools);
+
+ updateTools();
+ tools->show();
+ } else {
+ delete tools;
+ tools = 0;
+ }
+ }
+}
+
+void LauncherView::updateTools()
+{
+ disconnect( typemb, SIGNAL(selected(const QString&)),
+ this, SLOT(showType(const QString&)) );
+ disconnect( catmb, SIGNAL(signalSelected(int)),
+ this, SLOT(showCategory(int)) );
+
+ icons->updateCategoriesAndMimeTypes();
+
+ QString prev;
+
+ // Type filter
+ QStringList types;
+ types << tr("All");
+ types << "--";
+ types += icons->mimeTypes();
+ prev = typemb->currentText();
+ typemb->clear();
+ typemb->insertItems(types);
+ typemb->select(prev);
+
+ Categories cats( 0 );
+ cats.load( categoryFileName() );
+ QArray<int> vl( 0 );
+ catmb->setCategories( vl, "Document View", tr("Document View") );
+ catmb->setRemoveCategoryEdit( TRUE );
+ catmb->setAllCategories( TRUE );
+
+ connect(typemb, SIGNAL(selected(const QString&)), this, SLOT(showType(const QString&)));
+ connect(catmb, SIGNAL(signalSelected(int)), this, SLOT(showCategory(int)));
+}
+
+void LauncherView::sortBy(int s)
+{
+ icons->setSortMethod((LauncherIconView::SortMethod)s);
+}
+
+void LauncherView::showType(const QString& t)
+{
+ if ( t == tr("All") ) {
+ icons->setTypeFilter("",TRUE);
+ } else {
+ icons->setTypeFilter(t+"/*",TRUE);
+ }
+}
+
+void LauncherView::showCategory( int c )
+{
+ icons->setCategoryFilter( c, TRUE );
+}
+
+void LauncherView::resizeEvent(QResizeEvent *e)
+{
+ QVBox::resizeEvent( e );
+ if ( e->size().width() != e->oldSize().width() )
+ sort();
+}
+
+void LauncherView::populate( AppLnkSet *folder, const QString& typefilter )
+{
+ icons->clear();
+ internalPopulate( folder, typefilter );
+}
+
+void LauncherView::selectionChanged()
+{
+ QIconViewItem* item = icons->currentItem();
+ if ( item && item->isSelected() ) {
+ AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
+ if ( icons->inKeyEvent() ) // not for mouse press
+ emit clicked( appLnk );
+ item->setSelected(FALSE);
+ }
+}
+
+void LauncherView::returnPressed( QIconViewItem *item )
+{
+ if ( item ) {
+ AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
+ emit clicked( appLnk );
+ }
+}
+
+void LauncherView::itemClicked( int btn, QIconViewItem *item )
+{
+ if ( item ) {
+ AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
+ if ( btn == LeftButton ) {
+ // Make sure it's the item we execute that gets highlighted
+ icons->setCurrentItem( item );
+ emit clicked( appLnk );
+ }
+ item->setSelected(FALSE);
+ }
+}
+
+void LauncherView::itemPressed( int btn, QIconViewItem *item )
+{
+ if ( item ) {
+ AppLnk *appLnk = ((LauncherItem *)item)->appLnk();
+ if ( btn == RightButton )
+ emit rightPressed( appLnk );
+/*
+ else if ( btn == LeftButton )
+ emit clicked( appLnk );
+*/
+ item->setSelected(FALSE);
+ }
+}
+
+void LauncherView::internalPopulate( AppLnkSet *folder, const QString& typefilter )
+{
+ QListIterator<AppLnk> it( folder->children() );
+ icons->setTypeFilter(typefilter,FALSE);
+
+ while ( it.current() ) {
+ icons->addItem(*it,FALSE);
+ ++it;
+ }
+
+ icons->sort();
+}
+
+bool LauncherView::removeLink(const QString& linkfile)
+{
+ return icons->removeLink(linkfile);
+}
+
+void LauncherView::sort()
+{
+ icons->sort();
+}
+
+void LauncherView::addItem(AppLnk* app, bool resort)
+{
+ icons->addItem(app,resort);
+}
+
+void LauncherView::setFileSystems(const QList<FileSystem> &)
+{
+ // ### does nothing now...
+}
diff --git a/core/launcher/launcherview.h b/core/launcher/launcherview.h
new file mode 100644
index 0000000..3aaef7e
--- a/dev/null
+++ b/core/launcher/launcherview.h
@@ -0,0 +1,81 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef LAUNCHERVIEW_H
+#define LAUNCHERVIEW_H
+
+#include <qpe/storage.h>
+
+#include <qvbox.h>
+
+class AppLnk;
+class AppLnkSet;
+class CategorySelect;
+class LauncherIconView;
+class QIconView;
+class QIconViewItem;
+class MenuButton;
+
+class LauncherView : public QVBox
+{
+ Q_OBJECT
+
+public:
+ LauncherView( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~LauncherView();
+
+ bool removeLink(const QString& linkfile);
+ void addItem(AppLnk* app, bool resort=TRUE);
+ void sort();
+
+ void setFileSystems(const QList<FileSystem> &);
+ void setToolsEnabled(bool);
+ void updateTools();
+
+ void setBusy(bool);
+
+public slots:
+ void populate( AppLnkSet *folder, const QString& categoryfilter );
+
+signals:
+ void clicked( const AppLnk * );
+ void rightPressed( AppLnk * );
+
+protected slots:
+ void selectionChanged();
+ void returnPressed( QIconViewItem *item );
+ void itemClicked( int, QIconViewItem * );
+ void itemPressed( int, QIconViewItem * );
+ void sortBy(int);
+ void showType(const QString&);
+ void showCategory( int );
+ void resizeEvent(QResizeEvent *);
+
+protected:
+ void internalPopulate( AppLnkSet *, const QString& categoryfilter );
+
+private:
+ static bool bsy;
+ QWidget* tools;
+ LauncherIconView* icons;
+ MenuButton *typemb;
+ CategorySelect *catmb;
+};
+
+#endif // LAUNCHERVIEW_H
diff --git a/core/launcher/main.cpp b/core/launcher/main.cpp
new file mode 100644
index 0000000..024f9cc
--- a/dev/null
+++ b/core/launcher/main.cpp
@@ -0,0 +1,276 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "desktop.h"
+#include "taskbar.h"
+#include "stabmon.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/network.h>
+#include <qpe/config.h>
+#ifdef QT_QWS_CUSTOM
+#include <qpe/custom.h>
+#endif
+
+#include <qfile.h>
+#include <qwindowsystem_qws.h>
+#include <qpe/qcopenvelope_qws.h>
+#include <qpe/alarmserver.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+
+#if defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
+#include "../calibrate/calibrate.h"
+#endif
+
+#ifdef QT_QWS_LOGIN
+#include "../login/qdmdialogimpl.h"
+#endif
+
+#ifdef QT_QWS_CASSIOPEIA
+static void ignoreMessage( QtMsgType, const char * )
+{
+}
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <qdatetime.h>
+
+void initCassiopeia()
+{
+ // MIPSEL-specific init - make sure /proc exists for shm
+/*
+ if ( mount("/dev/ram0", "/", "ext2", MS_REMOUNT | MS_MGC_VAL, 0 ) ) {
+ perror("Remounting - / read/write");
+ }
+*/
+ if ( mount("none", "/tmp", "ramfs", 0, 0 ) ) {
+ perror("mounting ramfs /tmp");
+ } else {
+ fprintf( stderr, "mounted /tmp\n" );
+ }
+ if ( mount("none", "/home", "ramfs", 0, 0 ) ) {
+ perror("mounting ramfs /home");
+ } else {
+ fprintf( stderr, "mounted /home\n" );
+ }
+ if ( mount("none","/proc","proc",0,0) ) {
+ perror("Mounting - /proc");
+ } else {
+ fprintf( stderr, "mounted /proc\n" );
+ }
+ if ( mount("none","/mnt","shm",0,0) ) {
+ perror("Mounting - shm");
+ }
+ setenv( "QTDIR", "/", 1 );
+ setenv( "QPEDIR", "/", 1 );
+ setenv( "HOME", "/home", 1 );
+ mkdir( "/home/Documents", 0755 );
+
+ // set a reasonable starting date
+ QDateTime dt( QDate( 2001, 3, 15 ) );
+ QDateTime now = QDateTime::currentDateTime();
+ int change = now.secsTo( dt );
+
+ time_t t = ::time(0);
+ t += change;
+ stime(&t);
+
+ qInstallMsgHandler(ignoreMessage);
+}
+#endif
+
+#ifdef QPE_OWNAPM
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <linux/ioctl.h>
+#include <qpe/global.h>
+
+static void disableAPM()
+{
+
+ int fd, cur_val, ret;
+ char *device = "/dev/apm_bios";
+
+ fd = open (device, O_WRONLY);
+
+ if (fd == -1) {
+ perror(device);
+ return;
+ }
+
+ cur_val = ioctl(fd, APM_IOCGEVTSRC, 0);
+ if (cur_val == -1) {
+ perror("ioctl");
+ exit(errno);
+ }
+
+ ret = ioctl(fd, APM_IOCSEVTSRC, cur_val & ~APM_EVT_POWER_BUTTON);
+ if (ret == -1) {
+ perror("ioctl");
+ return;
+ }
+ close(fd);
+}
+
+static void initAPM()
+{
+ // So that we have to do it ourself, but better.
+ disableAPM();
+}
+#endif
+
+#ifdef QT_DEMO_SINGLE_FLOPPY
+#include <sys/mount.h>
+
+void initFloppy()
+{
+ mount("none","/proc","proc",0,0);
+ setenv( "QTDIR", "/", 0 );
+ setenv( "HOME", "/root", 0 );
+ setenv( "QWS_SIZE", "240x320", 0 );
+}
+#endif
+
+
+void initEnvironment()
+{
+ Config config("locale");
+ config.setGroup( "Location" );
+ QString tz = config.readEntry( "Timezone", getenv("TZ") );
+
+ // if not timezone set, pick New York
+ if (tz.isNull())
+ tz = "America/New_York";
+
+ setenv( "TZ", tz, 1 );
+ config.writeEntry( "Timezone", tz);
+
+ config.setGroup( "Language" );
+ QString lang = config.readEntry( "Language", getenv("LANG") );
+ if ( !lang.isNull() )
+ setenv( "LANG", lang, 1 );
+}
+
+static void initBacklight()
+{
+ QCopEnvelope e("QPE/System", "setBacklight(int)" );
+ e << -3; // Forced on
+}
+
+
+
+int initApplication( int argc, char ** argv )
+{
+#ifdef QT_QWS_CASSIOPEIA
+ initCassiopeia();
+#endif
+
+#ifdef QPE_OWNAPM
+ initAPM();
+#endif
+
+#ifdef QT_DEMO_SINGLE_FLOPPY
+ initFloppy();
+#endif
+
+ initEnvironment();
+
+#if !defined(QT_QWS_CASSIOPEIA) && !defined(QT_QWS_IPAQ) && !defined(QT_QWS_EBX)
+ setenv( "QWS_SIZE", "240x320", 0 );
+#endif
+
+ //Don't flicker at startup:
+ QWSServer::setDesktopBackground( QImage() );
+ DesktopApplication a( argc, argv, QApplication::GuiServer );
+
+ initBacklight();
+
+ AlarmServer::initialize();
+
+#if defined(QT_QWS_LOGIN)
+ for( int i=0; i<a.argc(); i++ )
+ if( strcmp( a.argv()[i], "-login" ) == 0 ) {
+ QDMDialogImpl::login( );
+ return 0;
+ }
+#endif
+
+ Desktop *d = new Desktop();
+
+ QObject::connect( &a, SIGNAL(datebook()), d, SLOT(raiseDatebook()) );
+ QObject::connect( &a, SIGNAL(contacts()), d, SLOT(raiseContacts()) );
+ QObject::connect( &a, SIGNAL(launch()), d, SLOT(raiseLauncher()) );
+ QObject::connect( &a, SIGNAL(email()), d, SLOT(raiseEmail()) );
+ QObject::connect( &a, SIGNAL(power()), d, SLOT(togglePower()) );
+ QObject::connect( &a, SIGNAL(backlight()), d, SLOT(toggleLight()) );
+ QObject::connect( &a, SIGNAL(symbol()), d, SLOT(toggleSymbolInput()) );
+ QObject::connect( &a, SIGNAL(numLockStateToggle()), d, SLOT(toggleNumLockState()) );
+ QObject::connect( &a, SIGNAL(capsLockStateToggle()), d, SLOT(toggleCapsLockState()) );
+ QObject::connect( &a, SIGNAL(prepareForRestart()), d, SLOT(terminateServers()) );
+
+ (void)new SysFileMonitor(d);
+ Network::createServer(d);
+
+#if defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_IPAQ) || defined(QT_QWS_EBX)
+ if ( !QFile::exists( "/etc/pointercal" ) ) {
+ // Make sure calibration widget starts on top.
+ Calibrate *cal = new Calibrate;
+ cal->exec();
+ delete cal;
+ }
+#endif
+
+ d->show();
+
+ int rv = a.exec();
+
+ delete d;
+
+ return rv;
+}
+
+int main( int argc, char ** argv )
+{
+#ifndef SINGLE_APP
+ signal( SIGCHLD, SIG_IGN );
+#endif
+
+ int retVal = initApplication( argc, argv );
+
+#ifndef SINGLE_APP
+ // Kill them. Kill them all.
+ setpgid( getpid(), getppid() );
+ killpg( getpid(), SIGTERM );
+ sleep( 1 );
+ killpg( getpid(), SIGKILL );
+#endif
+
+ return retVal;
+}
+
diff --git a/core/launcher/mrulist.cpp b/core/launcher/mrulist.cpp
new file mode 100644
index 0000000..4daf7d2
--- a/dev/null
+++ b/core/launcher/mrulist.cpp
@@ -0,0 +1,199 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "mrulist.h"
+
+#include <qpe/global.h>
+#include <qpe/applnk.h>
+#include <qpe/resource.h>
+
+#include <qframe.h>
+#include <qpushbutton.h>
+#include <qtoolbutton.h>
+#include <qpopupmenu.h>
+#include <qpainter.h>
+#include <qwindowsystem_qws.h>
+
+
+QList<MRUList> *MRUList::MRUListWidgets = NULL;
+QList<AppLnk> *MRUList::task = NULL;
+
+
+MRUList::MRUList( QWidget *parent )
+ : QFrame( parent ), selected(-1), oldsel(-1)
+{
+ setBackgroundMode( PaletteButton );
+ if (!MRUListWidgets)
+ MRUListWidgets = new QList<MRUList>;
+ if (!task)
+ task = new QList<AppLnk>;
+ MRUListWidgets->append( this );
+}
+
+
+MRUList::~MRUList()
+{
+ if (MRUListWidgets)
+ MRUListWidgets->remove( this );
+ if (task)
+ task->setAutoDelete( TRUE );
+}
+
+
+QSize MRUList::sizeHint() const
+{
+ return QSize( frameWidth(), 16 );
+}
+
+
+void MRUList::addTask( const AppLnk *appLnk )
+{
+ if ( !appLnk )
+ return;
+ unsigned int i = 0;
+
+ if ( !task )
+ return;
+
+ for ( ; i < task->count(); i++ ) {
+ AppLnk *t = task->at(i);
+ if ( t->exec() == appLnk->exec() ) {
+ if (i != 0) {
+ task->remove();
+ task->prepend( t );
+ }
+ for (unsigned i = 0; i < MRUListWidgets->count(); i++ )
+ MRUListWidgets->at(i)->update();
+ return;
+ }
+ }
+
+ AppLnk *t = new AppLnk( *appLnk );
+ // DocLnks have an overloaded virtual function exec()
+ t->setExec( appLnk->exec() );
+ task->prepend( t );
+
+ if ( task->count() > 6 ) {
+ t = task->last();
+ task->remove();
+ Global::terminate(t);
+ delete t;
+ }
+
+ for (unsigned i = 0; i < MRUListWidgets->count(); i++ )
+ MRUListWidgets->at(i)->update();
+}
+
+bool MRUList::quitOldApps()
+{
+ QStringList appsstarted;
+ QStringList appsrunning;
+ for ( int i=task->count()-1; i>=0; --i ) {
+ AppLnk *t = task->at(i);
+ appsstarted.append(t->exec());
+ }
+
+ const QList<QWSWindow> &list = qwsServer->clientWindows();
+ QWSWindow* w;
+ for (QListIterator<QWSWindow> it(list); (w=it.current()); ++it) {
+ QString app = w->client()->identity();
+ if ( appsstarted.contains(app) && !appsrunning.contains(app) )
+ appsrunning.append(app);
+ }
+
+ if ( appsrunning.count() > 1 ) {
+ QStringList::ConstIterator it = appsrunning.begin();
+ ++it; // top stays running!
+ for (; it != appsrunning.end(); it++) {
+ for ( int i=task->count()-1; i>=0; --i ) {
+ AppLnk *t = task->at(i);
+ if ( t->exec() == *it )
+ Global::terminate(t);
+ }
+ }
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+void MRUList::mousePressEvent(QMouseEvent *e)
+{
+ selected = 0;
+ int x=0;
+ QListIterator<AppLnk> it( *task );
+ for ( ; it.current(); ++it,++selected,x+=15 ) {
+ if ( x + 15 <= width() ) {
+ if ( e->x() >= x && e->x() < x+15 ) {
+ if ( selected < (int)task->count() ) {
+ repaint(FALSE);
+ return;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ selected = -1;
+ repaint( FALSE );
+}
+
+
+void MRUList::mouseReleaseEvent(QMouseEvent *)
+{
+ if ( selected >= 0 ) {
+ if ( parentWidget() )
+ if ( parentWidget()->isA( "QPopupMenu" ) )
+ parentWidget()->hide();
+ Global::execute( task->at(selected)->exec() );
+ selected = -1;
+ oldsel = -1;
+ update();
+ }
+}
+
+
+void MRUList::paintEvent( QPaintEvent * )
+{
+ QPainter p( this );
+ AppLnk *t;
+ int x = 0;
+ int y = (height() - 14) / 2;
+ int i = 0;
+
+ p.fillRect( 0, 0, width(), height(), colorGroup().background() );
+
+ if ( task ) {
+ QListIterator<AppLnk> it( *task );
+ for ( ; it.current(); i++, ++it ) {
+ if ( x + 15 <= width() ) {
+ t = it.current();
+ if ( (int)i == selected )
+ p.fillRect( x, y, 15, t->pixmap().height()+1, colorGroup().highlight() );
+ else if ( (int)i == oldsel )
+ p.eraseRect( x, y, 15, t->pixmap().height()+1 );
+ p.drawPixmap( x, y, t->pixmap() );
+ x += 15;
+ }
+ }
+ }
+}
+
diff --git a/core/launcher/mrulist.h b/core/launcher/mrulist.h
new file mode 100644
index 0000000..141a09b
--- a/dev/null
+++ b/core/launcher/mrulist.h
@@ -0,0 +1,55 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef __MRU_LIST_H__
+#define __MRU_LIST_H__
+
+
+#include <qpe/applnk.h>
+
+#include <qframe.h>
+#include <qlist.h>
+#include <qpixmap.h>
+
+
+class MRUList : public QFrame
+{
+public:
+ MRUList( QWidget *parent );
+ ~MRUList();
+ virtual QSize sizeHint() const;
+ static void addTask( const AppLnk *appLnk );
+ bool quitOldApps();
+
+protected:
+ void mousePressEvent(QMouseEvent *e);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void paintEvent( QPaintEvent *event );
+
+private:
+ static QList<MRUList> *MRUListWidgets;
+ static QList<AppLnk> *task;
+ int selected;
+ int oldsel;
+};
+
+
+#endif // __MRU_LIST_H__
+
diff --git a/core/launcher/obexinterface.h b/core/launcher/obexinterface.h
new file mode 100644
index 0000000..a73fde6
--- a/dev/null
+++ b/core/launcher/obexinterface.h
@@ -0,0 +1,40 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef OBEXINTERFACE_H
+#define OBEXINTERFACE_H
+
+#include <qpe/qcom.h>
+
+#ifndef QT_NO_COMPONENT
+// ### regenerate!!!!!!
+// {6CA35D0B-C637-4865-A667-7D4CD8A70407}
+# ifndef IID_ObexInterface
+# define IID_ObexInterface QUuid( 0x6ca35d0b, 0xc637, 0x4865, 0xa6, 0x67, 0x7d, 0x4c, 0xd8, 0xa7, 0x04, 0x07)
+# endif
+#endif
+
+class QObject;
+
+struct ObexInterface : public QUnknownInterface
+{
+};
+
+#endif
diff --git a/core/launcher/packageslave.cpp b/core/launcher/packageslave.cpp
new file mode 100644
index 0000000..4f149a5
--- a/dev/null
+++ b/core/launcher/packageslave.cpp
@@ -0,0 +1,97 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "packageslave.h"
+
+#include <qpe/process.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#include <qdatastream.h>
+#include <qcopchannel_qws.h>
+
+#include <unistd.h>
+
+PackageSlave::PackageSlave( QObject *parent, char* name )
+ : QObject( parent, name ), packageChannel( 0 )
+{
+ // setup qcop channel
+ packageChannel = new QCopChannel( "QPE/Package", this );
+ connect( packageChannel, SIGNAL( received(const QCString &, const QByteArray &) ),
+ this, SLOT( qcopMessage( const QCString &, const QByteArray &) ) );
+}
+
+void PackageSlave::qcopMessage( const QCString &msg, const QByteArray &data )
+{
+ QDataStream stream( data, IO_ReadOnly );
+
+ if ( msg == "installPackage(QString)" ) {
+ QString file;
+ stream >> file;
+ installPackage( file );
+ }
+ else if ( msg == "removePackage(QString)" ) {
+ QString file;
+ stream >> file;
+ removePackage( file );
+ }
+}
+
+void PackageSlave::installPackage( const QString &package )
+{
+ Process proc( QStringList() << "ipkg" << "install" << package );
+
+ sendReply( "installStarted(QString)", package );
+
+ QString output;
+ if ( proc.exec( "", output ) ) {
+ sendReply( "installDone(QString)", package );
+ }
+ else {
+ sendReply( "installFailed(QString)", package );
+ }
+ QCopEnvelope e("QPE/System", "linkChanged(QString)");
+ QString lf = QString::null;
+ e << lf;
+ unlink( package );
+}
+
+void PackageSlave::removePackage( const QString &package )
+{
+ Process proc( QStringList() << "ipkg" << "remove" << package );
+
+ sendReply( "removeStarted(QString)", package );
+
+ QString output;
+ if ( proc.exec( "", output ) ) {
+ sendReply( "removeDone(QString)", package );
+ }
+ else {
+ sendReply( "removeFailed(QString)", package );
+ }
+ QCopEnvelope e("QPE/System", "linkChanged(QString)");
+ QString lf = QString::null;
+ e << lf;
+}
+
+void PackageSlave::sendReply( const QCString& msg, const QString& arg )
+{
+ QCopEnvelope e( "QPE/Desktop", msg );
+ e << arg;
+}
diff --git a/core/launcher/packageslave.h b/core/launcher/packageslave.h
new file mode 100644
index 0000000..036abed
--- a/dev/null
+++ b/core/launcher/packageslave.h
@@ -0,0 +1,52 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef __packageslave_h__
+#define __packageslave_h__
+
+#include <qobject.h>
+
+class QCopChannel;
+
+class PackageSlave : public QObject
+{
+ Q_OBJECT
+
+public:
+ PackageSlave( QObject *parent, char* name = 0 );
+
+protected:
+ void installPackage( const QString &package );
+ void removePackage( const QString &package );
+
+protected slots:
+ void qcopMessage( const QCString &msg, const QByteArray &data );
+
+private:
+ void sendReply( const QCString& msg, const QString& arg );
+
+private:
+ QCopChannel *packageChannel;
+};
+
+
+#endif // __QUICK_LAUNCHER_H__
+
+
diff --git a/core/launcher/qcopbridge.cpp b/core/launcher/qcopbridge.cpp
new file mode 100644
index 0000000..c78e827
--- a/dev/null
+++ b/core/launcher/qcopbridge.cpp
@@ -0,0 +1,416 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "qcopbridge.h"
+#include "transferserver.h"
+
+#include <qpe/qcopenvelope_qws.h>
+#include <qpe/qpeapplication.h>
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qdatastream.h>
+#include <qstringlist.h>
+#include <qfileinfo.h>
+#include <qregexp.h>
+#include <qcopchannel_qws.h>
+
+#define _XOPEN_SOURCE
+#include <pwd.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#if defined(_OS_LINUX_)
+#include <shadow.h>
+#endif
+
+//#define INSECURE
+
+const int block_size = 51200;
+
+QCopBridge::QCopBridge( Q_UINT16 port, QObject *parent = 0,
+ const char* name = 0)
+ : QServerSocket( port, 1, parent, name ),
+ desktopChannel( 0 ),
+ cardChannel( 0 )
+{
+ if ( !ok() )
+ qWarning( "Failed to bind to port %d", port );
+ else {
+ desktopChannel = new QCopChannel( "QPE/Desktop", this );
+ connect( desktopChannel, SIGNAL(received(const QCString &, const QByteArray &)),
+ this, SLOT(desktopMessage( const QCString &, const QByteArray &)) );
+ cardChannel = new QCopChannel( "QPE/Card", this );
+ connect( cardChannel, SIGNAL(received(const QCString &, const QByteArray &)),
+ this, SLOT(desktopMessage( const QCString &, const QByteArray &)) );
+ }
+ sendSync = FALSE;
+}
+
+QCopBridge::~QCopBridge()
+{
+ delete desktopChannel;
+}
+
+void QCopBridge::newConnection( int socket )
+{
+ QCopBridgePI *pi = new QCopBridgePI( socket, this );
+ openConnections.append( pi );
+ connect ( pi, SIGNAL( connectionClosed( QCopBridgePI *) ), this, SLOT( connectionClosed( QCopBridgePI *) ) );
+ QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::DisableSuspend;
+
+ if ( sendSync ) {
+ pi ->startSync();
+ sendSync = FALSE;
+ }
+}
+
+void QCopBridge::connectionClosed( QCopBridgePI *pi )
+{
+ openConnections.remove( pi );
+ if ( openConnections.count() == 0 ) {
+ QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
+ }
+}
+
+void QCopBridge::closeOpenConnections()
+{
+ QCopBridgePI *pi;
+ for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() )
+ pi->close();
+}
+
+
+void QCopBridge::desktopMessage( const QCString &command, const QByteArray &args )
+{
+ command.stripWhiteSpace();
+
+ int paren = command.find( "(" );
+ if ( paren <= 0 ) {
+ qDebug("DesktopMessage: bad qcop syntax");
+ return;
+ }
+
+ QString params = command.mid( paren + 1 );
+ if ( params[params.length()-1] != ')' ) {
+ qDebug("DesktopMessage: bad qcop syntax");
+ return;
+ }
+
+ params.truncate( params.length()-1 );
+
+ QStringList paramList = QStringList::split( ",", params );
+ QString data;
+ if ( paramList.count() ) {
+ QDataStream stream( args, IO_ReadOnly );
+ for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) {
+ QString str;
+ if ( *it == "QString" ) {
+ stream >> str;
+ } else if ( *it == "QCString" ) {
+ QCString cstr;
+ stream >> cstr;
+ str = QString::fromLocal8Bit( cstr );
+ } else if ( *it == "int" ) {
+ int i;
+ stream >> i;
+ str = QString::number( i );
+ } else if ( *it == "bool" ) {
+ int i;
+ stream >> i;
+ str = QString::number( i );
+ } else {
+ qDebug(" cannot route the argument type %s throught the qcop bridge", (*it).latin1() );
+ return;
+ }
+ str.replace( QRegExp("&"), "&amp;" );
+ str.replace( QRegExp(" "), "&0x20;" );
+ str.replace( QRegExp("\n"), "&0x0d;" );
+ str.replace( QRegExp("\r"), "&0x0a;" );
+ data += " " + str;
+ }
+ }
+ QString sendCommand = QString(command.data()) + data;
+ // send the command to all open connections
+ if ( command == "startSync()" ) {
+ // we need to buffer it a bit
+ sendSync = TRUE;
+ startTimer( 20000 );
+ }
+
+ QCopBridgePI *pi;
+ for ( pi = openConnections.first(); pi != 0; pi = openConnections.next() ) {
+ pi->sendDesktopMessage( sendCommand );
+ }
+}
+
+void QCopBridge::timerEvent( QTimerEvent * )
+{
+ sendSync = FALSE;
+ killTimers();
+}
+
+
+QCopBridgePI::QCopBridgePI( int socket, QObject *parent = 0, const char* name = 0 )
+ : QSocket( parent, name )
+{
+ setSocket( socket );
+
+ peerport = peerPort();
+ peeraddress = peerAddress();
+
+#ifndef INSECURE
+ if ( !accessAuthorized(peeraddress) ) {
+ state = Forbidden;
+ startTimer( 0 );
+ } else
+#endif
+ {
+ state = Connected;
+ sendSync = FALSE;
+ connect( this, SIGNAL( readyRead() ), SLOT( read() ) );
+ connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
+
+ send( "220 Qtopia QCop bridge ready!" );
+ state = Wait_USER;
+
+ // idle timer to close connections when not used anymore
+ startTimer( 60000 );
+ connected = TRUE;
+ }
+}
+
+
+QCopBridgePI::~QCopBridgePI()
+{
+
+}
+
+void QCopBridgePI::connectionClosed()
+{
+ emit connectionClosed( this );
+ // qDebug( "Debug: Connection closed" );
+ delete this;
+}
+
+void QCopBridgePI::sendDesktopMessage( const QString &msg )
+{
+ QString str = "CALL QPE/Desktop " + msg;
+ send ( str );
+}
+
+
+void QCopBridgePI::send( const QString& msg )
+{
+ QTextStream os( this );
+ os << msg << endl;
+ //qDebug( "sending qcop message: %s", msg.latin1() );
+}
+
+void QCopBridgePI::read()
+{
+ while ( canReadLine() )
+ process( readLine().stripWhiteSpace() );
+}
+
+bool QCopBridgePI::checkUser( const QString& user )
+{
+ if ( user.isEmpty() ) return FALSE;
+
+ struct passwd *pw;
+ pw = getpwuid( geteuid() );
+ QString euser = QString::fromLocal8Bit( pw->pw_name );
+ return user == euser;
+}
+
+bool QCopBridgePI::checkPassword( const QString& password )
+{
+ // ### HACK for testing on local host
+ return true;
+
+ /*
+ struct passwd *pw = 0;
+ struct spwd *spw = 0;
+
+ pw = getpwuid( geteuid() );
+ spw = getspnam( pw->pw_name );
+
+ QString cpwd = QString::fromLocal8Bit( pw->pw_passwd );
+ if ( cpwd == "x" && spw )
+ cpwd = QString::fromLocal8Bit( spw->sp_pwdp );
+
+ QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) );
+ return cpwd == cpassword;
+*/
+}
+
+void QCopBridgePI::process( const QString& message )
+{
+ //qDebug( "Command: %s", message.latin1() );
+
+ // split message using "," as separator
+ QStringList msg = QStringList::split( " ", message );
+ if ( msg.isEmpty() ) return;
+
+ // command token
+ QString cmd = msg[0].upper();
+
+ // argument token
+ QString arg;
+ if ( msg.count() >= 2 )
+ arg = msg[1];
+
+ // we always respond to QUIT, regardless of state
+ if ( cmd == "QUIT" ) {
+ send( "211 Have a nice day!" );
+ delete this;
+ return;
+ }
+
+ // connected to client
+ if ( Connected == state )
+ return;
+
+ // waiting for user name
+ if ( Wait_USER == state ) {
+
+ if ( cmd != "USER" || msg.count() < 2 || !checkUser( arg ) ) {
+ send( "530 Please login with USER and PASS" );
+ return;
+ }
+ send( "331 User name ok, need password" );
+ state = Wait_PASS;
+ return;
+ }
+
+ // waiting for password
+ if ( Wait_PASS == state ) {
+
+ if ( cmd != "PASS" || !checkPassword( arg ) ) {
+ //if ( cmd != "PASS" || msg.count() < 2 || !checkPassword( arg ) ) {
+ send( "530 Please login with USER and PASS" );
+ return;
+ }
+ send( "230 User logged in, proceed" );
+ state = Ready;
+ if ( sendSync ) {
+ sendDesktopMessage( "startSync()" );
+ sendSync = FALSE;
+ }
+ return;
+ }
+
+ // noop (NOOP)
+ else if ( cmd == "NOOP" ) {
+ connected = TRUE;
+ send( "200 Command okay" );
+ }
+
+ // call (CALL)
+ else if ( cmd == "CALL" ) {
+
+ // example: call QPE/System execute(QString) addressbook
+
+ if ( msg.count() < 3 ) {
+ send( "500 Syntax error, command unrecognized" );
+ }
+ else {
+
+ QString channel = msg[1];
+ QString command = msg[2];
+
+ command.stripWhiteSpace();
+
+ int paren = command.find( "(" );
+ if ( paren <= 0 ) {
+ send( "500 Syntax error, command unrecognized" );
+ return;
+ }
+
+ QString params = command.mid( paren + 1 );
+ if ( params[params.length()-1] != ')' ) {
+ send( "500 Syntax error, command unrecognized" );
+ return;
+ }
+
+ params.truncate( params.length()-1 );
+ QByteArray buffer;
+ QDataStream ds( buffer, IO_WriteOnly );
+
+ int msgId = 3;
+
+ QStringList paramList = QStringList::split( ",", params );
+ if ( paramList.count() > msg.count() - 3 ) {
+ send( "500 Syntax error, command unrecognized" );
+ return;
+ }
+
+ for ( QStringList::Iterator it = paramList.begin(); it != paramList.end(); ++it ) {
+
+ QString arg = msg[msgId];
+ arg.replace( QRegExp("&0x20;"), " " );
+ arg.replace( QRegExp("&amp;"), "&" );
+ arg.replace( QRegExp("&0x0d;"), "\n" );
+ arg.replace( QRegExp("&0x0a;"), "\r" );
+ if ( *it == "QString" )
+ ds << arg;
+ else if ( *it == "QCString" )
+ ds << arg.local8Bit();
+ else if ( *it == "int" )
+ ds << arg.toInt();
+ else if ( *it == "bool" )
+ ds << arg.toInt();
+ else {
+ send( "500 Syntax error, command unrecognized" );
+ return;
+ }
+ msgId++;
+ }
+
+ if ( !QCopChannel::isRegistered( channel.latin1() ) ) {
+ // send message back about it
+ QString answer = "599 ChannelNotRegistered " + channel;
+ send( answer );
+ return;
+ }
+
+ if ( paramList.count() )
+ QCopChannel::send( channel.latin1(), command.latin1(), buffer );
+ else
+ QCopChannel::send( channel.latin1(), command.latin1() );
+
+ send( "200 Command okay" );
+ }
+ }
+ // not implemented
+ else
+ send( "502 Command not implemented" );
+}
+
+
+
+void QCopBridgePI::timerEvent( QTimerEvent * )
+{
+ if ( connected )
+ connected = FALSE;
+ else
+ connectionClosed();
+}
diff --git a/core/launcher/qcopbridge.h b/core/launcher/qcopbridge.h
new file mode 100644
index 0000000..114b3ee
--- a/dev/null
+++ b/core/launcher/qcopbridge.h
@@ -0,0 +1,95 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef __qcopbridge_h__
+#define __qcopbridge_h__
+
+#include <qserversocket.h>
+#include <qsocket.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qbuffer.h>
+
+class QFileInfo;
+class QCopBridgePI;
+class QCopChannel;
+
+class QCopBridge : public QServerSocket
+{
+ Q_OBJECT
+
+public:
+ QCopBridge( Q_UINT16 port, QObject *parent = 0, const char* name = 0 );
+ virtual ~QCopBridge();
+
+ void newConnection( int socket );
+ void closeOpenConnections();
+
+public slots:
+ void connectionClosed( QCopBridgePI *pi );
+ void desktopMessage( const QCString &call, const QByteArray & );
+
+protected:
+ void timerEvent( QTimerEvent * );
+
+private:
+ QCopChannel *desktopChannel;
+ QCopChannel *cardChannel;
+ QList<QCopBridgePI> openConnections;
+ bool sendSync;
+};
+
+
+class QCopBridgePI : public QSocket
+{
+ Q_OBJECT
+
+ enum State { Connected, Wait_USER, Wait_PASS, Ready, Forbidden };
+
+public:
+ QCopBridgePI( int socket, QObject *parent = 0, const char* name = 0 );
+ virtual ~QCopBridgePI();
+
+ void sendDesktopMessage( const QString &msg );
+ void startSync() { sendSync = TRUE; }
+
+signals:
+ void connectionClosed( QCopBridgePI *);
+
+protected slots:
+ void read();
+ void send( const QString& msg );
+ void process( const QString& command );
+ void connectionClosed();
+
+protected:
+ bool checkUser( const QString& user );
+ bool checkPassword( const QString& pw );
+
+ void timerEvent( QTimerEvent *e );
+
+private:
+ State state;
+ Q_UINT16 peerport;
+ QHostAddress peeraddress;
+ bool connected;
+ bool sendSync;
+};
+
+#endif
diff --git a/core/launcher/qpe-taskbar.control b/core/launcher/qpe-taskbar.control
new file mode 100644
index 0000000..f78f136
--- a/dev/null
+++ b/core/launcher/qpe-taskbar.control
@@ -0,0 +1,9 @@
+Files: bin/qpe apps/Settings/Calibrate.desktop
+Priority: required
+Section: qpe/system
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qt-embedded (>=$QTE_VERSION)
+Description: Launcher for QPE
+ The "finder" or "explorer", or whatever you want to call it.
diff --git a/core/launcher/quicklauncher.cpp b/core/launcher/quicklauncher.cpp
new file mode 100644
index 0000000..925b3b5
--- a/dev/null
+++ b/core/launcher/quicklauncher.cpp
@@ -0,0 +1,49 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qapplication.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <applnk.h>
+#include <resource.h>
+#include "quicklauncher.h"
+
+
+void QuickLauncher::addLauncherButton( AppLnk *appLnk )
+{
+ QPushButton *pb = new QPushButton( this );
+ // It's no a QObject anymore
+ //pb->connect( pb, SIGNAL( clicked( ) ), appLnk, SLOT( execute() ) );
+ pb->setPixmap( appLnk->pixmap() );
+ pb->setFocusPolicy( QWidget::NoFocus );
+ pb->setFlat( TRUE );
+ pb->setFixedSize( 18, 18 );
+}
+
+
+QuickLauncher::QuickLauncher( QWidget *parent ) : QHBox( parent )
+{
+// Example usage to add icons to the quick launcher area
+// addLauncherButton( "filebrowser_icon", "filebrowser" );
+// addLauncherButton( "textedit_icon", "textedit" );
+// addLauncherButton( "help_icon", "helpbrowser" );
+}
+
+
diff --git a/core/launcher/quicklauncher.h b/core/launcher/quicklauncher.h
new file mode 100644
index 0000000..92c6c66
--- a/dev/null
+++ b/core/launcher/quicklauncher.h
@@ -0,0 +1,40 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef __QUICK_LAUNCHER_H__
+#define __QUICK_LAUNCHER_H__
+
+
+#include <qhbox.h>
+
+class AppLnk;
+
+
+class QuickLauncher : public QHBox {
+ Q_OBJECT
+public:
+ QuickLauncher( QWidget *parent );
+ void addLauncherButton( AppLnk * );
+};
+
+
+#endif // __QUICK_LAUNCHER_H__
+
+
diff --git a/core/launcher/shutdown.ui b/core/launcher/shutdown.ui
new file mode 100644
index 0000000..0023427
--- a/dev/null
+++ b/core/launcher/shutdown.ui
@@ -0,0 +1,1323 @@
+<!DOCTYPE UI><UI>
+<class>Shutdown</class>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Form1</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>437</width>
+ <height>465</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Shut down...</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>6</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>3</number>
+ </property>
+ <widget>
+ <class>QButtonGroup</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>ButtonGroup1</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Terminate</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>7</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>3</number>
+ </property>
+ <widget row="1" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>quit</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>palette</name>
+ <palette>
+ <active>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>236</red>
+ <green>236</green>
+ <blue>179</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>245</red>
+ <green>245</green>
+ <blue>217</blue>
+ </color>
+ <color>
+ <red>118</red>
+ <green>118</green>
+ <blue>89</blue>
+ </color>
+ <color>
+ <red>157</red>
+ <green>157</green>
+ <blue>119</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>222</red>
+ <green>222</green>
+ <blue>222</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </active>
+ <disabled>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>236</red>
+ <green>236</green>
+ <blue>179</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>209</blue>
+ </color>
+ <color>
+ <red>118</red>
+ <green>118</green>
+ <blue>89</blue>
+ </color>
+ <color>
+ <red>157</red>
+ <green>157</green>
+ <blue>119</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>222</red>
+ <green>222</green>
+ <blue>222</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </disabled>
+ <inactive>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>236</red>
+ <green>236</green>
+ <blue>179</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>209</blue>
+ </color>
+ <color>
+ <red>118</red>
+ <green>118</green>
+ <blue>89</blue>
+ </color>
+ <color>
+ <red>157</red>
+ <green>157</green>
+ <blue>119</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>222</red>
+ <green>222</green>
+ <blue>222</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </inactive>
+ </palette>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Terminate Server</string>
+ </property>
+ <property stdset="1">
+ <name>buttonGroupId</name>
+ <number>4</number>
+ </property>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>reboot</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>palette</name>
+ <palette>
+ <active>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>236</red>
+ <green>183</green>
+ <blue>181</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>245</red>
+ <green>219</green>
+ <blue>218</blue>
+ </color>
+ <color>
+ <red>118</red>
+ <green>92</green>
+ <blue>91</blue>
+ </color>
+ <color>
+ <red>157</red>
+ <green>122</green>
+ <blue>121</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>222</red>
+ <green>222</green>
+ <blue>222</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </active>
+ <disabled>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>236</red>
+ <green>183</green>
+ <blue>181</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>213</green>
+ <blue>212</blue>
+ </color>
+ <color>
+ <red>118</red>
+ <green>92</green>
+ <blue>91</blue>
+ </color>
+ <color>
+ <red>157</red>
+ <green>122</green>
+ <blue>121</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>222</red>
+ <green>222</green>
+ <blue>222</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </disabled>
+ <inactive>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>236</red>
+ <green>183</green>
+ <blue>181</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>213</green>
+ <blue>212</blue>
+ </color>
+ <color>
+ <red>118</red>
+ <green>92</green>
+ <blue>91</blue>
+ </color>
+ <color>
+ <red>157</red>
+ <green>122</green>
+ <blue>121</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>222</red>
+ <green>222</green>
+ <blue>222</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </inactive>
+ </palette>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Reboot</string>
+ </property>
+ <property stdset="1">
+ <name>buttonGroupId</name>
+ <number>2</number>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>restart</cstring>
+ </property>
+ <property stdset="1">
+ <name>palette</name>
+ <palette>
+ <active>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>236</red>
+ <green>236</green>
+ <blue>179</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>245</red>
+ <green>245</green>
+ <blue>217</blue>
+ </color>
+ <color>
+ <red>118</red>
+ <green>118</green>
+ <blue>89</blue>
+ </color>
+ <color>
+ <red>157</red>
+ <green>157</green>
+ <blue>119</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>222</red>
+ <green>222</green>
+ <blue>222</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </active>
+ <disabled>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>236</red>
+ <green>236</green>
+ <blue>179</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>209</blue>
+ </color>
+ <color>
+ <red>118</red>
+ <green>118</green>
+ <blue>89</blue>
+ </color>
+ <color>
+ <red>157</red>
+ <green>157</green>
+ <blue>119</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>222</red>
+ <green>222</green>
+ <blue>222</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </disabled>
+ <inactive>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>236</red>
+ <green>236</green>
+ <blue>179</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>209</blue>
+ </color>
+ <color>
+ <red>118</red>
+ <green>118</green>
+ <blue>89</blue>
+ </color>
+ <color>
+ <red>157</red>
+ <green>157</green>
+ <blue>119</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>222</red>
+ <green>222</green>
+ <blue>222</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </inactive>
+ </palette>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Restart Server</string>
+ </property>
+ <property stdset="1">
+ <name>buttonGroupId</name>
+ <number>3</number>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>shutdown</cstring>
+ </property>
+ <property stdset="1">
+ <name>palette</name>
+ <palette>
+ <active>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>236</red>
+ <green>183</green>
+ <blue>181</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>245</red>
+ <green>219</green>
+ <blue>218</blue>
+ </color>
+ <color>
+ <red>118</red>
+ <green>92</green>
+ <blue>91</blue>
+ </color>
+ <color>
+ <red>157</red>
+ <green>122</green>
+ <blue>121</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>222</red>
+ <green>222</green>
+ <blue>222</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </active>
+ <disabled>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>236</red>
+ <green>183</green>
+ <blue>181</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>213</green>
+ <blue>212</blue>
+ </color>
+ <color>
+ <red>118</red>
+ <green>92</green>
+ <blue>91</blue>
+ </color>
+ <color>
+ <red>157</red>
+ <green>122</green>
+ <blue>121</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>222</red>
+ <green>222</green>
+ <blue>222</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </disabled>
+ <inactive>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>236</red>
+ <green>183</green>
+ <blue>181</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>213</green>
+ <blue>212</blue>
+ </color>
+ <color>
+ <red>118</red>
+ <green>92</green>
+ <blue>91</blue>
+ </color>
+ <color>
+ <red>157</red>
+ <green>122</green>
+ <blue>121</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>222</red>
+ <green>222</green>
+ <blue>222</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </inactive>
+ </palette>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Shutdown</string>
+ </property>
+ <property stdset="1">
+ <name>buttonGroupId</name>
+ <number>1</number>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>info</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;p&gt;
+These termination options are provided primarily for use while developing and testing the Qtopia system. In a normal environment, these concepts are unnecessary.</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QProgressBar</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>progressBar</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>totalSteps</name>
+ <number>20</number>
+ </property>
+ <property stdset="1">
+ <name>indicatorFollowsStyle</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cancel</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>7</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>palette</name>
+ <palette>
+ <active>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>181</red>
+ <green>222</green>
+ <blue>178</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>218</red>
+ <green>238</green>
+ <blue>216</blue>
+ </color>
+ <color>
+ <red>90</red>
+ <green>111</green>
+ <blue>89</blue>
+ </color>
+ <color>
+ <red>120</red>
+ <green>148</green>
+ <blue>118</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>174</red>
+ <green>222</green>
+ <blue>158</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </active>
+ <disabled>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>181</red>
+ <green>222</green>
+ <blue>178</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>207</red>
+ <green>255</green>
+ <blue>204</blue>
+ </color>
+ <color>
+ <red>90</red>
+ <green>111</green>
+ <blue>89</blue>
+ </color>
+ <color>
+ <red>120</red>
+ <green>148</green>
+ <blue>118</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>174</red>
+ <green>222</green>
+ <blue>158</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </disabled>
+ <inactive>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>181</red>
+ <green>222</green>
+ <blue>178</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>207</red>
+ <green>255</green>
+ <blue>204</blue>
+ </color>
+ <color>
+ <red>90</red>
+ <green>111</green>
+ <blue>89</blue>
+ </color>
+ <color>
+ <red>120</red>
+ <green>148</green>
+ <blue>118</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>174</red>
+ <green>222</green>
+ <blue>158</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </inactive>
+ </palette>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Cancel</string>
+ </property>
+ <property stdset="1">
+ <name>default</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+</UI>
diff --git a/core/launcher/shutdownimpl.cpp b/core/launcher/shutdownimpl.cpp
new file mode 100644
index 0000000..06ed756
--- a/dev/null
+++ b/core/launcher/shutdownimpl.cpp
@@ -0,0 +1,95 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "shutdownimpl.h"
+
+#include <qpe/global.h>
+
+#include <qtimer.h>
+#include <qprogressbar.h>
+#include <qpushbutton.h>
+#include <qbuttongroup.h>
+#include <qlabel.h>
+
+
+
+#include <stdio.h>
+ShutdownImpl::ShutdownImpl( QWidget* parent, const char *name, WFlags fl )
+ : Shutdown( parent, name, fl )
+{
+ timer = new QTimer( this );
+ connect( timer, SIGNAL(timeout()), this, SLOT(timeout()) );
+
+ connect( ButtonGroup1, SIGNAL(clicked(int)), this, SLOT(buttonClicked(int)) );
+ connect( cancel, SIGNAL(clicked()), this, SLOT(cancelClicked()) );
+
+ progressBar->hide();
+ Global::hideInputMethod();
+#ifdef QT_QWS_CUSTOM
+ QPushButton *sb = Shutdown::shutdown;
+ sb->hide();
+#endif
+}
+
+void ShutdownImpl::buttonClicked( int b )
+{
+ progress = 0;
+ switch ( b ) {
+ case 1:
+ operation = ShutdownSystem;
+ break;
+ case 2:
+ operation = RebootSystem;
+ break;
+ case 3:
+ operation = RestartDesktop;
+ break;
+ case 4:
+ operation = TerminateDesktop;
+ break;
+ }
+ info->hide();
+ progressBar->show();
+ timer->start( 300 );
+ timeout();
+}
+
+void ShutdownImpl::cancelClicked()
+{
+ progressBar->hide();
+ info->show();
+ if ( timer->isActive() )
+ timer->stop();
+ else
+ close();
+}
+
+void ShutdownImpl::timeout()
+{
+ if ( (progress+=2) > progressBar->totalSteps() ) {
+ progressBar->hide();
+ timer->stop();
+ emit shutdown( operation );
+ } else {
+ progressBar->setProgress( progress );
+ }
+}
+
+
diff --git a/core/launcher/shutdownimpl.h b/core/launcher/shutdownimpl.h
new file mode 100644
index 0000000..54668f3
--- a/dev/null
+++ b/core/launcher/shutdownimpl.h
@@ -0,0 +1,50 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef SHUTDOWNIMPL_H
+#define SHUTDOWNIMPL_H
+
+#include "shutdown.h"
+
+class QTimer;
+
+class ShutdownImpl : public Shutdown
+{
+ Q_OBJECT
+public:
+ ShutdownImpl( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+
+ enum Type { ShutdownSystem, RebootSystem, RestartDesktop, TerminateDesktop };
+
+signals:
+ void shutdown( ShutdownImpl::Type );
+
+private slots:
+ void buttonClicked( int );
+ void cancelClicked();
+ void timeout();
+
+private:
+ QTimer *timer;
+ int progress;
+ Type operation;
+};
+
+#endif
+
diff --git a/core/launcher/sidething.cpp b/core/launcher/sidething.cpp
new file mode 100644
index 0000000..821c9d5
--- a/dev/null
+++ b/core/launcher/sidething.cpp
@@ -0,0 +1,75 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "sidething.h"
+
+#include <qpe/resource.h>
+
+#include <qrect.h>
+#include <qpopupmenu.h>
+#include <qpainter.h>
+
+
+void PopupWithLaunchSideThing::setFrameRect( const QRect &r )
+{
+ fr = r;
+ QPopupMenu::setFrameRect( r );
+}
+
+
+void PopupWithLaunchSideThing::paintEvent( QPaintEvent *event )
+{
+ QPainter paint( this );
+
+ if ( !contentsRect().contains( event->rect() ) ) {
+
+ QPopupMenu::setFrameRect( fr );
+ int oldLW = lineWidth();
+ setUpdatesEnabled(FALSE);
+ setLineWidth(oldLW);
+ setUpdatesEnabled(TRUE);
+
+ paint.save();
+ paint.setClipRegion( event->region().intersect( frameRect() ) );
+ QPixmap pm( Resource::loadPixmap( sidePixmap ) );
+ paint.drawPixmap( 2, fr.height() - pm.height() - 2, pm );
+// Need to draw a filled rectangle that extends the colour from the
+// end of the pixmap up to the top of the popupmenu
+// paint.fillRect();
+ drawFrame( &paint );
+ paint.restore();
+
+ }
+ if ( event->rect().intersects( contentsRect() ) /* &&
+ (fstyle & MShape) != HLine && (fstyle & MShape) != VLine */ ) {
+
+ QPopupMenu::setFrameRect( QRect(fr.left() + 21, fr.top(), fr.width() - 21, fr.height()) );
+ int oldLW = lineWidth();
+ setUpdatesEnabled(FALSE);
+ setLineWidth(oldLW);
+ setUpdatesEnabled(TRUE);
+
+ paint.setClipRegion( event->region().intersect( contentsRect() ) );
+ drawContents( &paint );
+ }
+
+}
+
+
diff --git a/core/launcher/sidething.h b/core/launcher/sidething.h
new file mode 100644
index 0000000..666a59d
--- a/dev/null
+++ b/core/launcher/sidething.h
@@ -0,0 +1,43 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef __SIDE_THING_H__
+#define __SIDE_THING_H__
+
+
+#include "startmenu.h"
+
+
+class PopupWithLaunchSideThing : public StartPopupMenu
+{
+Q_OBJECT
+public:
+ PopupWithLaunchSideThing( QWidget *parent, QString *pixmap ) : StartPopupMenu( parent ), sidePixmap(*pixmap) { }
+
+protected:
+ void setFrameRect( const QRect & );
+ void paintEvent( QPaintEvent *event );
+ QRect fr;
+ QString sidePixmap;
+};
+
+
+#endif // __SIDE_THING_H__
+
diff --git a/core/launcher/stabmon.cpp b/core/launcher/stabmon.cpp
new file mode 100644
index 0000000..2911a1c
--- a/dev/null
+++ b/core/launcher/stabmon.cpp
@@ -0,0 +1,92 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#include "stabmon.h"
+
+#include <qpe/qcopenvelope_qws.h>
+
+#include <qfile.h>
+#include <qcstring.h>
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+SysFileMonitor::SysFileMonitor(QObject* parent) :
+ QObject(parent)
+{
+ startTimer(2000);
+}
+
+const char * stab0 = "/var/run/stab";
+const char * stab1 = "/var/state/pcmcia/stab";
+const char * stab2 = "/var/lib/pcmcia/stab";
+
+void SysFileMonitor::timerEvent(QTimerEvent*)
+{
+ struct stat s;
+
+ static const char * tab [] = {
+ stab0,
+ stab1,
+ stab2
+ };
+ static const int nstab = sizeof(tab)/sizeof(const char *);
+ static int last[nstab];
+
+ bool ch = FALSE;
+ for ( int i=0; i<nstab; i++ ) {
+ if ( ::stat(tab[i], &s)==0 && (long)s.st_mtime != last[i] ) {
+ last[i] = (long)s.st_mtime;
+ ch=TRUE;
+ }
+ if ( ch ) {
+ QCopEnvelope("QPE/Card", "stabChanged()" );
+ break;
+ }
+ }
+
+ // st_size is no use, it's 0 for /proc/mounts too. Read it all.
+ static int mtabSize = 0;
+ QFile f( "/etc/mtab" );
+ if ( f.open(IO_ReadOnly) ) {
+#if 0
+ // readAll does not work correctly on sequential devices (as eg. /proc files)
+ QByteArray ba = f.readAll();
+ if ( (int)ba.size() != mtabSize ) {
+ mtabSize = (int)ba.size();
+ QCopEnvelope("QPE/Card", "mtabChanged()" );
+ }
+#else
+ QString s;
+ while( !f.atEnd() ) {
+ QString tmp;
+ f.readLine( tmp, 1024 );
+ s += tmp;
+ }
+ if ( (int)s.length() != mtabSize ) {
+ mtabSize = (int)s.length();
+ QCopEnvelope("QPE/Card", "mtabChanged()" );
+ }
+#endif
+ }
+}
+
diff --git a/core/launcher/stabmon.h b/core/launcher/stabmon.h
new file mode 100644
index 0000000..10c79a3
--- a/dev/null
+++ b/core/launcher/stabmon.h
@@ -0,0 +1,34 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#ifndef STABMON_H
+#define STABMON_H
+
+#include <qobject.h>
+
+class SysFileMonitor : public QObject {
+public:
+ SysFileMonitor(QObject* parent);
+protected:
+ void timerEvent(QTimerEvent*);
+};
+
+#endif
diff --git a/core/launcher/startmenu.cpp b/core/launcher/startmenu.cpp
new file mode 100644
index 0000000..54bdfcc
--- a/dev/null
+++ b/core/launcher/startmenu.cpp
@@ -0,0 +1,171 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "startmenu.h"
+#include "sidething.h"
+#include "mrulist.h"
+#include "info.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/config.h>
+#include <qpe/applnk.h>
+#include <qpe/global.h>
+#include <qpe/resource.h>
+
+#include <qdict.h>
+
+#include <stdlib.h>
+
+
+// #define USE_CONFIG_FILE
+
+
+StartMenu::StartMenu(QWidget *parent) : QLabel( parent )
+{
+ loadOptions();
+
+ setPixmap( Resource::loadPixmap( startButtonPixmap ) );
+ setFocusPolicy( NoFocus );
+ //setFlat( startButtonIsFlat );
+
+ apps = new AppLnkSet( QPEApplication::qpeDir() + "apps" );
+
+ createMenu();
+}
+
+
+void StartMenu::mousePressEvent( QMouseEvent * )
+{
+ launch();
+ if (desktopInfo)
+ desktopInfo->menuClicked();
+}
+
+
+StartMenu::~StartMenu()
+{
+ delete apps;
+}
+
+
+void StartMenu::loadOptions()
+{
+#ifdef USE_CONFIG_FILE
+ // Read configuration file
+ Config config("StartMenu");
+ config.setGroup( "StartMenu" );
+ QString tmpBoolString1 = config.readEntry( "UseWidePopupMenu", "FALSE" );
+ useWidePopupMenu = ( tmpBoolString1 == "TRUE" ) ? TRUE : FALSE;
+ QString tmpBoolString2 = config.readEntry( "StartButtonIsFlat", "TRUE" );
+ startButtonIsFlat = ( tmpBoolString2 == "TRUE" ) ? TRUE : FALSE;
+ QString tmpBoolString3 = config.readEntry( "UseMRUList", "TRUE" );
+ popupMenuSidePixmap = config.readEntry( "PopupMenuSidePixmap", "sidebar" );
+ startButtonPixmap = config.readEntry( "StartButtonPixmap", "go" );
+#else
+ // Basically just #include the .qpe_menu.conf file settings
+ useWidePopupMenu = FALSE;
+ popupMenuSidePixmap = "sidebar";
+ startButtonIsFlat = TRUE;
+ startButtonPixmap = "go";
+#endif
+}
+
+
+void StartMenu::createMenu()
+{
+ if ( useWidePopupMenu )
+ launchMenu = new PopupWithLaunchSideThing( this, &popupMenuSidePixmap );
+ else
+ launchMenu = new StartPopupMenu( this );
+
+ loadMenu( apps, launchMenu );
+
+}
+
+void StartMenu::itemSelected( int id )
+{
+ const AppLnk *app = apps->find( id );
+ if ( app )
+ app->execute();
+}
+
+bool StartMenu::loadMenu( AppLnkSet *folder, QPopupMenu *menu )
+{
+ bool result = FALSE;
+
+ QStringList typs = folder->types();
+ QDict<QPopupMenu> typpop;
+ for (QStringList::Iterator tit=typs.begin(); tit!=typs.end(); ++tit) {
+ if ( !(*tit).isEmpty() ) {
+ QPopupMenu *new_menu = new StartPopupMenu( menu );
+ typpop.insert(*tit, new_menu);
+ connect( new_menu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
+ menu->insertItem( folder->typePixmap(*tit), *tit, new_menu );
+ }
+ }
+
+ QListIterator<AppLnk> it( folder->children() );
+ for ( ; it.current(); ++it ) {
+ AppLnk *app = it.current();
+ if ( app->type() == "Separator" ) {
+ menu->insertSeparator();
+ } else {
+ QString t = app->type();
+ QPopupMenu* pmenu = typpop.find(t);
+ if ( !pmenu )
+ pmenu = menu;
+ pmenu->insertItem( app->pixmap(), app->name(), app->id() );
+ result=TRUE;
+ }
+ }
+
+ if ( result )
+ connect( menu, SIGNAL(activated(int)), SLOT(itemSelected(int)) );
+
+ return result;
+}
+
+
+void StartMenu::launch()
+{
+ int y = mapToGlobal( QPoint() ).y() - launchMenu->sizeHint().height();
+
+ if ( launchMenu->isVisible() )
+ launchMenu->hide();
+ else
+ launchMenu->popup( QPoint( 1, y ) );
+}
+
+const AppLnk* StartMenu::execToLink(const QString& appname)
+{
+ const AppLnk* a = apps->findExec( appname );
+ return a;
+}
+
+void StartPopupMenu::keyPressEvent( QKeyEvent *e )
+{
+ if ( e->key() == Key_F33 || e->key() == Key_Space ) {
+ // "OK" button, little hacky
+ QKeyEvent ke(QEvent::KeyPress, Key_Enter, 13, 0);
+ QPopupMenu::keyPressEvent( &ke );
+ } else {
+ QPopupMenu::keyPressEvent( e );
+ }
+}
diff --git a/core/launcher/startmenu.h b/core/launcher/startmenu.h
new file mode 100644
index 0000000..a02f39e
--- a/dev/null
+++ b/core/launcher/startmenu.h
@@ -0,0 +1,76 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef __START_MENU_H__
+#define __START_MENU_H__
+
+#include <qstring.h>
+#include <qlist.h>
+#include <qlabel.h>
+#include <qpopupmenu.h>
+
+
+class AppLnkSet;
+class AppLnk;
+
+class StartPopupMenu : public QPopupMenu
+{
+public:
+ StartPopupMenu( QWidget *parent ) : QPopupMenu( parent ) {}
+protected:
+ void keyPressEvent( QKeyEvent *e );
+};
+
+class StartMenu : public QLabel {
+ Q_OBJECT
+public:
+ StartMenu( QWidget * );
+ ~StartMenu();
+
+ const AppLnk* execToLink(const QString& appname);
+
+public:
+ StartPopupMenu *launchMenu;
+
+public slots:
+ void launch( );
+ void loadOptions( );
+ void createMenu( );
+
+protected slots:
+ void itemSelected( int id );
+
+protected:
+ virtual void mousePressEvent( QMouseEvent * );
+
+private:
+ bool loadMenu( AppLnkSet *folder, QPopupMenu *menu );
+
+private:
+ bool useWidePopupMenu;
+ QString popupMenuSidePixmap;
+
+ bool startButtonIsFlat;
+ QString startButtonPixmap;
+
+ AppLnkSet *apps;
+};
+
+#endif // __START_MENU_H__
diff --git a/core/launcher/syncdialog.ui b/core/launcher/syncdialog.ui
new file mode 100644
index 0000000..141f123
--- a/dev/null
+++ b/core/launcher/syncdialog.ui
@@ -0,0 +1,228 @@
+<!DOCTYPE UI><UI>
+<class>SyncDialog</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>SyncDialog</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>210</width>
+ <height>244</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Syncing</string>
+ </property>
+ <property stdset="1">
+ <name>sizeGripEnabled</name>
+ <bool>true</bool>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer10</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout3</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Syncing</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignCenter</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>whatLabel</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;b&gt;Contacts&lt;/b&gt;</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer11</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout4</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer4</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonCancel</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Cancel</string>
+ </property>
+ <property stdset="1">
+ <name>autoDefault</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer5</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer12</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>SyncDialog</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+</UI>
diff --git a/core/launcher/systray.cpp b/core/launcher/systray.cpp
new file mode 100644
index 0000000..ad1553f
--- a/dev/null
+++ b/core/launcher/systray.cpp
@@ -0,0 +1,107 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpe/qpeapplication.h>
+#include <qpe/qlibrary.h>
+#include <qpe/config.h>
+
+#include <qlayout.h>
+#include <qdir.h>
+#include <qtranslator.h>
+
+#include "quicklauncher.h"
+#include "systray.h"
+
+#include <stdlib.h>
+
+#ifdef SINGLE_APP
+#include "clockappletimpl.h"
+#endif
+
+SysTray::SysTray( QWidget *parent ) : QFrame( parent ), layout(0)
+{
+ //setFrameStyle( QFrame::Panel | QFrame::Sunken );
+ loadApplets();
+}
+
+void SysTray::loadApplets()
+{
+#ifndef SINGLE_APP
+ QValueList<TaskbarApplet>::Iterator mit;
+ for ( mit = appletList.begin(); mit != appletList.end(); ++mit ) {
+ (*mit).iface->release();
+ (*mit).library->unload();
+ delete (*mit).library;
+ }
+ appletList.clear();
+ if ( layout )
+ delete layout;
+ layout = new QHBoxLayout( this );
+
+ QString path = QPEApplication::qpeDir() + "/plugins/applets";
+ QDir dir( path, "lib*.so" );
+ QStringList list = dir.entryList();
+ QStringList::Iterator it;
+ for ( it = list.begin(); it != list.end(); ++it ) {
+ TaskbarAppletInterface *iface = 0;
+ QLibrary *lib = new QLibrary( path + "/" + *it );
+ if ( lib->queryInterface( IID_TaskbarApplet, (QUnknownInterface**)&iface ) == QS_OK ) {
+ TaskbarApplet applet;
+ applet.library = lib;
+ applet.iface = iface;
+ applet.applet = applet.iface->applet( this );
+ positionApplet( applet );
+ QString lang = getenv( "LANG" );
+ QTranslator * trans = new QTranslator(qApp);
+ QString type = (*it).left( (*it).find(".") );
+ QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/"+type+".qm";
+ qDebug("tr fpr sysapplet: %s", tfn.latin1() );
+ if ( trans->load( tfn ))
+ qApp->installTranslator( trans );
+ else
+ delete trans;
+ } else {
+ delete lib;
+ }
+ }
+#else
+ layout = new QHBoxLayout( this );
+ TaskbarApplet applet;
+ applet.iface = new ClockAppletImpl();
+ applet.applet = applet.iface->applet( this );
+ positionApplet( applet );
+#endif
+}
+
+void SysTray::positionApplet( const TaskbarApplet &a )
+{
+ int p = 0;
+ QValueList<TaskbarApplet>::Iterator it;
+ for ( it = appletList.begin(); it != appletList.end(); ++it ) {
+ if ( (*it).iface->position() > a.iface->position() )
+ break;
+ p += 2;
+ }
+
+ appletList.insert( it, a );
+ layout->insertWidget( p, a.applet );
+ layout->insertSpacing( p, 1 );
+}
+
diff --git a/core/launcher/systray.h b/core/launcher/systray.h
new file mode 100644
index 0000000..0aed348
--- a/dev/null
+++ b/core/launcher/systray.h
@@ -0,0 +1,58 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef __SYSTRAY_H__
+#define __SYSTRAY_H__
+
+#include <qpe/taskbarappletinterface.h>
+
+#include <qframe.h>
+#include <qvaluelist.h>
+
+class QHBoxLayout;
+class QLibrary;
+
+struct TaskbarApplet
+{
+#ifndef QT_NO_COMPONENT
+ QLibrary *library;
+#endif
+ TaskbarAppletInterface *iface;
+ QWidget *applet;
+};
+
+class SysTray : public QFrame {
+ Q_OBJECT
+public:
+ SysTray( QWidget *parent );
+
+ void loadApplets();
+
+private:
+ void positionApplet( const TaskbarApplet &a );
+
+private:
+ QHBoxLayout *layout;
+ QValueList<TaskbarApplet> appletList;
+};
+
+
+#endif // __SYSTRAY_H__
+
diff --git a/core/launcher/taskbar.cpp b/core/launcher/taskbar.cpp
new file mode 100644
index 0000000..d7f36bd
--- a/dev/null
+++ b/core/launcher/taskbar.cpp
@@ -0,0 +1,314 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "startmenu.h"
+#include "inputmethods.h"
+#include "mrulist.h"
+#include "systray.h"
+#include "calibrate.h"
+#include "wait.h"
+#include "appicons.h"
+
+#include "taskbar.h"
+#include "desktop.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/qcopenvelope_qws.h>
+#include <qpe/global.h>
+#ifdef QT_QWS_CUSTOM
+#include <qpe/custom.h>
+#endif
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <qwindowsystem_qws.h>
+#include <qwidgetstack.h>
+
+#if defined( Q_WS_QWS )
+#include <qwsdisplay_qws.h>
+#include <qgfx_qws.h>
+#endif
+
+
+#define FACTORY(T) \
+ static QWidget *new##T( bool maximized ) { \
+ QWidget *w = new T( 0, "test", QWidget::WDestructiveClose | QWidget::WGroupLeader ); \
+ if ( maximized ) { \
+ if ( qApp->desktop()->width() <= 350 ) { \
+ w->showMaximized(); \
+ } else { \
+ w->resize( QSize( 300, 300 ) ); \
+ } \
+ } \
+ w->show(); \
+ return w; \
+ }
+
+
+#ifdef SINGLE_APP
+#define APP(a,b,c,d) FACTORY(b)
+#include "../taskbar/apps.h"
+#undef APP
+#endif // SINGLE_APP
+
+static Global::Command builtins[] = {
+
+#ifdef SINGLE_APP
+#define APP(a,b,c,d) { a, new##b, c },
+#include "../taskbar/apps.h"
+#undef APP
+#endif
+
+#if defined(QT_QWS_IPAQ) || defined(QT_QWS_CASSIOPEIA) || defined(QT_QWS_EBX)
+ { "calibrate", TaskBar::calibrate, 1, 0 },
+#endif
+#if !defined(QT_QWS_CASSIOPEIA)
+ { "shutdown", Global::shutdown, 1, 0 },
+// { "run", run, 1, 0 },
+#endif
+
+ { 0, TaskBar::calibrate, 0, 0 },
+};
+
+static bool initNumLock()
+{
+#ifdef QPE_INITIAL_NUMLOCK_STATE
+ QPE_INITIAL_NUMLOCK_STATE
+#endif
+ return FALSE;
+}
+
+class LockKeyState : public QWidget
+{
+public:
+ LockKeyState( QWidget *parent ) :
+ QWidget(parent),
+ nl(initNumLock()), cl(FALSE)
+ {
+ nl_pm = Resource::loadPixmap("numlock");
+ cl_pm = Resource::loadPixmap("capslock");
+ }
+ QSize sizeHint() const
+ {
+ return QSize(nl_pm.width()+2,nl_pm.width()+nl_pm.height()+1);
+ }
+ void toggleNumLockState()
+ {
+ nl = !nl; repaint();
+ }
+ void toggleCapsLockState()
+ {
+ cl = !cl; repaint();
+ }
+ void paintEvent( QPaintEvent * )
+ {
+ int y = (height()-sizeHint().height())/2;
+ QPainter p(this);
+ if ( nl )
+ p.drawPixmap(1,y,nl_pm);
+ if ( cl )
+ p.drawPixmap(1,y+nl_pm.height()+1,cl_pm);
+ }
+private:
+ QPixmap nl_pm, cl_pm;
+ bool nl, cl;
+};
+
+TaskBar::~TaskBar()
+{
+}
+
+
+TaskBar::TaskBar() : QHBox(0, 0, WStyle_Customize | WStyle_Tool | WStyle_StaysOnTop | WGroupLeader)
+{
+ Global::setBuiltinCommands(builtins);
+
+ sm = new StartMenu( this );
+
+ inputMethods = new InputMethods( this );
+ connect( inputMethods, SIGNAL(inputToggled(bool)),
+ this, SLOT(calcMaxWindowRect()) );
+ //new QuickLauncher( this );
+
+ stack = new QWidgetStack( this );
+ stack->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) );
+ label = new QLabel(stack);
+
+ mru = new MRUList( stack );
+ stack->raiseWidget( mru );
+
+ waitIcon = new Wait( this );
+ (void) new AppIcons( this );
+
+ sysTray = new SysTray( this );
+
+ // ## make customizable in some way?
+#ifdef QT_QWS_CUSTOM
+ lockState = new LockKeyState( this );
+#else
+ lockState = 0;
+#endif
+
+#if defined(Q_WS_QWS)
+#if !defined(QT_NO_COP)
+ QCopChannel *channel = new QCopChannel( "QPE/TaskBar", this );
+ connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
+ this, SLOT(receive(const QCString&, const QByteArray&)) );
+#endif
+#endif
+ waitTimer = new QTimer( this );
+ connect( waitTimer, SIGNAL( timeout() ), this, SLOT( stopWait() ) );
+ clearer = new QTimer( this );
+ QObject::connect(clearer, SIGNAL(timeout()), SLOT(clearStatusBar()));
+ QObject::connect(clearer, SIGNAL(timeout()), sysTray, SLOT(show()));
+}
+
+void TaskBar::setStatusMessage( const QString &text )
+{
+ label->setText( text );
+ stack->raiseWidget( label );
+ if ( sysTray && ( label->fontMetrics().width( text ) > label->width() ) )
+ sysTray->hide();
+ clearer->start( 3000 );
+}
+
+void TaskBar::clearStatusBar()
+{
+ label->clear();
+ stack->raiseWidget( mru );
+}
+
+void TaskBar::startWait()
+{
+ waitIcon->setWaiting( true );
+ // a catchall stop after 10 seconds...
+ waitTimer->start( 10 * 1000, true );
+}
+
+void TaskBar::stopWait(const QString& app)
+{
+ waitTimer->stop();
+ mru->addTask(sm->execToLink(app));
+ waitIcon->setWaiting( false );
+}
+
+void TaskBar::stopWait()
+{
+ waitTimer->stop();
+ waitIcon->setWaiting( false );
+}
+
+void TaskBar::resizeEvent( QResizeEvent *e )
+{
+ QHBox::resizeEvent( e );
+ calcMaxWindowRect();
+}
+
+void TaskBar::styleChange( QStyle &s )
+{
+ QHBox::styleChange( s );
+ calcMaxWindowRect();
+}
+
+void TaskBar::calcMaxWindowRect()
+{
+#ifdef Q_WS_QWS
+ QRect wr;
+ int displayWidth = qApp->desktop()->width();
+ QRect ir = inputMethods->inputRect();
+ if ( ir.isValid() ) {
+ wr.setCoords( 0, 0, displayWidth-1, ir.top()-1 );
+ } else {
+ wr.setCoords( 0, 0, displayWidth-1, y()-1 );
+ }
+
+#if QT_VERSION < 300
+ QWSServer::setMaxWindowRect( qt_screen->mapToDevice(wr,
+ QSize(qt_screen->width(),qt_screen->height()))
+ );
+#else
+ QWSServer::setMaxWindowRect( wr );
+#endif
+#endif
+}
+
+void TaskBar::receive( const QCString &msg, const QByteArray &data )
+{
+ QDataStream stream( data, IO_ReadOnly );
+ if ( msg == "message(QString)" ) {
+ QString text;
+ stream >> text;
+ setStatusMessage( text );
+ } else if ( msg == "hideInputMethod()" ) {
+ inputMethods->hideInputMethod();
+ } else if ( msg == "showInputMethod()" ) {
+ inputMethods->showInputMethod();
+ } else if ( msg == "reloadInputMethods()" ) {
+ inputMethods->loadInputMethods();
+ } else if ( msg == "reloadApplets()" ) {
+ sysTray->loadApplets();
+ } else if ( msg == "soundAlarm()" ) {
+ Desktop::soundAlarm();
+ }
+#ifdef CUSTOM_LEDS
+ else if ( msg == "setLed(int,bool)" ) {
+ int led, status;
+ stream >> led >> status;
+ CUSTOM_LEDS( led, status );
+ }
+#endif
+}
+
+QWidget *TaskBar::calibrate(bool)
+{
+#ifdef Q_WS_QWS
+ Calibrate *c = new Calibrate;
+ c->show();
+ return c;
+#else
+ return 0;
+#endif
+}
+
+void TaskBar::toggleNumLockState()
+{
+ if ( lockState ) lockState->toggleNumLockState();
+}
+
+void TaskBar::toggleCapsLockState()
+{
+ if ( lockState ) lockState->toggleCapsLockState();
+}
+
+void TaskBar::toggleSymbolInput()
+{
+ if ( inputMethods->currentShown() == "Unicode" ) {
+ inputMethods->hideInputMethod();
+ } else {
+ inputMethods->showInputMethod("Unicode");
+ }
+}
+
+bool TaskBar::recoverMemory()
+{
+ return mru->quitOldApps();
+}
+
diff --git a/core/launcher/taskbar.h b/core/launcher/taskbar.h
new file mode 100644
index 0000000..cdeb3c7
--- a/dev/null
+++ b/core/launcher/taskbar.h
@@ -0,0 +1,86 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef __TASKBAR_H__
+#define __TASKBAR_H__
+
+#ifdef QT_QWS_CUSTOM
+#include <qpe/custom.h>
+#endif
+
+#include <qhbox.h>
+
+class QLabel;
+class QTimer;
+class InputMethods;
+class Wait;
+class SysTray;
+class MRUList;
+class QWidgetStack;
+class QTimer;
+class QLabel;
+class StartMenu;
+class LockKeyState;
+
+class TaskBar : public QHBox {
+ Q_OBJECT
+public:
+ TaskBar();
+ ~TaskBar();
+
+ static QWidget *calibrate( bool );
+
+ bool recoverMemory();
+
+ StartMenu *startMenu() const { return sm; }
+public slots:
+ void startWait();
+ void stopWait(const QString&);
+ void stopWait();
+ void clearStatusBar();
+ void toggleNumLockState();
+ void toggleCapsLockState();
+ void toggleSymbolInput();
+
+protected:
+ void resizeEvent( QResizeEvent * );
+ void styleChange( QStyle & );
+ void setStatusMessage( const QString &text );
+
+private slots:
+ void calcMaxWindowRect();
+ void receive( const QCString &msg, const QByteArray &data );
+
+private:
+
+ QTimer *waitTimer;
+ Wait *waitIcon;
+ InputMethods *inputMethods;
+ SysTray *sysTray;
+ MRUList *mru;
+ QWidgetStack *stack;
+ QTimer *clearer;
+ QLabel *label;
+ LockKeyState* lockState;
+ StartMenu *sm;
+};
+
+
+#endif // __TASKBAR_H__
diff --git a/core/launcher/transferserver.cpp b/core/launcher/transferserver.cpp
new file mode 100644
index 0000000..87a49eb
--- a/dev/null
+++ b/core/launcher/transferserver.cpp
@@ -0,0 +1,1245 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#define _XOPEN_SOURCE
+#include <pwd.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#if defined(_OS_LINUX_)
+#include <shadow.h>
+#endif
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qdatastream.h>
+#include <qmessagebox.h>
+#include <qstringlist.h>
+#include <qfileinfo.h>
+#include <qregexp.h>
+//#include <qpe/qcopchannel_qws.h>
+#include <qpe/qprocess.h>
+#include <qpe/process.h>
+#include <qpe/config.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#include "transferserver.h"
+
+const int block_size = 51200;
+
+TransferServer::TransferServer( Q_UINT16 port, QObject *parent = 0,
+ const char* name = 0)
+ : QServerSocket( port, 1, parent, name )
+{
+ if ( !ok() )
+ qWarning( "Failed to bind to port %d", port );
+}
+
+TransferServer::~TransferServer()
+{
+
+}
+
+void TransferServer::newConnection( int socket )
+{
+ (void) new ServerPI( socket, this );
+}
+
+bool accessAuthorized(QHostAddress peeraddress)
+{
+ Config cfg("Security");
+ cfg.setGroup("Sync");
+ uint auth_peer = cfg.readNumEntry("auth_peer",0xc0a80100);
+ uint auth_peer_bits = cfg.readNumEntry("auth_peer_bits",24);
+ bool ok = (peeraddress.ip4Addr() & (((1<<auth_peer_bits)-1)<<(32-auth_peer_bits)))
+ == auth_peer;
+ /* Allows denial-of-service attack.
+ if ( !ok ) {
+ QMessageBox::warning(0,tr("Security"),
+ tr("<p>An attempt to access this device from %1 has been denied.")
+ .arg(peeraddress.toString()));
+ }
+ */
+ return ok;
+}
+
+ServerPI::ServerPI( int socket, QObject *parent = 0, const char* name = 0 )
+ : QSocket( parent, name ) , dtp( 0 ), serversocket( 0 ), waitsocket( 0 )
+{
+ state = Connected;
+
+ setSocket( socket );
+
+ peerport = peerPort();
+ peeraddress = peerAddress();
+
+#ifndef INSECURE
+ if ( !accessAuthorized(peeraddress) ) {
+ state = Forbidden;
+ startTimer( 0 );
+ } else
+#endif
+ {
+ connect( this, SIGNAL( readyRead() ), SLOT( read() ) );
+ connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
+
+ passiv = FALSE;
+ for( int i = 0; i < 4; i++ )
+ wait[i] = FALSE;
+
+ send( "220 Qtopia transfer service ready!" );
+ state = Wait_USER;
+
+ dtp = new ServerDTP( this );
+ connect( dtp, SIGNAL( completed() ), SLOT( dtpCompleted() ) );
+ connect( dtp, SIGNAL( failed() ), SLOT( dtpFailed() ) );
+ connect( dtp, SIGNAL( error( int ) ), SLOT( dtpError( int ) ) );
+
+
+ directory = QDir::currentDirPath();
+
+ static int p = 1024;
+
+ while ( !serversocket || !serversocket->ok() ) {
+ delete serversocket;
+ serversocket = new ServerSocket( ++p, this );
+ }
+ connect( serversocket, SIGNAL( newIncomming( int ) ),
+ SLOT( newConnection( int ) ) );
+ }
+}
+
+ServerPI::~ServerPI()
+{
+
+}
+
+void ServerPI::connectionClosed()
+{
+ // qDebug( "Debug: Connection closed" );
+ delete this;
+}
+
+void ServerPI::send( const QString& msg )
+{
+ QTextStream os( this );
+ os << msg << endl;
+ //qDebug( "Reply: %s", msg.latin1() );
+}
+
+void ServerPI::read()
+{
+ while ( canReadLine() )
+ process( readLine().stripWhiteSpace() );
+}
+
+bool ServerPI::checkUser( const QString& user )
+{
+ if ( user.isEmpty() ) return FALSE;
+
+ struct passwd *pw;
+ pw = getpwuid( geteuid() );
+ QString euser = QString::fromLocal8Bit( pw->pw_name );
+ return user == euser;
+}
+
+bool ServerPI::checkPassword( const QString& /* password */ )
+{
+ // ### HACK for testing on local host
+ return true;
+
+ /*
+ struct passwd *pw = 0;
+ struct spwd *spw = 0;
+
+ pw = getpwuid( geteuid() );
+ spw = getspnam( pw->pw_name );
+
+ QString cpwd = QString::fromLocal8Bit( pw->pw_passwd );
+ if ( cpwd == "x" && spw )
+ cpwd = QString::fromLocal8Bit( spw->sp_pwdp );
+
+ QString cpassword = QString::fromLocal8Bit( crypt( password.local8Bit(), cpwd.local8Bit() ) );
+ return cpwd == cpassword;
+*/
+}
+
+bool ServerPI::checkReadFile( const QString& file )
+{
+ QString filename;
+
+ if ( file[0] != "/" )
+ filename = directory.path() + "/" + file;
+ else
+ filename = file;
+
+ QFileInfo fi( filename );
+ return ( fi.exists() && fi.isReadable() );
+}
+
+bool ServerPI::checkWriteFile( const QString& file )
+{
+ QString filename;
+
+ if ( file[0] != "/" )
+ filename = directory.path() + "/" + file;
+ else
+ filename = file;
+
+ QFileInfo fi( filename );
+
+ if ( fi.exists() )
+ if ( !QFile( filename ).remove() )
+ return FALSE;
+ return TRUE;
+}
+
+void ServerPI::process( const QString& message )
+{
+ //qDebug( "Command: %s", message.latin1() );
+
+ // split message using "," as separator
+ QStringList msg = QStringList::split( " ", message );
+ if ( msg.isEmpty() ) return;
+
+ // command token
+ QString cmd = msg[0].upper();
+
+ // argument token
+ QString arg;
+ if ( msg.count() >= 2 )
+ arg = msg[1];
+
+ // full argument string
+ QString args;
+ if ( msg.count() >= 2 ) {
+ QStringList copy( msg );
+ // FIXME: for Qt3
+ // copy.pop_front()
+ copy.remove( copy.begin() );
+ args = copy.join( " " );
+ }
+
+ //qDebug( "args: %s", args.latin1() );
+
+ // we always respond to QUIT, regardless of state
+ if ( cmd == "QUIT" ) {
+ send( "211 Good bye!" );
+ delete this;
+ return;
+ }
+
+ // connected to client
+ if ( Connected == state )
+ return;
+
+ // waiting for user name
+ if ( Wait_USER == state ) {
+
+ if ( cmd != "USER" || msg.count() < 2 || !checkUser( arg ) ) {
+ send( "530 Please login with USER and PASS" );
+ return;
+ }
+ send( "331 User name ok, need password" );
+ state = Wait_PASS;
+ return;
+ }
+
+ // waiting for password
+ if ( Wait_PASS == state ) {
+
+ if ( cmd != "PASS" || !checkPassword( arg ) ) {
+ //if ( cmd != "PASS" || msg.count() < 2 || !checkPassword( arg ) ) {
+ send( "530 Please login with USER and PASS" );
+ return;
+ }
+ send( "230 User logged in, proceed" );
+ state = Ready;
+ return;
+ }
+
+ // ACCESS CONTROL COMMANDS
+
+
+ // account (ACCT)
+ if ( cmd == "ACCT" ) {
+ // even wu-ftp does not support it
+ send( "502 Command not implemented" );
+ }
+
+ // change working directory (CWD)
+ else if ( cmd == "CWD" ) {
+
+ if ( !args.isEmpty() ) {
+ if ( directory.cd( args, TRUE ) )
+ send( "250 Requested file action okay, completed" );
+ else
+ send( "550 Requested action not taken" );
+ }
+ else
+ send( "500 Syntax error, command unrecognized" );
+ }
+
+ // change to parent directory (CDUP)
+ else if ( cmd == "CDUP" ) {
+ if ( directory.cdUp() )
+ send( "250 Requested file action okay, completed" );
+ else
+ send( "550 Requested action not taken" );
+ }
+
+ // structure mount (SMNT)
+ else if ( cmd == "SMNT" ) {
+ // even wu-ftp does not support it
+ send( "502 Command not implemented" );
+ }
+
+ // reinitialize (REIN)
+ else if ( cmd == "REIN" ) {
+ // even wu-ftp does not support it
+ send( "502 Command not implemented" );
+ }
+
+
+ // TRANSFER PARAMETER COMMANDS
+
+
+ // data port (PORT)
+ else if ( cmd == "PORT" ) {
+ if ( parsePort( arg ) )
+ send( "200 Command okay" );
+ else
+ send( "500 Syntax error, command unrecognized" );
+ }
+
+ // passive (PASV)
+ else if ( cmd == "PASV" ) {
+ passiv = TRUE;
+ send( "227 Entering Passive Mode ("
+ + address().toString().replace( QRegExp( "\\." ), "," ) + ","
+ + QString::number( ( serversocket->port() ) >> 8 ) + ","
+ + QString::number( ( serversocket->port() ) & 0xFF ) +")" );
+ }
+
+ // representation type (TYPE)
+ else if ( cmd == "TYPE" ) {
+ if ( arg.upper() == "A" || arg.upper() == "I" )
+ send( "200 Command okay" );
+ else
+ send( "504 Command not implemented for that parameter" );
+ }
+
+ // file structure (STRU)
+ else if ( cmd == "STRU" ) {
+ if ( arg.upper() == "F" )
+ send( "200 Command okay" );
+ else
+ send( "504 Command not implemented for that parameter" );
+ }
+
+ // transfer mode (MODE)
+ else if ( cmd == "MODE" ) {
+ if ( arg.upper() == "S" )
+ send( "200 Command okay" );
+ else
+ send( "504 Command not implemented for that parameter" );
+ }
+
+
+ // FTP SERVICE COMMANDS
+
+
+ // retrieve (RETR)
+ else if ( cmd == "RETR" )
+ if ( !args.isEmpty() && checkReadFile( absFilePath( args ) )
+ || backupRestoreGzip( absFilePath( args ) ) ) {
+ send( "150 File status okay" );
+ sendFile( absFilePath( args ) );
+ }
+ else {
+ qDebug("550 Requested action not taken");
+ send( "550 Requested action not taken" );
+ }
+
+ // store (STOR)
+ else if ( cmd == "STOR" )
+ if ( !args.isEmpty() && checkWriteFile( absFilePath( args ) ) ) {
+ send( "150 File status okay" );
+ retrieveFile( absFilePath( args ) );
+ }
+ else
+ send( "550 Requested action not taken" );
+
+ // store unique (STOU)
+ else if ( cmd == "STOU" ) {
+ send( "502 Command not implemented" );
+ }
+
+ // append (APPE)
+ else if ( cmd == "APPE" ) {
+ send( "502 Command not implemented" );
+ }
+
+ // allocate (ALLO)
+ else if ( cmd == "ALLO" ) {
+ send( "200 Command okay" );
+ }
+
+ // restart (REST)
+ else if ( cmd == "REST" ) {
+ send( "502 Command not implemented" );
+ }
+
+ // rename from (RNFR)
+ else if ( cmd == "RNFR" ) {
+ renameFrom = QString::null;
+ if ( args.isEmpty() )
+ send( "500 Syntax error, command unrecognized" );
+ else {
+ QFile file( absFilePath( args ) );
+ if ( file.exists() ) {
+ send( "350 File exists, ready for destination name" );
+ renameFrom = absFilePath( args );
+ }
+ else
+ send( "550 Requested action not taken" );
+ }
+ }
+
+ // rename to (RNTO)
+ else if ( cmd == "RNTO" ) {
+ if ( lastCommand != "RNFR" )
+ send( "503 Bad sequence of commands" );
+ else if ( args.isEmpty() )
+ send( "500 Syntax error, command unrecognized" );
+ else {
+ QDir dir( absFilePath( args ) );
+ if ( dir.rename( renameFrom, absFilePath( args ), TRUE ) )
+ send( "250 Requested file action okay, completed." );
+ else
+ send( "550 Requested action not taken" );
+ }
+ }
+
+ // abort (ABOR)
+ else if ( cmd.contains( "ABOR" ) ) {
+ dtp->close();
+ if ( dtp->dtpMode() != ServerDTP::Idle )
+ send( "426 Connection closed; transfer aborted" );
+ else
+ send( "226 Closing data connection" );
+ }
+
+ // delete (DELE)
+ else if ( cmd == "DELE" ) {
+ if ( args.isEmpty() )
+ send( "500 Syntax error, command unrecognized" );
+ else {
+ QFile file( absFilePath( args ) ) ;
+ if ( file.remove() )
+ send( "250 Requested file action okay, completed" );
+ else
+ send( "550 Requested action not taken" );
+ }
+ }
+
+ // remove directory (RMD)
+ else if ( cmd == "RMD" ) {
+ if ( args.isEmpty() )
+ send( "500 Syntax error, command unrecognized" );
+ else {
+ QDir dir;
+ if ( dir.rmdir( absFilePath( args ), TRUE ) )
+ send( "250 Requested file action okay, completed" );
+ else
+ send( "550 Requested action not taken" );
+ }
+ }
+
+ // make directory (MKD)
+ else if ( cmd == "MKD" ) {
+ if ( args.isEmpty() ) {
+ qDebug(" Error: no arg");
+ send( "500 Syntax error, command unrecognized" );
+ }
+ else {
+ QDir dir;
+ if ( dir.mkdir( absFilePath( args ), TRUE ) )
+ send( "250 Requested file action okay, completed." );
+ else
+ send( "550 Requested action not taken" );
+ }
+ }
+
+ // print working directory (PWD)
+ else if ( cmd == "PWD" ) {
+ send( "257 \"" + directory.path() +"\"" );
+ }
+
+ // list (LIST)
+ else if ( cmd == "LIST" ) {
+ if ( sendList( absFilePath( args ) ) )
+ send( "150 File status okay" );
+ else
+ send( "500 Syntax error, command unrecognized" );
+ }
+
+ // size (SIZE)
+ else if ( cmd == "SIZE" ) {
+ QString filePath = absFilePath( args );
+ QFileInfo fi( filePath );
+ bool gzipfile = backupRestoreGzip( filePath );
+ if ( !fi.exists() && !gzipfile )
+ send( "500 Syntax error, command unrecognized" );
+ else {
+ if ( !gzipfile )
+ send( "213 " + QString::number( fi.size() ) );
+ else {
+ Process duproc( QString("du") );
+ duproc.addArgument("-s");
+ QString in, out;
+ if ( !duproc.exec(in, out) ) {
+ qDebug("du process failed; just sending back 1K");
+ send( "213 1024");
+ }
+ else {
+ QString size = out.left( out.find("\t") );
+ int guess = size.toInt()/5;
+ if ( filePath.contains("doc") )
+ guess *= 1000;
+ qDebug("sending back gzip guess of %d", guess);
+ send( "213 " + QString::number(guess) );
+ }
+ }
+ }
+ }
+ // name list (NLST)
+ else if ( cmd == "NLST" ) {
+ send( "502 Command not implemented" );
+ }
+
+ // site parameters (SITE)
+ else if ( cmd == "SITE" ) {
+ send( "502 Command not implemented" );
+ }
+
+ // system (SYST)
+ else if ( cmd == "SYST" ) {
+ send( "215 UNIX Type: L8" );
+ }
+
+ // status (STAT)
+ else if ( cmd == "STAT" ) {
+ send( "502 Command not implemented" );
+ }
+
+ // help (HELP )
+ else if ( cmd == "HELP" ) {
+ send( "502 Command not implemented" );
+ }
+
+ // noop (NOOP)
+ else if ( cmd == "NOOP" ) {
+ send( "200 Command okay" );
+ }
+
+ // not implemented
+ else
+ send( "502 Command not implemented" );
+
+ lastCommand = cmd;
+}
+
+bool ServerPI::backupRestoreGzip( const QString &file )
+{
+ return (file.find( "backup" ) != -1 &&
+ file.findRev( ".tgz" ) == (int)file.length()-4 );
+}
+
+bool ServerPI::backupRestoreGzip( const QString &file, QStringList &targets )
+{
+ if ( file.find( "backup" ) != -1 &&
+ file.findRev( ".tgz" ) == (int)file.length()-4 ) {
+ QFileInfo info( file );
+ targets = info.dirPath( TRUE );
+ qDebug("ServerPI::backupRestoreGzip for %s = %s", file.latin1(),
+ targets.join(" ").latin1() );
+ return true;
+ }
+ return false;
+}
+
+void ServerPI::sendFile( const QString& file )
+{
+ if ( passiv ) {
+ wait[SendFile] = TRUE;
+ waitfile = file;
+ if ( waitsocket )
+ newConnection( waitsocket );
+ }
+ else {
+ QStringList targets;
+ if ( backupRestoreGzip( file, targets ) )
+ dtp->sendGzipFile( file, targets, peeraddress, peerport );
+ else dtp->sendFile( file, peeraddress, peerport );
+ }
+}
+
+void ServerPI::retrieveFile( const QString& file )
+{
+ if ( passiv ) {
+ wait[RetrieveFile] = TRUE;
+ waitfile = file;
+ if ( waitsocket )
+ newConnection( waitsocket );
+ }
+ else {
+ QStringList targets;
+ if ( backupRestoreGzip( file, targets ) )
+ dtp->retrieveGzipFile( file, peeraddress, peerport );
+ else
+ dtp->retrieveFile( file, peeraddress, peerport );
+ }
+}
+
+bool ServerPI::parsePort( const QString& pp )
+{
+ QStringList p = QStringList::split( ",", pp );
+ if ( p.count() != 6 ) return FALSE;
+
+ // h1,h2,h3,h4,p1,p2
+ peeraddress = QHostAddress( ( p[0].toInt() << 24 ) + ( p[1].toInt() << 16 ) +
+ ( p[2].toInt() << 8 ) + p[3].toInt() );
+ peerport = ( p[4].toInt() << 8 ) + p[5].toInt();
+ return TRUE;
+}
+
+void ServerPI::dtpCompleted()
+{
+ dtp->close();
+ waitsocket = 0;
+ send( "226 Closing data connection, file transfer successful" );
+}
+
+void ServerPI::dtpFailed()
+{
+ dtp->close();
+ waitsocket = 0;
+ send( "451 Requested action aborted: local error in processing" );
+}
+
+void ServerPI::dtpError( int )
+{
+ dtp->close();
+ waitsocket = 0;
+ send( "451 Requested action aborted: local error in processing" );
+}
+
+bool ServerPI::sendList( const QString& arg )
+{
+ QByteArray listing;
+ QBuffer buffer( listing );
+
+ if ( !buffer.open( IO_WriteOnly ) )
+ return FALSE;
+
+ QTextStream ts( &buffer );
+ QString fn = arg;
+
+ if ( fn.isEmpty() )
+ fn = directory.path();
+
+ QFileInfo fi( fn );
+ if ( !fi.exists() ) return FALSE;
+
+ // return file listing
+ if ( fi.isFile() ) {
+ ts << fileListing( &fi ) << endl;
+ }
+
+ // return directory listing
+ else if ( fi.isDir() ) {
+ QDir dir( fn );
+ const QFileInfoList *list = dir.entryInfoList( QDir::All | QDir::Hidden );
+
+ QFileInfoListIterator it( *list );
+ QFileInfo *info;
+
+ unsigned long total = 0;
+ while ( ( info = it.current() ) ) {
+ if ( info->fileName() != "." && info->fileName() != ".." )
+ total += info->size();
+ ++it;
+ }
+
+ ts << "total " << QString::number( total / 1024 ) << endl;
+
+ it.toFirst();
+ while ( ( info = it.current() ) ) {
+ if ( info->fileName() == "." || info->fileName() == ".." ) {
+ ++it;
+ continue;
+ }
+ ts << fileListing( info ) << endl;
+ ++it;
+ }
+ }
+
+ if ( passiv ) {
+ waitarray = buffer.buffer();
+ wait[SendByteArray] = TRUE;
+ if ( waitsocket )
+ newConnection( waitsocket );
+ }
+ else
+ dtp->sendByteArray( buffer.buffer(), peeraddress, peerport );
+ return TRUE;
+}
+
+QString ServerPI::fileListing( QFileInfo *info )
+{
+ if ( !info ) return QString::null;
+ QString s;
+
+ // type char
+ if ( info->isDir() )
+ s += "d";
+ else if ( info->isSymLink() )
+ s += "l";
+ else
+ s += "-";
+
+ // permisson string
+ s += permissionString( info ) + " ";
+
+ // number of hardlinks
+ int subdirs = 1;
+
+ if ( info->isDir() )
+ subdirs = 2;
+ // FIXME : this is to slow
+ //if ( info->isDir() )
+ //subdirs = QDir( info->absFilePath() ).entryList( QDir::Dirs ).count();
+
+ s += QString::number( subdirs ).rightJustify( 3, ' ', TRUE ) + " ";
+
+ // owner
+ s += info->owner().leftJustify( 8, ' ', TRUE ) + " ";
+
+ // group
+ s += info->group().leftJustify( 8, ' ', TRUE ) + " ";
+
+ // file size in bytes
+ s += QString::number( info->size() ).rightJustify( 9, ' ', TRUE ) + " ";
+
+ // last modified date
+ QDate date = info->lastModified().date();
+ QTime time = info->lastModified().time();
+ s += date.monthName( date.month() ) + " "
+ + QString::number( date.day() ).rightJustify( 2, ' ', TRUE ) + " "
+ + QString::number( time.hour() ).rightJustify( 2, '0', TRUE ) + ":"
+ + QString::number( time.minute() ).rightJustify( 2,'0', TRUE ) + " ";
+
+ // file name
+ s += info->fileName();
+
+ return s;
+}
+
+QString ServerPI::permissionString( QFileInfo *info )
+{
+ if ( !info ) return QString( "---------" );
+ QString s;
+
+ // user
+ if ( info->permission( QFileInfo::ReadUser ) ) s += "r";
+ else s += "-";
+ if ( info->permission( QFileInfo::WriteUser ) ) s += "w";
+ else s += "-";
+ if ( info->permission( QFileInfo::ExeUser ) ) s += "x";
+ else s += "-";
+
+ // group
+ if ( info->permission( QFileInfo::ReadGroup ) ) s += "r";
+ else s += "-";
+ if ( info->permission( QFileInfo::WriteGroup ) )s += "w";
+ else s += "-";
+ if ( info->permission( QFileInfo::ExeGroup ) ) s += "x";
+ else s += "-";
+
+ // exec
+ if ( info->permission( QFileInfo::ReadOther ) ) s += "r";
+ else s += "-";
+ if ( info->permission( QFileInfo::WriteOther ) ) s += "w";
+ else s += "-";
+ if ( info->permission( QFileInfo::ExeOther ) ) s += "x";
+ else s += "-";
+
+ return s;
+}
+
+void ServerPI::newConnection( int socket )
+{
+ //qDebug( "New incomming connection" );
+
+ if ( !passiv ) return;
+
+ if ( wait[SendFile] ) {
+ QStringList targets;
+ if ( backupRestoreGzip( waitfile, targets ) )
+ dtp->sendGzipFile( waitfile, targets );
+ else
+ dtp->sendFile( waitfile );
+ dtp->setSocket( socket );
+ }
+ else if ( wait[RetrieveFile] ) {
+ qDebug("check retrieve file");
+ if ( backupRestoreGzip( waitfile ) )
+ dtp->retrieveGzipFile( waitfile );
+ else
+ dtp->retrieveFile( waitfile );
+ dtp->setSocket( socket );
+ }
+ else if ( wait[SendByteArray] ) {
+ dtp->sendByteArray( waitarray );
+ dtp->setSocket( socket );
+ }
+ else if ( wait[RetrieveByteArray] ) {
+ qDebug("retrieve byte array");
+ dtp->retrieveByteArray();
+ dtp->setSocket( socket );
+ }
+ else
+ waitsocket = socket;
+
+ for( int i = 0; i < 4; i++ )
+ wait[i] = FALSE;
+}
+
+QString ServerPI::absFilePath( const QString& file )
+{
+ if ( file.isEmpty() ) return file;
+
+ QString filepath( file );
+ if ( file[0] != "/" )
+ filepath = directory.path() + "/" + file;
+
+ return filepath;
+}
+
+
+void ServerPI::timerEvent( QTimerEvent * )
+{
+ connectionClosed();
+}
+
+
+ServerDTP::ServerDTP( QObject *parent = 0, const char* name = 0)
+ : QSocket( parent, name ), mode( Idle ), createTargzProc( 0 ),
+retrieveTargzProc( 0 ), gzipProc( 0 )
+{
+
+ connect( this, SIGNAL( connected() ), SLOT( connected() ) );
+ connect( this, SIGNAL( connectionClosed() ), SLOT( connectionClosed() ) );
+ connect( this, SIGNAL( bytesWritten( int ) ), SLOT( bytesWritten( int ) ) );
+ connect( this, SIGNAL( readyRead() ), SLOT( readyRead() ) );
+
+ gzipProc = new QProcess( this, "gzipProc" );
+ gzipProc->setCommunication( QProcess::Stdin | QProcess::Stdout );
+
+ createTargzProc = new QProcess( QString("tar"), this, "createTargzProc");
+ createTargzProc->setCommunication( QProcess::Stdout );
+ createTargzProc->setWorkingDirectory( QDir::rootDirPath() );
+ connect( createTargzProc, SIGNAL( processExited() ), SLOT( targzDone() ) );
+
+ QStringList args = "tar";
+ args += "-xv";
+ retrieveTargzProc = new QProcess( args, this, "retrieveTargzProc" );
+ retrieveTargzProc->setCommunication( QProcess::Stdin );
+ retrieveTargzProc->setWorkingDirectory( QDir::rootDirPath() );
+ connect( retrieveTargzProc, SIGNAL( processExited() ),
+ SIGNAL( completed() ) );
+ connect( retrieveTargzProc, SIGNAL( processExited() ),
+ SLOT( extractTarDone() ) );
+}
+
+ServerDTP::~ServerDTP()
+{
+ buf.close();
+ file.close();
+ createTargzProc->kill();
+}
+
+void ServerDTP::extractTarDone()
+{
+ qDebug("extract done");
+ QCopEnvelope e( "QPE/Desktop", "restoreDone(QString)" );
+ e << file.name();
+}
+
+void ServerDTP::connected()
+{
+ // send file mode
+ switch ( mode ) {
+ case SendFile :
+ if ( !file.exists() || !file.open( IO_ReadOnly) ) {
+ emit failed();
+ mode = Idle;
+ return;
+ }
+
+ //qDebug( "Debug: Sending file '%s'", file.name().latin1() );
+
+ bytes_written = 0;
+ if ( file.size() == 0 ) {
+ //make sure it doesn't hang on empty files
+ file.close();
+ emit completed();
+ mode = Idle;
+ } else {
+
+ if( !file.atEnd() ) {
+ QCString s;
+ s.resize( block_size );
+ int bytes = file.readBlock( s.data(), block_size );
+ writeBlock( s.data(), bytes );
+ }
+ }
+ break;
+ case SendGzipFile:
+ if ( createTargzProc->isRunning() ) {
+ // SHOULDN'T GET HERE, BUT DOING A SAFETY CHECK ANYWAY
+ qWarning("Previous tar --gzip process is still running; killing it...");
+ createTargzProc->kill();
+ }
+
+ bytes_written = 0;
+ qDebug("==>start send tar process");
+ if ( !createTargzProc->start() )
+ qWarning("Error starting %s or %s",
+ createTargzProc->arguments().join(" ").latin1(),
+ gzipProc->arguments().join(" ").latin1() );
+ break;
+ case SendBuffer:
+ if ( !buf.open( IO_ReadOnly) ) {
+ emit failed();
+ mode = Idle;
+ return;
+ }
+
+ // qDebug( "Debug: Sending byte array" );
+ bytes_written = 0;
+ while( !buf.atEnd() )
+ putch( buf.getch() );
+ buf.close();
+ break;
+ case RetrieveFile:
+ // retrieve file mode
+ if ( file.exists() && !file.remove() ) {
+ emit failed();
+ mode = Idle;
+ return;
+ }
+
+ if ( !file.open( IO_WriteOnly) ) {
+ emit failed();
+ mode = Idle;
+ return;
+ }
+ // qDebug( "Debug: Retrieving file %s", file.name().latin1() );
+ break;
+ case RetrieveGzipFile:
+ qDebug("=-> starting tar process to receive .tgz file");
+ break;
+ case RetrieveBuffer:
+ // retrieve buffer mode
+ if ( !buf.open( IO_WriteOnly) ) {
+ emit failed();
+ mode = Idle;
+ return;
+ }
+ // qDebug( "Debug: Retrieving byte array" );
+ break;
+ case Idle:
+ qDebug("connection established but mode set to Idle; BUG!");
+ break;
+ }
+}
+
+void ServerDTP::connectionClosed()
+{
+ //qDebug( "Debug: Data connection closed %ld bytes written", bytes_written );
+
+ // send file mode
+ if ( SendFile == mode ) {
+ if ( bytes_written == file.size() )
+ emit completed();
+ else
+ emit failed();
+ }
+
+ // send buffer mode
+ else if ( SendBuffer == mode ) {
+ if ( bytes_written == buf.size() )
+ emit completed();
+ else
+ emit failed();
+ }
+
+ // retrieve file mode
+ else if ( RetrieveFile == mode ) {
+ file.close();
+ emit completed();
+ }
+
+ else if ( RetrieveGzipFile == mode ) {
+ qDebug("Done writing ungzip file; closing input");
+ gzipProc->flushStdin();
+ gzipProc->closeStdin();
+ }
+
+ // retrieve buffer mode
+ else if ( RetrieveBuffer == mode ) {
+ buf.close();
+ emit completed();
+ }
+
+ mode = Idle;
+}
+
+void ServerDTP::bytesWritten( int bytes )
+{
+ bytes_written += bytes;
+
+ // send file mode
+ if ( SendFile == mode ) {
+
+ if ( bytes_written == file.size() ) {
+ // qDebug( "Debug: Sending complete: %d bytes", file.size() );
+ file.close();
+ emit completed();
+ mode = Idle;
+ }
+ else if( !file.atEnd() ) {
+ QCString s;
+ s.resize( block_size );
+ int bytes = file.readBlock( s.data(), block_size );
+ writeBlock( s.data(), bytes );
+ }
+ }
+
+ // send buffer mode
+ if ( SendBuffer == mode ) {
+
+ if ( bytes_written == buf.size() ) {
+ // qDebug( "Debug: Sending complete: %d bytes", buf.size() );
+ emit completed();
+ mode = Idle;
+ }
+ }
+}
+
+void ServerDTP::readyRead()
+{
+ // retrieve file mode
+ if ( RetrieveFile == mode ) {
+ QCString s;
+ s.resize( bytesAvailable() );
+ readBlock( s.data(), bytesAvailable() );
+ file.writeBlock( s.data(), s.size() );
+ }
+ else if ( RetrieveGzipFile == mode ) {
+ if ( !gzipProc->isRunning() )
+ gzipProc->start();
+
+ QByteArray s;
+ s.resize( bytesAvailable() );
+ readBlock( s.data(), bytesAvailable() );
+ gzipProc->writeToStdin( s );
+ qDebug("wrote %d bytes to ungzip ", s.size() );
+ }
+ // retrieve buffer mode
+ else if ( RetrieveBuffer == mode ) {
+ QCString s;
+ s.resize( bytesAvailable() );
+ readBlock( s.data(), bytesAvailable() );
+ buf.writeBlock( s.data(), s.size() );
+ }
+}
+
+void ServerDTP::writeTargzBlock()
+{
+ QByteArray block = gzipProc->readStdout();
+ writeBlock( block.data(), block.size() );
+ qDebug("writeTargzBlock %d", block.size());
+ if ( !createTargzProc->isRunning() ) {
+ qDebug("tar and gzip done");
+ emit completed();
+ mode = Idle;
+ disconnect( gzipProc, SIGNAL( readyReadStdout() ),
+ this, SLOT( writeTargzBlock() ) );
+ }
+}
+
+void ServerDTP::targzDone()
+{
+ //qDebug("targz done");
+ disconnect( createTargzProc, SIGNAL( readyReadStdout() ),
+ this, SLOT( gzipTarBlock() ) );
+ gzipProc->closeStdin();
+}
+
+void ServerDTP::gzipTarBlock()
+{
+ //qDebug("gzipTarBlock");
+ if ( !gzipProc->isRunning() ) {
+ //qDebug("auto start gzip proc");
+ gzipProc->start();
+ }
+ gzipProc->writeToStdin( createTargzProc->readStdout() );
+}
+
+void ServerDTP::sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port )
+{
+ file.setName( fn );
+ mode = SendFile;
+ connectToHost( host.toString(), port );
+}
+
+void ServerDTP::sendFile( const QString fn )
+{
+ file.setName( fn );
+ mode = SendFile;
+}
+
+void ServerDTP::sendGzipFile( const QString &fn,
+ const QStringList &archiveTargets,
+ const QHostAddress& host, Q_UINT16 port )
+{
+ sendGzipFile( fn, archiveTargets );
+ connectToHost( host.toString(), port );
+}
+
+void ServerDTP::sendGzipFile( const QString &fn,
+ const QStringList &archiveTargets )
+{
+ mode = SendGzipFile;
+ file.setName( fn );
+
+ QStringList args = "tar";
+ args += "-cv";
+ args += archiveTargets;
+ qDebug("sendGzipFile %s", args.join(" ").latin1() );
+ createTargzProc->setArguments( args );
+ connect( createTargzProc,
+ SIGNAL( readyReadStdout() ), SLOT( gzipTarBlock() ) );
+
+ gzipProc->setArguments( "gzip" );
+ connect( gzipProc, SIGNAL( readyReadStdout() ),
+ SLOT( writeTargzBlock() ) );
+}
+
+void ServerDTP::gunzipDone()
+{
+ qDebug("gunzipDone");
+ disconnect( gzipProc, SIGNAL( processExited() ),
+ this, SLOT( gunzipDone() ) );
+ retrieveTargzProc->closeStdin();
+ disconnect( gzipProc, SIGNAL( readyReadStdout() ),
+ this, SLOT( tarExtractBlock() ) );
+}
+
+void ServerDTP::tarExtractBlock()
+{
+ qDebug("ungzipTarBlock");
+ if ( !retrieveTargzProc->isRunning() ) {
+ qDebug("auto start ungzip proc");
+ if ( !retrieveTargzProc->start() )
+ qWarning(" failed to start tar -x process");
+ }
+ retrieveTargzProc->writeToStdin( gzipProc->readStdout() );
+}
+
+
+void ServerDTP::retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port )
+{
+ file.setName( fn );
+ mode = RetrieveFile;
+ connectToHost( host.toString(), port );
+}
+
+void ServerDTP::retrieveFile( const QString fn )
+{
+ file.setName( fn );
+ mode = RetrieveFile;
+}
+
+void ServerDTP::retrieveGzipFile( const QString &fn )
+{
+ qDebug("retrieveGzipFile %s", fn.latin1());
+ file.setName( fn );
+ mode = RetrieveGzipFile;
+
+ gzipProc->setArguments( "gunzip" );
+ connect( gzipProc, SIGNAL( readyReadStdout() ),
+ SLOT( tarExtractBlock() ) );
+ connect( gzipProc, SIGNAL( processExited() ),
+ SLOT( gunzipDone() ) );
+}
+
+void ServerDTP::retrieveGzipFile( const QString &fn, const QHostAddress& host, Q_UINT16 port )
+{
+ retrieveGzipFile( fn );
+ connectToHost( host.toString(), port );
+}
+
+void ServerDTP::sendByteArray( const QByteArray& array, const QHostAddress& host, Q_UINT16 port )
+{
+ buf.setBuffer( array );
+ mode = SendBuffer;
+ connectToHost( host.toString(), port );
+}
+
+void ServerDTP::sendByteArray( const QByteArray& array )
+{
+ buf.setBuffer( array );
+ mode = SendBuffer;
+}
+
+void ServerDTP::retrieveByteArray( const QHostAddress& host, Q_UINT16 port )
+{
+ buf.setBuffer( QByteArray() );
+ mode = RetrieveBuffer;
+ connectToHost( host.toString(), port );
+}
+
+void ServerDTP::retrieveByteArray()
+{
+ buf.setBuffer( QByteArray() );
+ mode = RetrieveBuffer;
+}
+
+void ServerDTP::setSocket( int socket )
+{
+ QSocket::setSocket( socket );
+ connected();
+}
+
diff --git a/core/launcher/transferserver.h b/core/launcher/transferserver.h
new file mode 100644
index 0000000..076e460
--- a/dev/null
+++ b/core/launcher/transferserver.h
@@ -0,0 +1,168 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qserversocket.h>
+#include <qsocket.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qbuffer.h>
+
+class QFileInfo;
+class QProcess;
+class TransferServer : public QServerSocket
+{
+ Q_OBJECT
+
+public:
+ TransferServer( Q_UINT16 port, QObject *parent = 0, const char* name = 0 );
+ virtual ~TransferServer();
+
+ void newConnection( int socket );
+};
+
+
+class ServerDTP : public QSocket
+{
+ Q_OBJECT
+
+public:
+ ServerDTP( QObject *parent = 0, const char* name = 0 );
+ ~ServerDTP();
+
+ enum Mode{ Idle = 0, SendFile, SendGzipFile, SendBuffer,
+ RetrieveFile, RetrieveGzipFile, RetrieveBuffer };
+
+ void sendFile( const QString fn );
+ void sendFile( const QString fn, const QHostAddress& host, Q_UINT16 port );
+ void sendGzipFile( const QString &fn, const QStringList &archiveTargets );
+ void sendGzipFile( const QString &fn, const QStringList &archiveTargets,
+ const QHostAddress& host, Q_UINT16 port );
+ void sendByteArray( const QByteArray& array );
+ void sendByteArray( const QByteArray& array, const QHostAddress& host, Q_UINT16 port );
+
+ void retrieveFile( const QString fn );
+ void retrieveFile( const QString fn, const QHostAddress& host, Q_UINT16 port );
+ void retrieveGzipFile( const QString &fn );
+ void retrieveGzipFile( const QString &fn, const QHostAddress& host, Q_UINT16 port );
+ void retrieveByteArray();
+ void retrieveByteArray( const QHostAddress& host, Q_UINT16 port );
+
+ Mode dtpMode() { return mode; }
+ QByteArray buffer() { return buf.buffer(); }
+
+ void setSocket( int socket );
+
+signals:
+ void completed();
+ void failed();
+
+private slots:
+ void connectionClosed();
+ void connected();
+ void bytesWritten( int bytes );
+ void readyRead();
+ void writeTargzBlock();
+ void targzDone();
+
+ void gzipTarBlock();
+ void tarExtractBlock();
+ void gunzipDone();
+ void extractTarDone();
+
+private:
+
+ unsigned long bytes_written;
+ Mode mode;
+ QFile file;
+ QBuffer buf;
+ QProcess *createTargzProc;
+ QProcess *retrieveTargzProc;
+ QProcess *gzipProc;
+};
+
+class ServerSocket : public QServerSocket
+{
+ Q_OBJECT
+
+public:
+ ServerSocket( Q_UINT16 port, QObject *parent = 0, const char* name = 0 )
+ : QServerSocket( port, 1, parent, name ) {}
+
+ void newConnection( int socket ) { emit newIncomming( socket ); }
+signals:
+ void newIncomming( int socket );
+};
+
+class ServerPI : public QSocket
+{
+ Q_OBJECT
+
+ enum State { Connected, Wait_USER, Wait_PASS, Ready, Forbidden };
+ enum Transfer { SendFile = 0, RetrieveFile = 1, SendByteArray = 2, RetrieveByteArray = 3 };
+
+public:
+ ServerPI( int socket, QObject *parent = 0, const char* name = 0 );
+ virtual ~ServerPI();
+
+protected slots:
+ void read();
+ void send( const QString& msg );
+ void process( const QString& command );
+ void connectionClosed();
+ void dtpCompleted();
+ void dtpFailed();
+ void dtpError( int );
+ void newConnection( int socket );
+
+protected:
+ bool checkUser( const QString& user );
+ bool checkPassword( const QString& pw );
+ bool checkReadFile( const QString& file );
+ bool checkWriteFile( const QString& file );
+ bool parsePort( const QString& pw );
+ bool backupRestoreGzip( const QString &file, QStringList &targets );
+ bool backupRestoreGzip( const QString &file );
+
+ bool sendList( const QString& arg );
+ void sendFile( const QString& file );
+ void retrieveFile( const QString& file );
+
+ QString permissionString( QFileInfo *info );
+ QString fileListing( QFileInfo *info );
+ QString absFilePath( const QString& file );
+
+ void timerEvent( QTimerEvent *e );
+
+private:
+ State state;
+ Q_UINT16 peerport;
+ QHostAddress peeraddress;
+ bool passiv;
+ bool wait[4];
+ ServerDTP *dtp;
+ ServerSocket *serversocket;
+ QString waitfile;
+ QDir directory;
+ QByteArray waitarray;
+ QString renameFrom;
+ QString lastCommand;
+ int waitsocket;
+};
+
+bool accessAuthorized(QHostAddress peeraddress);
diff --git a/core/launcher/wait.cpp b/core/launcher/wait.cpp
new file mode 100644
index 0000000..059e6f1
--- a/dev/null
+++ b/core/launcher/wait.cpp
@@ -0,0 +1,64 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "wait.h"
+
+#include <qpe/resource.h>
+
+#include <qwidget.h>
+#include <qpixmap.h>
+#include <qpainter.h>
+
+
+Wait *lastWaitObject = NULL;
+
+
+Wait::Wait( QWidget *parent ) : QWidget( parent ),
+ pm( Resource::loadPixmap( "wait" ) ), waiting( FALSE )
+{
+ setFixedSize( pm.size() );
+ lastWaitObject = this;
+ hide();
+}
+
+
+Wait *Wait::getWaitObject()
+{
+ return lastWaitObject;
+}
+
+
+void Wait::setWaiting( bool w )
+{
+ waiting = w;
+ if ( w )
+ show();
+ else
+ hide();
+}
+
+
+void Wait::paintEvent( QPaintEvent * )
+{
+ QPainter p( this );
+ p.drawPixmap( 0, 0, pm );
+}
+
+
diff --git a/core/launcher/wait.h b/core/launcher/wait.h
new file mode 100644
index 0000000..519b654
--- a/dev/null
+++ b/core/launcher/wait.h
@@ -0,0 +1,45 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef __WAIT_H__
+#define __WAIT_H__
+
+#include <qpe/resource.h>
+
+#include <qwidget.h>
+#include <qpixmap.h>
+#include <qpainter.h>
+
+
+class Wait : public QWidget
+{
+public:
+ Wait( QWidget *parent );
+ void setWaiting( bool w );
+ void paintEvent( QPaintEvent * );
+ static Wait *getWaitObject();
+private:
+ QPixmap pm;
+ bool waiting;
+};
+
+
+#endif // __WAIT_H__
+
diff --git a/core/multimedia/opieplayer/.cvsignore b/core/multimedia/opieplayer/.cvsignore
new file mode 100644
index 0000000..6fe2396
--- a/dev/null
+++ b/core/multimedia/opieplayer/.cvsignore
@@ -0,0 +1,2 @@
+moc_*
+Makefile
diff --git a/core/multimedia/opieplayer/Makefile.in b/core/multimedia/opieplayer/Makefile.in
new file mode 100644
index 0000000..5fca66e
--- a/dev/null
+++ b/core/multimedia/opieplayer/Makefile.in
@@ -0,0 +1,280 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) -DQCONFIG=\"qpe\"
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS) -DQCONFIG=\"qpe\"
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe -lpthread $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = mpegplayer
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = loopcontrol.h \
+ mediaplayerplugininterface.h \
+ playlistselection.h \
+ mediaplayerstate.h \
+ videowidget.h \
+ audiowidget.h \
+ playlistwidget.h \
+ mediaplayer.h \
+ audiodevice.h
+SOURCES = main.cpp \
+ loopcontrol.cpp \
+ playlistselection.cpp \
+ mediaplayerstate.cpp \
+ videowidget.cpp \
+ audiowidget.cpp \
+ playlistwidget.cpp \
+ mediaplayer.cpp \
+ audiodevice.cpp
+OBJECTS = main.o \
+ loopcontrol.o \
+ playlistselection.o \
+ mediaplayerstate.o \
+ videowidget.o \
+ audiowidget.o \
+ playlistwidget.o \
+ mediaplayer.o \
+ audiodevice.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_loopcontrol.cpp \
+ moc_playlistselection.cpp \
+ moc_mediaplayerstate.cpp \
+ moc_videowidget.cpp \
+ moc_audiowidget.cpp \
+ moc_playlistwidget.cpp \
+ moc_mediaplayer.cpp \
+ moc_audiodevice.cpp
+OBJMOC = moc_loopcontrol.o \
+ moc_playlistselection.o \
+ moc_mediaplayerstate.o \
+ moc_videowidget.o \
+ moc_audiowidget.o \
+ moc_playlistwidget.o \
+ moc_mediaplayer.o \
+ moc_audiodevice.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake mpegplayer.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ mediaplayerstate.h \
+ playlistwidget.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ audiowidget.h \
+ videowidget.h \
+ loopcontrol.h \
+ mediaplayer.h \
+ $(QPEDIR)/include/qpe/qlibrary.h \
+ $(QPEDIR)/include/qpe/qcom.h \
+ $(QPEDIR)/include/qpe/quuid.h \
+ mediaplayerplugininterface.h
+
+loopcontrol.o: loopcontrol.cpp \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
+ loopcontrol.h \
+ videowidget.h \
+ audiodevice.h \
+ mediaplayerplugininterface.h \
+ $(QPEDIR)/include/qpe/qcom.h \
+ $(QPEDIR)/include/qpe/quuid.h \
+ mediaplayerstate.h
+
+playlistselection.o: playlistselection.cpp \
+ $(QPEDIR)/include/qpe/applnk.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ playlistselection.h
+
+mediaplayerstate.o: mediaplayerstate.cpp \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/qlibrary.h \
+ $(QPEDIR)/include/qpe/qcom.h \
+ $(QPEDIR)/include/qpe/quuid.h \
+ $(QPEDIR)/include/qpe/config.h \
+ mediaplayerplugininterface.h \
+ mediaplayerstate.h \
+ libmad/libmadpluginimpl.h \
+ libmpeg3/libmpeg3pluginimpl.h \
+ wavplugin/wavpluginimpl.h
+
+videowidget.o: videowidget.cpp \
+ $(QPEDIR)/include/qpe/resource.h \
+ videowidget.h \
+ mediaplayerplugininterface.h \
+ $(QPEDIR)/include/qpe/qcom.h \
+ $(QPEDIR)/include/qpe/quuid.h \
+ mediaplayerstate.h
+
+audiowidget.o: audiowidget.cpp \
+ $(QPEDIR)/include/qpe/resource.h \
+ audiowidget.h \
+ mediaplayerstate.h
+
+playlistwidget.o: playlistwidget.cpp \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h \
+ $(QPEDIR)/include/qpe/fileselector.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ playlistselection.h \
+ playlistwidget.h \
+ mediaplayerstate.h
+
+mediaplayer.o: mediaplayer.cpp \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/qlibrary.h \
+ $(QPEDIR)/include/qpe/qcom.h \
+ $(QPEDIR)/include/qpe/quuid.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/config.h \
+ mediaplayer.h \
+ mediaplayerplugininterface.h \
+ playlistwidget.h \
+ $(QPEDIR)/include/qpe/applnk.h \
+ audiowidget.h \
+ loopcontrol.h \
+ audiodevice.h \
+ mediaplayerstate.h
+
+audiodevice.o: audiodevice.cpp \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/config.h \
+ audiodevice.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h
+
+moc_loopcontrol.o: moc_loopcontrol.cpp \
+ loopcontrol.h
+
+moc_playlistselection.o: moc_playlistselection.cpp \
+ playlistselection.h \
+ $(QPEDIR)/include/qpe/applnk.h
+
+moc_mediaplayerstate.o: moc_mediaplayerstate.cpp \
+ mediaplayerstate.h
+
+moc_videowidget.o: moc_videowidget.cpp \
+ videowidget.h
+
+moc_audiowidget.o: moc_audiowidget.cpp \
+ audiowidget.h
+
+moc_playlistwidget.o: moc_playlistwidget.cpp \
+ playlistwidget.h \
+ $(QPEDIR)/include/qpe/applnk.h
+
+moc_mediaplayer.o: moc_mediaplayer.cpp \
+ mediaplayer.h \
+ $(QPEDIR)/include/qpe/qlibrary.h \
+ $(QPEDIR)/include/qpe/qcom.h \
+ $(QPEDIR)/include/qpe/quuid.h \
+ mediaplayerplugininterface.h
+
+moc_audiodevice.o: moc_audiodevice.cpp \
+ audiodevice.h
+
+moc_loopcontrol.cpp: loopcontrol.h
+ $(MOC) loopcontrol.h -o moc_loopcontrol.cpp
+
+moc_playlistselection.cpp: playlistselection.h
+ $(MOC) playlistselection.h -o moc_playlistselection.cpp
+
+moc_mediaplayerstate.cpp: mediaplayerstate.h
+ $(MOC) mediaplayerstate.h -o moc_mediaplayerstate.cpp
+
+moc_videowidget.cpp: videowidget.h
+ $(MOC) videowidget.h -o moc_videowidget.cpp
+
+moc_audiowidget.cpp: audiowidget.h
+ $(MOC) audiowidget.h -o moc_audiowidget.cpp
+
+moc_playlistwidget.cpp: playlistwidget.h
+ $(MOC) playlistwidget.h -o moc_playlistwidget.cpp
+
+moc_mediaplayer.cpp: mediaplayer.h
+ $(MOC) mediaplayer.h -o moc_mediaplayer.cpp
+
+moc_audiodevice.cpp: audiodevice.h
+ $(MOC) audiodevice.h -o moc_audiodevice.cpp
+
+
diff --git a/core/multimedia/opieplayer/audiodevice.cpp b/core/multimedia/opieplayer/audiodevice.cpp
new file mode 100644
index 0000000..8861015
--- a/dev/null
+++ b/core/multimedia/opieplayer/audiodevice.cpp
@@ -0,0 +1,386 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <stdlib.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/config.h>
+#include "audiodevice.h"
+
+#if ( defined Q_WS_QWS || defined(_WS_QWS_) ) && !defined(QT_NO_COP)
+#include "qpe/qcopenvelope_qws.h"
+#endif
+
+#ifdef Q_WS_WIN
+#include <windows.h>
+#include <mmsystem.h>
+#include <mmreg.h>
+#endif
+
+#if defined(Q_WS_X11) || defined(Q_WS_QWS)
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/soundcard.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
+#if defined(Q_OS_WIN32)
+static const int expectedBytesPerMilliSecond = 2 * 2 * 44000 / 1000;
+static const int timerResolutionMilliSeconds = 30;
+static const int sound_fragment_bytes = timerResolutionMilliSeconds * expectedBytesPerMilliSecond;
+#else
+# if defined(QT_QWS_IPAQ)
+static const int sound_fragment_shift = 14;
+# else
+static const int sound_fragment_shift = 16;
+# endif
+static const int sound_fragment_bytes = (1<<sound_fragment_shift);
+#endif
+
+
+class AudioDevicePrivate {
+public:
+ int handle;
+ unsigned int frequency;
+ unsigned int channels;
+ unsigned int bytesPerSample;
+ unsigned int bufferSize;
+#ifndef Q_OS_WIN32
+ bool can_GETOSPACE;
+ char* unwrittenBuffer;
+ unsigned int unwritten;
+#endif
+
+ static int dspFd;
+ static bool muted;
+ static unsigned int leftVolume;
+ static unsigned int rightVolume;
+};
+
+
+#ifdef Q_WS_QWS
+// This is for keeping the device open in-between playing files when
+// the device makes clicks and it starts to drive you insane! :)
+// Best to have the device not open when not using it though
+//#define KEEP_DEVICE_OPEN
+#endif
+
+
+int AudioDevicePrivate::dspFd = 0;
+bool AudioDevicePrivate::muted = FALSE;
+unsigned int AudioDevicePrivate::leftVolume = 0;
+unsigned int AudioDevicePrivate::rightVolume = 0;
+
+
+void AudioDevice::getVolume( unsigned int& leftVolume, unsigned int& rightVolume, bool &muted ) {
+ muted = AudioDevicePrivate::muted;
+ unsigned int volume;
+#ifdef Q_OS_WIN32
+ HWAVEOUT handle;
+ WAVEFORMATEX formatData;
+ formatData.cbSize = sizeof(WAVEFORMATEX);
+ formatData.wFormatTag = WAVE_FORMAT_PCM;
+ formatData.nAvgBytesPerSec = 4 * 44000;
+ formatData.nBlockAlign = 4;
+ formatData.nChannels = 2;
+ formatData.nSamplesPerSec = 44000;
+ formatData.wBitsPerSample = 16;
+ waveOutOpen(&handle, WAVE_MAPPER, &formatData, 0L, 0L, CALLBACK_NULL);
+ if ( waveOutGetVolume( handle, (LPDWORD)&volume ) )
+ qDebug( "get volume of audio device failed" );
+ waveOutClose( handle );
+ leftVolume = volume & 0xFFFF;
+ rightVolume = volume >> 16;
+#else
+ int mixerHandle = open( "/dev/mixer", O_RDWR );
+ if ( mixerHandle >= 0 ) {
+ ioctl( mixerHandle, MIXER_READ(0), &volume );
+ close( mixerHandle );
+ } else
+ qDebug( "get volume of audio device failed" );
+ leftVolume = ((volume & 0x00FF) << 16) / 101;
+ rightVolume = ((volume & 0xFF00) << 8) / 101;
+#endif
+}
+
+
+void AudioDevice::setVolume( unsigned int leftVolume, unsigned int rightVolume, bool muted ) {
+ AudioDevicePrivate::muted = muted;
+ if ( muted ) {
+ AudioDevicePrivate::leftVolume = leftVolume;
+ AudioDevicePrivate::rightVolume = rightVolume;
+ leftVolume = 0;
+ rightVolume = 0;
+ } else {
+ leftVolume = ( (int) leftVolume < 0 ) ? 0 : (( leftVolume > 0xFFFF ) ? 0xFFFF : leftVolume );
+ rightVolume = ( (int)rightVolume < 0 ) ? 0 : (( rightVolume > 0xFFFF ) ? 0xFFFF : rightVolume );
+ }
+#ifdef Q_OS_WIN32
+ HWAVEOUT handle;
+ WAVEFORMATEX formatData;
+ formatData.cbSize = sizeof(WAVEFORMATEX);
+ formatData.wFormatTag = WAVE_FORMAT_PCM;
+ formatData.nAvgBytesPerSec = 4 * 44000;
+ formatData.nBlockAlign = 4;
+ formatData.nChannels = 2;
+ formatData.nSamplesPerSec = 44000;
+ formatData.wBitsPerSample = 16;
+ waveOutOpen(&handle, WAVE_MAPPER, &formatData, 0L, 0L, CALLBACK_NULL);
+ unsigned int volume = (rightVolume << 16) | leftVolume;
+ if ( waveOutSetVolume( handle, volume ) )
+ qDebug( "set volume of audio device failed" );
+ waveOutClose( handle );
+#else
+ // Volume can be from 0 to 100 which is 101 distinct values
+ unsigned int rV = (rightVolume * 101) >> 16;
+
+# if 0
+ unsigned int lV = (leftVolume * 101) >> 16;
+ unsigned int volume = ((rV << 8) & 0xFF00) | (lV & 0x00FF);
+ int mixerHandle = 0;
+ if ( ( mixerHandle = open( "/dev/mixer", O_RDWR ) ) >= 0 ) {
+ ioctl( mixerHandle, MIXER_WRITE(0), &volume );
+ close( mixerHandle );
+ } else
+ qDebug( "set volume of audio device failed" );
+# else
+ // This is the way this has to be done now I guess, doesn't allow for
+ // independant right and left channel setting, or setting for different outputs
+ Config cfg("Sound");
+ cfg.setGroup("System");
+ cfg.writeEntry("Volume",(int)rV);
+# endif
+
+#endif
+// qDebug( "setting volume to: 0x%x", volume );
+#if ( defined Q_WS_QWS || defined(_WS_QWS_) ) && !defined(QT_NO_COP)
+ // Send notification that the volume has changed
+ QCopEnvelope( "QPE/System", "volumeChange(bool)" ) << muted;
+#endif
+}
+
+
+
+
+AudioDevice::AudioDevice( unsigned int f, unsigned int chs, unsigned int bps ) {
+ d = new AudioDevicePrivate;
+ d->frequency = f;
+ d->channels = chs;
+ d->bytesPerSample = bps;
+
+ connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( volumeChanged(bool) ) );
+
+#ifdef Q_OS_WIN32
+ UINT result;
+ WAVEFORMATEX formatData;
+ formatData.cbSize = sizeof(WAVEFORMATEX);
+/*
+ // Other possible formats windows supports
+ formatData.wFormatTag = WAVE_FORMAT_MPEG;
+ formatData.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
+ formatData.wFormatTag = WAVE_FORMAT_ADPCM;
+*/
+ formatData.wFormatTag = WAVE_FORMAT_PCM;
+ formatData.nAvgBytesPerSec = bps * chs * f;
+ formatData.nBlockAlign = bps * chs;
+ formatData.nChannels = chs;
+ formatData.nSamplesPerSec = f;
+ formatData.wBitsPerSample = bps * 8;
+ // Open a waveform device for output
+ if (result = waveOutOpen((LPHWAVEOUT)&d->handle, WAVE_MAPPER, &formatData, 0L, 0L, CALLBACK_NULL)) {
+ QString errorMsg = "error opening audio device.\nReason: %i - ";
+ switch (result) {
+ case MMSYSERR_ALLOCATED: errorMsg += "Specified resource is already allocated."; break;
+ case MMSYSERR_BADDEVICEID: errorMsg += "Specified device identifier is out of range."; break;
+ case MMSYSERR_NODRIVER: errorMsg += "No device driver is present."; break;
+ case MMSYSERR_NOMEM: errorMsg += "Unable to allocate or lock memory."; break;
+ case WAVERR_BADFORMAT: errorMsg += "Attempted to open with an unsupported waveform-audio format."; break;
+ case WAVERR_SYNC: errorMsg += "The device is synchronous but waveOutOpen was called without using the WAVE_ALLOWSYNC flag."; break;
+ default: errorMsg += "Undefined error"; break;
+ }
+ qDebug( errorMsg, result );
+ }
+
+ d->bufferSize = sound_fragment_bytes;
+#else
+
+ int fragments = 0x10000 * 8 + sound_fragment_shift;
+ int format = AFMT_S16_LE;
+ int capabilities = 0;
+
+#ifdef KEEP_DEVICE_OPEN
+ if ( AudioDevicePrivate::dspFd == 0 ) {
+#endif
+ if ( ( d->handle = ::open( "/dev/dsp", O_WRONLY ) ) < 0 ) {
+ qDebug( "error opening audio device /dev/dsp, sending data to /dev/null instead" );
+ d->handle = ::open( "/dev/null", O_WRONLY );
+ }
+#ifdef KEEP_DEVICE_OPEN
+ AudioDevicePrivate::dspFd = d->handle;
+ } else {
+ d->handle = AudioDevicePrivate::dspFd;
+ }
+#endif
+
+ ioctl( d->handle, SNDCTL_DSP_GETCAPS, &capabilities );
+ ioctl( d->handle, SNDCTL_DSP_SETFRAGMENT, &fragments );
+ ioctl( d->handle, SNDCTL_DSP_SETFMT, &format );
+ ioctl( d->handle, SNDCTL_DSP_SPEED, &d->frequency );
+ if ( ioctl( d->handle, SNDCTL_DSP_CHANNELS, &d->channels ) == -1 ) {
+ d->channels = ( d->channels == 1 ) ? 2 : d->channels;
+ ioctl( d->handle, SNDCTL_DSP_CHANNELS, &d->channels );
+ }
+
+ d->bufferSize = sound_fragment_bytes;
+ d->unwrittenBuffer = new char[d->bufferSize];
+ d->unwritten = 0;
+ d->can_GETOSPACE = TRUE; // until we find otherwise
+
+ //if ( chs != d->channels ) qDebug( "Wanted %d, got %d channels", chs, d->channels );
+ //if ( f != d->frequency ) qDebug( "wanted %dHz, got %dHz", f, d->frequency );
+ //if ( capabilities & DSP_CAP_BATCH ) qDebug( "Sound card has local buffer" );
+ //if ( capabilities & DSP_CAP_REALTIME )qDebug( "Sound card has realtime sync" );
+ //if ( capabilities & DSP_CAP_TRIGGER ) qDebug( "Sound card has precise trigger" );
+ //if ( capabilities & DSP_CAP_MMAP ) qDebug( "Sound card can mmap" );
+#endif
+}
+
+
+AudioDevice::~AudioDevice() {
+#ifdef Q_OS_WIN32
+ waveOutClose( (HWAVEOUT)d->handle );
+#else
+# ifndef KEEP_DEVICE_OPEN
+ close( d->handle ); // Now it should be safe to shut the handle
+# endif
+ delete d->unwrittenBuffer;
+ delete d;
+#endif
+}
+
+
+void AudioDevice::volumeChanged( bool muted )
+{
+ AudioDevicePrivate::muted = muted;
+}
+
+
+void AudioDevice::write( char *buffer, unsigned int length )
+{
+#ifdef Q_OS_WIN32
+ // returns immediately and (to be implemented) emits completedIO() when finished writing
+ WAVEHDR *lpWaveHdr = (WAVEHDR *)malloc( sizeof(WAVEHDR) );
+ // maybe the buffer should be copied so that this fool proof, but its a performance hit
+ lpWaveHdr->lpData = buffer;
+ lpWaveHdr->dwBufferLength = length;
+ lpWaveHdr->dwFlags = 0L;
+ lpWaveHdr->dwLoops = 0L;
+ waveOutPrepareHeader( (HWAVEOUT)d->handle, lpWaveHdr, sizeof(WAVEHDR) );
+ // waveOutWrite returns immediately. the data is sent in the background.
+ if ( waveOutWrite( (HWAVEOUT)d->handle, lpWaveHdr, sizeof(WAVEHDR) ) )
+ qDebug( "failed to write block to audio device" );
+ // emit completedIO();
+#else
+ int t = ::write( d->handle, buffer, length );
+ if ( t<0 ) t = 0;
+ if ( t != (int)length) {
+ qDebug("Ahhh!! memcpys 1");
+ memcpy(d->unwrittenBuffer,buffer+t,length-t);
+ d->unwritten = length-t;
+ }
+#endif
+}
+
+
+unsigned int AudioDevice::channels() const
+{
+ return d->channels;
+}
+
+
+unsigned int AudioDevice::frequency() const
+{
+ return d->frequency;
+}
+
+
+unsigned int AudioDevice::bytesPerSample() const
+{
+ return d->bytesPerSample;
+}
+
+
+unsigned int AudioDevice::bufferSize() const
+{
+ return d->bufferSize;
+}
+
+unsigned int AudioDevice::canWrite() const
+{
+#ifdef Q_OS_WIN32
+ return bufferSize(); // Any better?
+#else
+ audio_buf_info info;
+ if ( d->can_GETOSPACE && ioctl(d->handle,SNDCTL_DSP_GETOSPACE,&info) ) {
+ d->can_GETOSPACE = FALSE;
+ fcntl( d->handle, F_SETFL, O_NONBLOCK );
+ }
+ if ( d->can_GETOSPACE ) {
+ int t = info.fragments * sound_fragment_bytes;
+ return QMIN(t,(int)bufferSize());
+ } else {
+ if ( d->unwritten ) {
+ int t = ::write( d->handle, d->unwrittenBuffer, d->unwritten );
+ if ( t<0 ) t = 0;
+ if ( (unsigned)t!=d->unwritten ) {
+ memcpy(d->unwrittenBuffer,d->unwrittenBuffer+t,d->unwritten-t);
+ d->unwritten -= t;
+ } else {
+ d->unwritten = 0;
+ }
+ }
+ if ( d->unwritten )
+ return 0;
+ else
+ return d->bufferSize;
+ }
+#endif
+}
+
+
+int AudioDevice::bytesWritten() {
+#ifdef Q_OS_WIN32
+ MMTIME pmmt = { TIME_BYTES, 0 };
+ if ( ( waveOutGetPosition( (HWAVEOUT)d->handle, &pmmt, sizeof(MMTIME) ) != MMSYSERR_NOERROR ) || ( pmmt.wType != TIME_BYTES ) ) {
+ qDebug( "failed to get audio device position" );
+ return -1;
+ }
+ return pmmt.u.cb;
+#else
+ int buffered = 0;
+ if ( ioctl( d->handle, SNDCTL_DSP_GETODELAY, &buffered ) ) {
+ qDebug( "failed to get audio device position" );
+ return -1;
+ }
+ return buffered;
+#endif
+}
+
diff --git a/core/multimedia/opieplayer/audiodevice.h b/core/multimedia/opieplayer/audiodevice.h
new file mode 100644
index 0000000..928f134
--- a/dev/null
+++ b/core/multimedia/opieplayer/audiodevice.h
@@ -0,0 +1,71 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef AUDIODEVICE_H
+#define AUDIODEVICE_H
+
+
+#include <qobject.h>
+
+
+class AudioDevicePrivate;
+
+
+class AudioDevice : public QObject {
+ Q_OBJECT
+public:
+ AudioDevice( unsigned int freq = 44000, unsigned int channels = 2, unsigned int bytesPerSample = 2 );
+ ~AudioDevice();
+
+ unsigned int canWrite() const;
+ void write( char *buffer, unsigned int length );
+ int bytesWritten();
+
+ unsigned int channels() const;
+ unsigned int frequency() const;
+ unsigned int bytesPerSample() const;
+ unsigned int bufferSize() const;
+
+ // Each volume level is from 0 to 0xFFFF
+ static void getVolume( unsigned int& left, unsigned int& right, bool& muted );
+ static void setVolume( unsigned int left, unsigned int right, bool muted );
+
+ static unsigned int leftVolume() { bool muted; unsigned int l, r; getVolume( l, r, muted ); return l; }
+ static unsigned int rightVolume() { bool muted; unsigned int l, r; getVolume( l, r, muted ); return r; }
+ static bool isMuted() { bool muted; unsigned int l, r; getVolume( l, r, muted ); return muted; }
+
+ static void increaseVolume() { setVolume( leftVolume() + 1968, rightVolume() + 1968, isMuted() ); }
+ static void decreaseVolume() { setVolume( leftVolume() - 1966, rightVolume() - 1966, isMuted() ); }
+
+public slots:
+ // Convinence functions derived from above functions
+ void setVolume( unsigned int level ) { setVolume( level, level, isMuted() ); }
+ void mute() { setVolume( leftVolume(), rightVolume(), TRUE ); }
+ void volumeChanged( bool muted );
+
+signals:
+ void completedIO();
+
+private:
+ AudioDevicePrivate *d;
+};
+
+
+#endif // AUDIODEVICE_H
+
diff --git a/core/multimedia/opieplayer/audiowidget.cpp b/core/multimedia/opieplayer/audiowidget.cpp
new file mode 100644
index 0000000..243c58c
--- a/dev/null
+++ b/core/multimedia/opieplayer/audiowidget.cpp
@@ -0,0 +1,277 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qwidget.h>
+#include <qpixmap.h>
+#include <qbutton.h>
+#include <qpainter.h>
+#include <qframe.h>
+#include <qpe/resource.h>
+#include "audiowidget.h"
+#include "mediaplayerstate.h"
+
+
+extern MediaPlayerState *mediaPlayerState;
+
+
+static const int xo = -2; // movable x offset
+static const int yo = 22; // movable y offset
+
+
+struct MediaButton {
+ int xPos, yPos;
+ int color;
+ bool isToggle, isBig, isHeld, isDown;
+};
+
+
+// Layout information for the audioButtons (and if it is a toggle button or not)
+MediaButton audioButtons[] = {
+ { 3*30-15+xo, 3*30-13+yo, 0, TRUE, TRUE, FALSE, FALSE }, // play
+ { 1*30+xo, 5*30+yo, 2, FALSE, FALSE, FALSE, FALSE }, // stop
+ { 5*30+xo, 5*30+yo, 2, TRUE, FALSE, FALSE, FALSE }, // pause
+ { 6*30-5+xo, 3*30+yo, 1, FALSE, FALSE, FALSE, FALSE }, // next
+ { 0*30+5+xo, 3*30+yo, 1, FALSE, FALSE, FALSE, FALSE }, // previous
+ { 3*30+xo, 0*30+5+yo, 3, FALSE, FALSE, FALSE, FALSE }, // volume up
+ { 3*30+xo, 6*30-5+yo, 3, FALSE, FALSE, FALSE, FALSE }, // volume down
+ { 5*30+xo, 1*30+yo, 0, TRUE, FALSE, FALSE, FALSE }, // repeat/loop
+ { 1*30+xo, 1*30+yo, 0, FALSE, FALSE, FALSE, FALSE } // playlist
+};
+
+
+static const int numButtons = (sizeof(audioButtons)/sizeof(MediaButton));
+
+
+AudioWidget::AudioWidget(QWidget* parent, const char* name, WFlags f) :
+ QWidget( parent, name, f )
+{
+ setCaption( tr("MediaPlayer") );
+ setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) );
+ pixmaps[0] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaButtonsAll" ) );
+ pixmaps[1] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaButtonsBig" ) );
+ pixmaps[2] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaControls" ) );
+ pixmaps[3] = new QPixmap( Resource::loadPixmap( "mpegplayer/animatedButton" ) );
+
+ songInfo = new Ticker( this );
+ songInfo->setFocusPolicy( QWidget::NoFocus );
+ songInfo->setGeometry( QRect( 7, 3, 220, 20 ) );
+
+ slider = new QSlider( Qt::Horizontal, this );
+ slider->setFixedWidth( 220 );
+ slider->setFixedHeight( 20 );
+ slider->setMinValue( 0 );
+ slider->setMaxValue( 1 );
+ slider->setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) );
+ slider->setFocusPolicy( QWidget::NoFocus );
+ slider->setGeometry( QRect( 7, 262, 220, 20 ) );
+
+ connect( slider, SIGNAL( sliderPressed() ), this, SLOT( sliderPressed() ) );
+ connect( slider, SIGNAL( sliderReleased() ), this, SLOT( sliderReleased() ) );
+
+ connect( mediaPlayerState, SIGNAL( lengthChanged(long) ), this, SLOT( setLength(long) ) );
+ connect( mediaPlayerState, SIGNAL( positionChanged(long) ),this, SLOT( setPosition(long) ) );
+ connect( mediaPlayerState, SIGNAL( positionUpdated(long) ),this, SLOT( setPosition(long) ) );
+ connect( mediaPlayerState, SIGNAL( viewChanged(char) ), this, SLOT( setView(char) ) );
+ connect( mediaPlayerState, SIGNAL( loopingToggled(bool) ), this, SLOT( setLooping(bool) ) );
+ connect( mediaPlayerState, SIGNAL( pausedToggled(bool) ), this, SLOT( setPaused(bool) ) );
+ connect( mediaPlayerState, SIGNAL( playingToggled(bool) ), this, SLOT( setPlaying(bool) ) );
+
+ // Intialise state
+ setLength( mediaPlayerState->length() );
+ setPosition( mediaPlayerState->position() );
+ setLooping( mediaPlayerState->fullscreen() );
+ setPaused( mediaPlayerState->paused() );
+ setPlaying( mediaPlayerState->playing() );
+
+}
+
+
+AudioWidget::~AudioWidget() {
+ for ( int i = 0; i < 4; i++ )
+ delete pixmaps[i];
+}
+
+
+static bool audioSliderBeingMoved = FALSE;
+
+
+void AudioWidget::sliderPressed() {
+ audioSliderBeingMoved = TRUE;
+}
+
+
+void AudioWidget::sliderReleased() {
+ audioSliderBeingMoved = FALSE;
+ if ( slider->width() == 0 )
+ return;
+ long val = long((double)slider->value() * mediaPlayerState->length() / slider->width());
+ mediaPlayerState->setPosition( val );
+}
+
+
+void AudioWidget::setPosition( long i ) {
+ updateSlider( i, mediaPlayerState->length() );
+}
+
+
+void AudioWidget::setLength( long max ) {
+ updateSlider( mediaPlayerState->position(), max );
+}
+
+
+void AudioWidget::setView( char view ) {
+ if ( view == 'a' ) {
+ startTimer( 150 );
+ showMaximized();
+ } else {
+ killTimers();
+ hide();
+ }
+}
+
+
+void AudioWidget::updateSlider( long i, long max ) {
+ if ( max == 0 )
+ return;
+ // Will flicker too much if we don't do this
+ // Scale to something reasonable
+ int width = slider->width();
+ int val = int((double)i * width / max);
+ if ( !audioSliderBeingMoved ) {
+ if ( slider->value() != val )
+ slider->setValue( val );
+ if ( slider->maxValue() != width )
+ slider->setMaxValue( width );
+ }
+}
+
+
+void AudioWidget::setToggleButton( int i, bool down ) {
+ if ( down != audioButtons[i].isDown )
+ toggleButton( i );
+}
+
+
+void AudioWidget::toggleButton( int i ) {
+ audioButtons[i].isDown = !audioButtons[i].isDown;
+ QPainter p(this);
+ paintButton ( &p, i );
+}
+
+
+void AudioWidget::paintButton( QPainter *p, int i ) {
+ int x = audioButtons[i].xPos;
+ int y = audioButtons[i].yPos;
+ int offset = 22 + 14 * audioButtons[i].isBig + audioButtons[i].isDown;
+ int buttonSize = 64 + audioButtons[i].isBig * (90 - 64);
+ p->drawPixmap( x, y, *pixmaps[audioButtons[i].isBig], buttonSize * (audioButtons[i].isDown + 2 * audioButtons[i].color), 0, buttonSize, buttonSize );
+ p->drawPixmap( x + offset, y + offset, *pixmaps[2], 18 * i, 0, 18, 18 );
+}
+
+
+void AudioWidget::timerEvent( QTimerEvent * ) {
+ static int frame = 0;
+ if ( !mediaPlayerState->paused() && audioButtons[ AudioPlay ].isDown ) {
+ frame = frame >= 7 ? 0 : frame + 1;
+ int x = audioButtons[AudioPlay].xPos;
+ int y = audioButtons[AudioPlay].yPos;
+ QPainter p( this );
+ // Optimize to only draw the little bit of the changing images which is different
+ p.drawPixmap( x + 14, y + 8, *pixmaps[3], 32 * frame, 0, 32, 32 );
+ p.drawPixmap( x + 37, y + 37, *pixmaps[2], 18 * AudioPlay, 0, 6, 3 );
+ }
+}
+
+
+void AudioWidget::mouseMoveEvent( QMouseEvent *event ) {
+ for ( int i = 0; i < numButtons; i++ ) {
+ int size = audioButtons[i].isBig;
+ int x = audioButtons[i].xPos;
+ int y = audioButtons[i].yPos;
+ if ( event->state() == QMouseEvent::LeftButton ) {
+ // The test to see if the mouse click is inside the circular button or not
+ // (compared with the radius squared to avoid a square-root of our distance)
+ int radius = 32 + 13 * size;
+ QPoint center = QPoint( x + radius, y + radius );
+ QPoint dXY = center - event->pos();
+ int dist = dXY.x() * dXY.x() + dXY.y() * dXY.y();
+ bool isOnButton = dist <= (radius * radius);
+// QRect r( x, y, 64 + 22*size, 64 + 22*size );
+// bool isOnButton = r.contains( event->pos() ); // Rectangular Button code
+ if ( isOnButton && !audioButtons[i].isHeld ) {
+ audioButtons[i].isHeld = TRUE;
+ toggleButton(i);
+ switch (i) {
+ case AudioVolumeUp: emit moreClicked(); return;
+ case AudioVolumeDown: emit lessClicked(); return;
+ }
+ } else if ( !isOnButton && audioButtons[i].isHeld ) {
+ audioButtons[i].isHeld = FALSE;
+ toggleButton(i);
+ }
+ } else {
+ if ( audioButtons[i].isHeld ) {
+ audioButtons[i].isHeld = FALSE;
+ if ( !audioButtons[i].isToggle )
+ setToggleButton( i, FALSE );
+ switch (i) {
+ case AudioPlay: mediaPlayerState->setPlaying(audioButtons[i].isDown); return;
+ case AudioStop: mediaPlayerState->setPlaying(FALSE); return;
+ case AudioPause: mediaPlayerState->setPaused(audioButtons[i].isDown); return;
+ case AudioNext: mediaPlayerState->setNext(); return;
+ case AudioPrevious: mediaPlayerState->setPrev(); return;
+ case AudioLoop: mediaPlayerState->setLooping(audioButtons[i].isDown); return;
+ case AudioVolumeUp: emit moreReleased(); return;
+ case AudioVolumeDown: emit lessReleased(); return;
+ case AudioPlayList: mediaPlayerState->setList(); return;
+ }
+ }
+ }
+ }
+}
+
+
+void AudioWidget::mousePressEvent( QMouseEvent *event ) {
+ mouseMoveEvent( event );
+}
+
+
+void AudioWidget::mouseReleaseEvent( QMouseEvent *event ) {
+ mouseMoveEvent( event );
+}
+
+
+void AudioWidget::showEvent( QShowEvent* ) {
+ QMouseEvent event( QEvent::MouseMove, QPoint( 0, 0 ), 0, 0 );
+ mouseMoveEvent( &event );
+}
+
+
+void AudioWidget::closeEvent( QCloseEvent* ) {
+ mediaPlayerState->setList();
+}
+
+
+void AudioWidget::paintEvent( QPaintEvent * ) {
+ QPainter p( this );
+ for ( int i = 0; i < numButtons; i++ )
+ paintButton( &p, i );
+}
+
+
diff --git a/core/multimedia/opieplayer/audiowidget.h b/core/multimedia/opieplayer/audiowidget.h
new file mode 100644
index 0000000..4b82a91
--- a/dev/null
+++ b/core/multimedia/opieplayer/audiowidget.h
@@ -0,0 +1,144 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef AUDIO_WIDGET_H
+#define AUDIO_WIDGET_H
+
+
+#include <qwidget.h>
+#include <qpainter.h>
+#include <qdrawutil.h>
+#include <qpixmap.h>
+#include <qstring.h>
+#include <qslider.h>
+#include <qframe.h>
+
+
+class QPixmap;
+
+
+enum AudioButtons {
+ AudioPlay,
+ AudioStop,
+ AudioPause,
+ AudioNext,
+ AudioPrevious,
+ AudioVolumeUp,
+ AudioVolumeDown,
+ AudioLoop,
+ AudioPlayList
+};
+
+
+#define USE_DBLBUF
+
+
+class Ticker : public QFrame {
+ Q_OBJECT
+public:
+ Ticker( QWidget* parent=0 ) : QFrame( parent ) {
+ setFrameStyle( WinPanel | Sunken );
+ setText( "No Song" );
+ }
+ ~Ticker() { }
+ void setText( const QString& text ) {
+ pos = 0; // reset it everytime the text is changed
+ scrollText = text;
+ pixelLen = fontMetrics().width( scrollText );
+ killTimers();
+ if ( pixelLen > width() )
+ startTimer( 50 );
+ update();
+ }
+protected:
+ void timerEvent( QTimerEvent * ) {
+ pos = ( pos + 1 > pixelLen ) ? 0 : pos + 1;
+#ifndef USE_DBLBUF
+ scroll( -1, 0, contentsRect() );
+#else
+ repaint( FALSE );
+#endif
+ }
+ void drawContents( QPainter *p ) {
+#ifndef USE_DBLBUF
+ for ( int i = 0; i - pos < width() && (i < 1 || pixelLen > width()); i += pixelLen )
+ p->drawText( i - pos, 0, INT_MAX, height(), AlignVCenter, scrollText );
+#else
+ // Double buffering code.
+ // Looks like qvfb makes it look like it flickers but I don't think it really is
+ QPixmap pm( width(), height() );
+ pm.fill( colorGroup().base() );
+ QPainter pmp( &pm );
+ for ( int i = 0; i - pos < width() && (i < 1 || pixelLen > width()); i += pixelLen )
+ pmp.drawText( i - pos, 0, INT_MAX, height(), AlignVCenter, scrollText );
+ p->drawPixmap( 0, 0, pm );
+#endif
+ }
+private:
+ QString scrollText;
+ int pos, pixelLen;
+};
+
+
+class AudioWidget : public QWidget {
+ Q_OBJECT
+public:
+ AudioWidget( QWidget* parent=0, const char* name=0, WFlags f=0 );
+ ~AudioWidget();
+ void setTickerText( const QString &text ) { songInfo->setText( text ); }
+
+public slots:
+ void updateSlider( long, long );
+ void sliderPressed( );
+ void sliderReleased( );
+ void setPaused( bool b) { setToggleButton( AudioPause, b ); }
+ void setLooping( bool b) { setToggleButton( AudioLoop, b ); }
+ void setPlaying( bool b) { setToggleButton( AudioPlay, b ); }
+ void setPosition( long );
+ void setLength( long );
+ void setView( char );
+
+signals:
+ void moreClicked();
+ void lessClicked();
+ void moreReleased();
+ void lessReleased();
+ void sliderMoved(long);
+
+protected:
+ void paintEvent( QPaintEvent *pe );
+ void showEvent( QShowEvent *se );
+ void mouseMoveEvent( QMouseEvent *event );
+ void mousePressEvent( QMouseEvent *event );
+ void mouseReleaseEvent( QMouseEvent *event );
+ void timerEvent( QTimerEvent *event );
+ void closeEvent( QCloseEvent *event );
+
+private:
+ void toggleButton( int );
+ void setToggleButton( int, bool );
+ void paintButton( QPainter *p, int i );
+ QPixmap *pixmaps[4];
+ Ticker *songInfo;
+ QSlider *slider;
+};
+
+
+#endif // AUDIO_WIDGET_H
+
diff --git a/core/multimedia/opieplayer/libflash/Makefile.in b/core/multimedia/opieplayer/libflash/Makefile.in
new file mode 100644
index 0000000..52c8557
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/Makefile.in
@@ -0,0 +1,644 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../../plugins/codecs/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = flashplugin
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = libflashplugin.h \
+ libflashpluginimpl.h
+SOURCES = libflashplugin.cpp \
+ libflashpluginimpl.cpp \
+ adpcm.cc \
+ character.cc \
+ flash.cc \
+ graphic16.cc \
+ matrix.cc \
+ script.cc \
+ sprite.cc \
+ bitmap.cc \
+ cxform.cc \
+ font.cc \
+ graphic24.cc \
+ movie.cc \
+ shape.cc \
+ sqrt.cc \
+ button.cc \
+ displaylist.cc \
+ graphic.cc \
+ graphic32.cc \
+ program.cc \
+ sound.cc \
+ text.cc
+OBJECTS = libflashplugin.o \
+ libflashpluginimpl.o \
+ adpcm.o \
+ character.o \
+ flash.o \
+ graphic16.o \
+ matrix.o \
+ script.o \
+ sprite.o \
+ bitmap.o \
+ cxform.o \
+ font.o \
+ graphic24.o \
+ movie.o \
+ shape.o \
+ sqrt.o \
+ button.o \
+ displaylist.o \
+ graphic.o \
+ graphic32.o \
+ program.o \
+ sound.o \
+ text.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC =
+OBJMOC =
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
+
+$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK_LIB)
+
+moc: $(SRCMOC)
+
+tmake: Makefile.in
+
+Makefile.in: libflash.pro
+ tmake libflash.pro -o Makefile.in
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+libflashplugin.o: libflashplugin.cpp \
+ libflashplugin.h \
+ flash.h \
+ ../mediaplayerplugininterface.h
+
+libflashpluginimpl.o: libflashpluginimpl.cpp \
+ libflashplugin.h \
+ flash.h \
+ ../mediaplayerplugininterface.h \
+ libflashpluginimpl.h \
+ ../mediaplayerplugininterface.h
+
+adpcm.o: adpcm.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+character.o: character.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+flash.o: flash.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h \
+ graphic16.h \
+ graphic24.h \
+ graphic32.h
+
+graphic16.o: graphic16.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h \
+ graphic16.h
+
+matrix.o: matrix.cc \
+ matrix.h
+
+script.o: script.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+sprite.o: sprite.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+bitmap.o: bitmap.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+cxform.o: cxform.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+font.o: font.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+graphic24.o: graphic24.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h \
+ graphic24.h
+
+movie.o: movie.cc \
+ movie.h \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h
+
+shape.o: shape.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+sqrt.o: sqrt.cc
+
+button.o: button.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+displaylist.o: displaylist.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+graphic.o: graphic.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+graphic32.o: graphic32.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h \
+ graphic32.h
+
+program.o: program.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+sound.o: sound.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+text.o: text.cc \
+ swf.h \
+ flash.h \
+ matrix.h \
+ cxform.h \
+ rect.h \
+ jpeglib.h \
+ jconfig.h \
+ jmorecfg.h \
+ jerror.h \
+ graphic.h \
+ character.h \
+ bitmap.h \
+ shape.h \
+ displaylist.h \
+ sound.h \
+ button.h \
+ font.h \
+ text.h \
+ adpcm.h \
+ program.h \
+ sprite.h \
+ script.h \
+ movie.h
+
+
diff --git a/core/multimedia/opieplayer/libflash/README b/core/multimedia/opieplayer/libflash/README
new file mode 100644
index 0000000..9914a00
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/README
@@ -0,0 +1,191 @@
+
+MODIFICATIONS BY TROLLTECH
+--------------------------
+
+Oct. 2001
+
+Just the Lib directory of the flash library source archive
+has been copied in to the QPE CVS tree. For the full source code
+to create a KDE screensaver or stand alone player etc, download
+the orginal source tar ball from http://www.swift-tools.com/Flash
+The files libflashplugin* have been added to wrapper the library
+to produce a Qtopia Media Player plugin out of the code.
+
+John R.
+
+
+INTRODUCTION
+------------
+
+Jun. 12th 2000
+
+This the Version 0.4.10 of the Flash Library for Linux.
+
+Flash Plugin is under GPL, see COPYING file.
+
+Provides:
+- Lib contains the FlashLib sources.
+- Plugin contains plugin sources.
+- Player contains the standalone player sources.
+- Kflash a Flash KDE screen saver.
+
+New features:
+- Bug fixes.
+- 24 and 32 modes supported.
+- Flash Library as screen saver (for xcreensaver and KDE).
+
+To get some information on this library check out the following link :
+http://www.swift-tools.com/Flash
+
+Authors: Olivier Debon <odebon@club-internet.fr>
+ Fabrice Bellard <fabrice.bellard@netgem.com>
+
+FEATURES
+--------
+
+Limitations :
+ - The plugin and the player use XShm extensions, so remote display is not possible.
+ - No Flash 4 features (but no crash on Flash 4 files).
+
+Not functional :
+ - No Morphing.
+ - No vertical anti-aliasing.
+
+SOUND SUPPORT
+-------------
+
+Limitations :
+ - No streamed sound supported (interleaved data).
+ - No sound envelop. So no fading or balancing effect.
+
+But the main feature is here and sound can be enjoyed.
+
+I recommend OSS drivers, but it is not required at all
+(http://www.opensound.com)
+
+If you have troubles with sound put the -DNOSOUND option
+for compilation. Also do this for non-Linux Unix.
+
+THE PLAYER
+----------
+
+The standalone player can simply control movie by
+pressing Q to quit, P to pause, C to continue and
+R to replay.
+There is also the possibility to zoom in or out
+and scroll using Keypad +/- and cursor keys, but
+it is buggy on frozen images.
+
+THE SCREEN SAVERS
+-----------------
+
+The standalone player can be run though xscreensaver. Modify
+your .xscreensaver file to add swfplayer:
+programs: swfplayer -root /home/olivier/Flash/Test/test.swf
+(See xscreensaver doc for more details on Xscreensaver).
+
+For KDE, just install the kflash.kss file from the Kflash
+directory in /usr/bin (or where your KDE installation expects
+kss file to be).
+In your KDE start menu, select Settings->Desktop->Screensaver
+Choose 'Flash Movies' and click on SetUp button. You'll have
+to select a Flash file (take the test.swf file provided with
+this distribution). The fullscreen option will scale the movie
+to the entire screen (it can be very CPU intensive). The
+enable sound option will allow to play sounds, but as a screen
+saver mode this is not a good idea :)
+
+BUG REPORT
+----------
+
+If Netscape crashes when it started to play a Flash file, please
+report the complete url where you have found the file.
+Do not send the actual file !
+
+If you have rendering problem also report the url.
+
+If the plugin does not seem to show anything or does not do what it
+is supposed to do, please consider that the plugin does not support
+all Flash 2/4 features. Anyway it tries to play it but may fail then.
+
+COMPILATION
+-----------
+
+If you use Linux just type 'make'.
+
+Warning : the plugin compilation should not fail, but you may
+have problem with Netscape at startup. See INSTALLATION section
+for workarounds.
+
+For other Unices like FreeBSD or Solaris you may have to change
+some flags. See Plugin/Makefile for hints.
+
+INSTALLATION
+------------
+
+Once you have successfully compiled the plugin, put the file
+npflash.so (located in the Plugin directory) into your
+~/.netscape/plugins directory or into the system-wide
+/opt/netscape/plugins directory (depends on where you have installed
+Netscape).
+
+If Netscape already runs type 'javascript:navigator.plugins.refresh'
+in the Location field.
+
+ PROBLEMS
+ --------
+
+If you have problem to successfully install the plugin, please
+read the following hints. Otherwise, report the problem with full
+description of your configuration :
+- Distribution.
+- Compiler.
+- Libs (the output of ldconfig -p is useful).
+- The netscape version and the output of 'ldd netscape'.
+
+If some symbols like _rtti or _throw are unresolved, it seems
+that you have egcs. Just uncomment the proper line in the main
+Makefile.
+You may then still have some unresolved symbols like __sigsetjmp.
+This time, add -DC6R5 in the Plugin/Makefile at the PLUGIN_DEFINES
+line.
+
+ CHECKING
+ --------
+
+To verify that the plugin is installed properly, type "about:plugins"
+in Netscape's "Location:" or "Netsite:" field. The plugin should show
+up there, something like
+
+___________________________________________________________________________
+
+ Shockwave Flash
+
+ File name: /opt/netscape/plugins/npflash.so
+
+ Flash file player Version 0.4.10
+
+ Shockwave is a trademark of Macromedia®
+
+ Author: Olivier Debon
+
+ ---------------------------------------------------------------------------------
+| Mime Type | Description | Suffixes | Enabled |
+|--------------------------------+-------------------+-------------+--------------|
+| application/futuresplash | Flash Plugin | spl | Yes |
+| application/x-shockwave-flash | | swf | Yes |
+ ---------------------------------------------------------------------------------
+
+___________________________________________________________________________
+
+
+If it shows up, but the "Enabled" column says "No", you need to
+configure the Flash plugin as a helper application. Go to
+Edit/Preferences/Navigator/Applications, and add it as follows:
+
+Description: Flash Plugin
+MIME Type: application/x-shockwave-flash
+Suffixes: swf
+Handled By: Plug In (select "Shockwave Flash")
+
+------
diff --git a/core/multimedia/opieplayer/libflash/adpcm.cc b/core/multimedia/opieplayer/libflash/adpcm.cc
new file mode 100644
index 0000000..a4bc435
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/adpcm.cc
@@ -0,0 +1,235 @@
+
+#include "swf.h"
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+// This file has been rearranged from the code posted
+// on news:forums.macromedia.com by Jonathan Gay.
+// Courtesy of Macromedia
+
+//
+// ADPCM tables
+//
+
+static const int indexTable2[2] = {
+ -1, 2,
+};
+
+// Is this ok?
+static const int indexTable3[4] = {
+ -1, -1, 2, 4,
+};
+
+static const int indexTable4[8] = {
+ -1, -1, -1, -1, 2, 4, 6, 8,
+};
+
+static const int indexTable5[16] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16,
+};
+
+static const int* indexTables[] = {
+ indexTable2,
+ indexTable3,
+ indexTable4,
+ indexTable5
+};
+
+static const int stepsizeTable[89] = {
+ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
+ 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
+ 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
+ 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
+ 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
+ 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
+ 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
+ 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
+ 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
+};
+
+long
+Adpcm::GetBits(int n)
+{
+ if ( bitPos < n ) FillBuffer();
+
+ assert(bitPos >= n);
+
+ long v = ((unsigned long)bitBuf << (32-bitPos)) >> (32-n);
+ bitPos -= n;
+
+ return v;
+}
+
+long
+Adpcm::GetSBits(int n)
+{
+ if ( bitPos < n ) FillBuffer();
+
+ assert(bitPos >= n);
+
+ long v = ((long)bitBuf << (32-bitPos)) >> (32-n);
+ bitPos -= n;
+
+ return v;
+}
+
+//
+// The Decompressor
+//
+
+// Constructor
+Adpcm::Adpcm(unsigned char *buffer, long isStereo)
+{
+ stereo = isStereo;
+ src = buffer;
+
+ nBits = 0; // flag that it is not inited
+ nSamples = 0;
+
+ bitPos = 0;
+ bitBuf = 0;
+}
+
+void
+Adpcm::FillBuffer()
+{
+ while ( bitPos <= 24 /*&& srcSize > 0*/ ) {
+ bitBuf = (bitBuf<<8) | *src++;
+ bitPos += 8;
+ }
+}
+
+void
+Adpcm::Decompress(short *dst, long n)
+{
+ if ( nBits == 0 ) {
+ // Get the compression header
+ nBits = (int)GetBits(2)+2;
+ }
+
+ const int* indexTable = indexTables[nBits-2];
+ int k0 = 1 << (nBits-2);
+ int signmask = 1 << (nBits-1);
+
+ if ( !stereo ) {
+ // Optimize for mono
+ long vp = valpred[0]; // maybe these can get into registers...
+ int ind = index[0];
+ long ns = nSamples;
+
+ while ( n-- > 0 ) {
+ ns++;
+
+ if ( (ns & 0xFFF) == 1 ) {
+ // Get a new block header
+ *dst++ = (short)(vp = GetSBits(16));
+
+ ind = (int)GetBits(6); // The first sample in a block does not have a delta
+ } else {
+ // Process a delta value
+ int delta = (int)GetBits(nBits);
+
+ // Compute difference and new predicted value
+ // Computes 'vpdiff = (delta+0.5)*step/4'
+ int step = stepsizeTable[ind];
+ long vpdiff = 0;
+ int k = k0;
+
+ do {
+ if ( delta & k )
+ vpdiff += step;
+ step >>= 1;
+ k >>= 1;
+ } while ( k );
+
+ vpdiff += step; // add 0.5
+
+ if ( delta & signmask ) // the sign bit
+ vp -= vpdiff;
+ else
+ vp += vpdiff;
+
+ // Find new index value
+ ind += indexTable[delta&(~signmask)];
+
+ if ( ind < 0 )
+ ind = 0;
+ else if ( ind > 88 )
+ ind = 88;
+
+ // clamp output value
+ if ( vp != (short)vp )
+ vp = vp < 0 ? -32768 : 32767;
+
+ /* Step 7 - Output value */
+ *dst++ = (short)vp;
+ }
+ }
+
+ valpred[0] = vp;
+ index[0] = ind;
+ nSamples = ns;
+
+ } else {
+ int sn = stereo ? 2 : 1;
+
+ // Stereo
+ while ( n-- > 0 ) {
+
+ nSamples++;
+
+ if ( (nSamples & 0xFFF) == 1 ) {
+ // Get a new block header
+ for ( int i = 0; i < sn; i++ ) {
+
+ *dst++ = (short)(valpred[i] = GetSBits(16));
+
+ // The first sample in a block does not have a delta
+ index[i] = (int)GetBits(6);
+ }
+ } else {
+ // Process a delta value
+ for ( int i = 0; i < sn; i++ ) {
+ int delta = (int)GetBits(nBits);
+
+ // Compute difference and new predicted value
+ // Computes 'vpdiff = (delta+0.5)*step/4'
+
+ int step = stepsizeTable[index[i]];
+ long vpdiff = 0;
+ int k = k0;
+
+ do {
+ if ( delta & k ) vpdiff += step;
+ step >>= 1;
+ k >>= 1;
+ } while ( k );
+ vpdiff += step; // add 0.5
+
+
+ if ( delta & signmask ) // the sign bit
+ valpred[i] -= vpdiff;
+ else
+ valpred[i] += vpdiff;
+
+ // Find new index value
+ index[i] += indexTable[delta&(~signmask)];
+
+ if ( index[i] < 0 )
+ index[i] = 0;
+ else if ( index[i] > 88 )
+ index[i] = 88;
+
+ // clamp output value
+ if ( valpred[i] != (short)valpred[i] )
+ valpred[i] = valpred[i] < 0 ? -32768 : 32767;
+
+ /* Step 7 - Output value */
+ *dst++ = (short)valpred[i];
+ }
+ }
+ }
+ }
+}
diff --git a/core/multimedia/opieplayer/libflash/adpcm.h b/core/multimedia/opieplayer/libflash/adpcm.h
new file mode 100644
index 0000000..5714c0c
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/adpcm.h
@@ -0,0 +1,36 @@
+#ifndef _ADPCM_H_
+#define _ADPCM_H_
+
+class Adpcm {
+
+ // Destination format - note we always decompress to 16 bit
+ long stereo;
+ int nBits; // number of bits in each sample
+
+ long valpred[2]; // Current state
+ int index[2];
+
+ long nSamples; // number of samples decompressed so far
+
+ // Parsing Info
+ unsigned char *src;
+ long bitBuf; // this should always contain at least 24 bits of data
+ int bitPos;
+
+ void FillBuffer();
+
+ long GetBits(int n);
+
+ long GetSBits(int n);
+
+public:
+ Adpcm(unsigned char *buffer, long isStereo);
+
+ void Decompress(short * dst, long n); // return number of good samples
+#ifdef DUMP
+ void dump(BitStream *bs);
+ void Compress(short *pcm, long n, int bits);
+#endif
+};
+
+#endif /* _ADPCM_H_ */
diff --git a/core/multimedia/opieplayer/libflash/bitmap.cc b/core/multimedia/opieplayer/libflash/bitmap.cc
new file mode 100644
index 0000000..03b4588
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/bitmap.cc
@@ -0,0 +1,606 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+static unsigned char *inputData;
+
+// Class variables
+
+int Bitmap::haveTables = 0;
+
+struct jpeg_decompress_struct Bitmap::jpegObject;
+
+struct jpeg_source_mgr Bitmap::jpegSourceManager;
+
+MyErrorHandler Bitmap::jpegErrorMgr;
+
+Bitmap::Bitmap(long id, int level) : Character(BitmapType, id )
+{
+ pixels = NULL;
+ alpha_buf = NULL;
+ colormap = NULL;
+ nbColors = 0;
+ defLevel = level;
+}
+
+Bitmap::~Bitmap()
+{
+ if (pixels) {
+ delete[] pixels;
+ }
+ if (alpha_buf) {
+ delete[] alpha_buf;
+ }
+ if (colormap)
+ {
+ delete colormap;
+ }
+ if (haveTables) {
+ jpeg_destroy_decompress(&jpegObject);
+ haveTables = 0;
+ }
+}
+
+static void errorExit(j_common_ptr info)
+{
+ (*info->err->output_message) (info);
+ longjmp(((MyErrorHandler *)info->err)->setjmp_buffer, 1);
+}
+
+// Methods for Source data manager
+static void initSource(struct jpeg_decompress_struct *cInfo)
+{
+ cInfo->src->bytes_in_buffer = 0;
+}
+
+static boolean fillInputBuffer(struct jpeg_decompress_struct *cInfo)
+{
+ cInfo->src->next_input_byte = inputData;
+ cInfo->src->bytes_in_buffer = 1;
+ inputData++;
+
+ return 1;
+}
+
+static void skipInputData(struct jpeg_decompress_struct *cInfo, long count)
+{
+ cInfo->src->bytes_in_buffer = 0;
+ inputData += count;
+}
+
+static boolean resyncToRestart(struct jpeg_decompress_struct *cInfo, int desired)
+{
+ return jpeg_resync_to_restart(cInfo, desired);
+}
+
+static void termSource(struct jpeg_decompress_struct *cInfo)
+{
+}
+
+long Bitmap::getWidth()
+{
+ return width;
+}
+
+long Bitmap::getHeight()
+{
+ return height;
+}
+
+Color *
+Bitmap::getColormap(long *n) {
+ if (n) *n = nbColors;
+ return colormap;
+}
+
+unsigned char *
+Bitmap::getPixels()
+{
+ return pixels;
+}
+
+// Read Tables and Compressed data to produce an image
+
+static int
+buildJpegAlpha(Bitmap *b, unsigned char *buffer)
+{
+ z_stream stream;
+ int status;
+ unsigned char *data;
+
+ data = new unsigned char[b->width*b->height];
+ if (data == NULL)
+ return -1;
+
+ stream.next_in = buffer;
+ stream.avail_in = 1;
+ stream.next_out = data;
+ stream.avail_out = b->width*b->height;
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+
+ status = inflateInit(&stream);
+
+ while (1) {
+ status = inflate(&stream, Z_SYNC_FLUSH) ;
+ if (status == Z_STREAM_END) {
+ break;
+ }
+ if (status != Z_OK) {
+ printf("Zlib data error : %s\n", stream.msg);
+ delete data;
+ return -1;
+ }
+ stream.avail_in = 1;
+ }
+
+ inflateEnd(&stream);
+
+ b->alpha_buf = data;
+
+ return 0;
+}
+
+int
+Bitmap::buildFromJpegInterchangeData(unsigned char *stream, int read_alpha, long offset)
+{
+ struct jpeg_decompress_struct cInfo;
+ struct jpeg_source_mgr mySrcMgr;
+ MyErrorHandler errorMgr;
+ JSAMPROW buffer[1];
+ unsigned char *ptrPix;
+ int stride;
+ long n;
+
+#if PRINT&1
+ printf("flash: loading jpeg (interchange)\n");
+#endif
+
+ // Kludge to correct some corrupted files
+ if (stream[1] == 0xd9 && stream[3] == 0xd8) {
+ stream[3] = 0xd9;
+ stream[1] = 0xd8;
+ }
+
+ // Setup error handler
+ cInfo.err = jpeg_std_error(&errorMgr.pub);
+ errorMgr.pub.error_exit = errorExit;
+
+ if (setjmp(errorMgr.setjmp_buffer)) {
+ // JPEG data Error
+ jpeg_destroy_decompress(&cInfo);
+ if (pixels) {
+ delete[] pixels;
+ pixels = NULL;
+ }
+ return -1;
+ }
+
+ // Set current stream pointer to stream
+ inputData = stream;
+
+ // Here it's Ok
+
+ jpeg_create_decompress(&cInfo);
+
+ // Setup source manager structure
+ mySrcMgr.init_source = initSource;
+ mySrcMgr.fill_input_buffer = fillInputBuffer;
+ mySrcMgr.skip_input_data = skipInputData;
+ mySrcMgr.resync_to_restart = resyncToRestart;
+ mySrcMgr.term_source = termSource;
+
+ // Set default source manager
+ cInfo.src = &mySrcMgr;
+
+ jpeg_read_header(&cInfo, FALSE);
+
+ jpeg_read_header(&cInfo, TRUE);
+ cInfo.quantize_colors = TRUE; // Create colormapped image
+ jpeg_start_decompress(&cInfo);
+
+ // Set objet dimensions
+ height = cInfo.output_height;
+ width = cInfo.output_width;
+ bpl = width;
+ pixels = new unsigned char [height*width];
+ if (pixels == NULL) {
+ jpeg_finish_decompress(&cInfo);
+ jpeg_destroy_decompress(&cInfo);
+ return -1;
+ }
+ ptrPix = pixels;
+
+ stride = cInfo.output_width * cInfo.output_components;
+
+ buffer[0] = (JSAMPROW)malloc(stride);
+
+ while (cInfo.output_scanline < cInfo.output_height) {
+
+ jpeg_read_scanlines(&cInfo, buffer, 1);
+
+ memcpy(ptrPix,buffer[0],stride);
+
+ ptrPix+= stride;
+ }
+
+ free(buffer[0]);
+
+ colormap = new Color[cInfo.actual_number_of_colors];
+ if (colormap == NULL) {
+ delete pixels;
+ jpeg_finish_decompress(&cInfo);
+ jpeg_destroy_decompress(&cInfo);
+ return -1;
+ }
+ nbColors = cInfo.actual_number_of_colors;
+
+ for(n=0; n < nbColors; n++)
+ {
+ colormap[n].red = cInfo.colormap[0][n];
+ colormap[n].green = cInfo.colormap[1][n];
+ colormap[n].blue = cInfo.colormap[2][n];
+ }
+
+ jpeg_finish_decompress(&cInfo);
+ jpeg_destroy_decompress(&cInfo);
+
+ if (read_alpha) {
+ if (buildJpegAlpha(this, stream + offset) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+// Read JPEG image using pre-loaded Tables
+
+int
+Bitmap::buildFromJpegAbbreviatedData(unsigned char *stream)
+{
+ JSAMPROW buffer[1];
+ unsigned char *ptrPix;
+ int stride;
+ long n;
+ int status;
+
+#if PRINT&1
+ printf("flash: loading jpeg (abbreviated)\n");
+#endif
+
+ // Set current stream pointer to stream
+ inputData = stream;
+
+ // Error handler
+ if (setjmp(jpegErrorMgr.setjmp_buffer)) {
+ // JPEG data Error
+ //jpeg_destroy_decompress(&jpegObject);
+ if (pixels) {
+ delete[] pixels;
+ pixels = NULL;
+ }
+ return -1;
+ }
+
+ // Here it's ok
+
+ jpeg_read_header(&jpegObject, TRUE);
+ jpegObject.quantize_colors = TRUE; // Create colormapped image
+ jpeg_start_decompress(&jpegObject);
+
+ // Set objet dimensions
+ height = jpegObject.output_height;
+ width = jpegObject.output_width;
+ bpl = width;
+ pixels = new unsigned char [height*width];
+ if (pixels == NULL) {
+ jpeg_finish_decompress(&jpegObject);
+ return -1;
+ }
+ ptrPix = pixels;
+
+ stride = jpegObject.output_width * jpegObject.output_components;
+
+ buffer[0] = (JSAMPROW)malloc(stride);
+
+ while (jpegObject.output_scanline < jpegObject.output_height) {
+
+ status = jpeg_read_scanlines(&jpegObject, buffer, 1);
+
+ memcpy(ptrPix,buffer[0],stride);
+
+ ptrPix+= stride;
+ }
+
+ free(buffer[0]);
+
+ colormap = new Color[jpegObject.actual_number_of_colors];
+ if (colormap == NULL) {
+ jpeg_finish_decompress(&jpegObject);
+ delete pixels;
+ return -1;
+ }
+ nbColors = jpegObject.actual_number_of_colors;
+
+ for(n=0; n < nbColors; n++)
+ {
+ colormap[n].red = jpegObject.colormap[0][n];
+ colormap[n].green = jpegObject.colormap[1][n];
+ colormap[n].blue = jpegObject.colormap[2][n];
+ }
+
+ status = jpeg_finish_decompress(&jpegObject);
+
+ return 0;
+}
+
+// Just init JPEG object and read JPEG Tables
+
+int
+Bitmap::readJpegTables(unsigned char *stream)
+{
+ if (haveTables) {
+ //Error, it has already been initialized
+ return -1;
+ }
+
+ // Setup error handler
+ jpegObject.err = jpeg_std_error(&jpegErrorMgr.pub);
+ jpegErrorMgr.pub.error_exit = errorExit;
+
+ if (setjmp(jpegErrorMgr.setjmp_buffer)) {
+ // JPEG data Error
+ jpeg_destroy_decompress(&jpegObject);
+ return -1;
+ }
+
+ // Set current stream pointer to stream
+ inputData = stream;
+
+ // Here it's Ok
+
+ jpeg_create_decompress(&jpegObject);
+
+ // Setup source manager structure
+ jpegSourceManager.init_source = initSource;
+ jpegSourceManager.fill_input_buffer = fillInputBuffer;
+ jpegSourceManager.skip_input_data = skipInputData;
+ jpegSourceManager.resync_to_restart = resyncToRestart;
+ jpegSourceManager.term_source = termSource;
+
+ // Set default source manager
+ jpegObject.src = &jpegSourceManager;
+
+ jpeg_read_header(&jpegObject, FALSE);
+
+ haveTables = 1;
+
+ return 0;
+}
+
+int
+Bitmap::buildFromZlibData(unsigned char *buffer, int width, int height, int format, int tableSize, int tableHasAlpha)
+{
+ z_stream stream;
+ int status;
+ unsigned char *data;
+ int elementSize;
+
+#if PRINT&1
+ printf("flash: loading with zlib\n");
+#endif
+
+ this->width = width;
+ this->height = height;
+ this->bpl = width;
+
+ if (tableHasAlpha) {
+ elementSize = 4; // Cmap is RGBA
+ } else {
+ elementSize = 3; // Cmap is RGB
+ }
+
+ stream.next_in = buffer;
+ stream.avail_in = 1;
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+
+ tableSize++;
+
+ // Uncompress Color Table
+ if (format == 3) {
+ unsigned char *colorTable;
+ long n;
+
+ // Ajust width for 32 bit padding
+ width = (width+3)/4*4;
+ this->width = width;
+ this->bpl = width;
+
+ depth = 1;
+ colorTable = new unsigned char[tableSize*elementSize];
+ if (colorTable == NULL) {
+ return -1;
+ }
+
+ stream.next_out = colorTable;
+ stream.avail_out = tableSize*elementSize;
+
+ inflateInit(&stream);
+
+ while (1) {
+ status = inflate(&stream, Z_SYNC_FLUSH);
+ if (status == Z_STREAM_END) {
+ break;
+ }
+ if (status != Z_OK) {
+ printf("Zlib cmap error : %s\n", stream.msg);
+ return -1;
+ }
+ stream.avail_in = 1;
+ // Colormap if full
+ if (stream.avail_out == 0) {
+ break;
+ }
+ }
+
+ nbColors = tableSize;
+
+ colormap = new Color[nbColors];
+ if (colormap == NULL) {
+ delete colorTable;
+ return -1;
+ }
+
+ for(n=0; n < nbColors; n++) {
+ colormap[n].red = colorTable[n*elementSize+0];
+ colormap[n].green = colorTable[n*elementSize+1];
+ colormap[n].blue = colorTable[n*elementSize+2];
+ if (tableHasAlpha) {
+ colormap[n].alpha = colorTable[n*elementSize+3];
+ }
+ }
+
+ delete colorTable;
+
+ } else if (format == 4) {
+ depth = 2;
+ width = (width+1)/2*2;
+ this->bpl = width;
+ } else if (format == 5) {
+ depth = 4;
+ }
+
+ data = new unsigned char[depth*width*height];
+ if (data == NULL) {
+ if (colormap) delete colormap;
+ return -1;
+ }
+
+ stream.next_out = data;
+ stream.avail_out = depth*width*height;
+
+ if (format != 3) {
+ status = inflateInit(&stream);
+ }
+
+ while (1) {
+ status = inflate(&stream, Z_SYNC_FLUSH) ;
+ if (status == Z_STREAM_END) {
+ break;
+ }
+ if (status != Z_OK) {
+ printf("Zlib data error : %s\n", stream.msg);
+ delete data;
+ return -1;
+ }
+ stream.avail_in = 1;
+ }
+
+ inflateEnd(&stream);
+
+ pixels = new unsigned char [height*width];
+ if (pixels == NULL) {
+ if (colormap) delete colormap;
+ delete data;
+ return -1;
+ }
+
+ if (format != 3) {
+ int n,c;
+ unsigned char r,g,b,a;
+ unsigned char *ptr;
+
+ r = g = b = a = 0; /* to supress warnings */
+
+ nbColors = 0;
+ colormap = new Color[256];
+ if (colormap == NULL) {
+ delete data;
+ delete pixels;
+ return -1;
+ }
+ memset(colormap, 0, 256 * sizeof(Color));
+ ptr = pixels;
+
+ for(n=0; n < width*height*depth; n+=depth,ptr++) {
+
+ switch (format) {
+ case 4:
+ a = 1;
+ r = (data[n] & 0x78)<<1;
+ g = ((data[n] & 0x03)<<6) | (data[n+1] & 0xc0)>>2;
+ b = (data[n+1] & 0x1e)<<3;
+ break;
+ case 5:
+ a = data[n];
+ // Reduce color dynamic range
+ r = data[n+1]&0xe0;
+ g = data[n+2]&0xe0;
+ b = data[n+3]&0xe0;
+ break;
+ }
+ for(c=0; c < nbColors; c++) {
+ if (r == colormap[c].red
+ && g == colormap[c].green
+ && b == colormap[c].blue) {
+ *ptr = c;
+ break;
+ }
+ }
+ if (c == nbColors) {
+ if (nbColors == 256) continue;
+ nbColors++;
+ if (nbColors == 256) {
+ //printf("Colormap entries exhausted. After %d scanned pixels\n", n/4);
+ }
+ colormap[c].alpha = a;
+ colormap[c].red = r;
+ colormap[c].green = g;
+ colormap[c].blue = b;
+ *ptr = c;
+ }
+ }
+ } else {
+ memcpy(pixels, data, width*height);
+ if (tableHasAlpha) {
+ int n;
+ unsigned char *ptr, *alpha;
+
+ alpha_buf = (unsigned char *)malloc(width*height);
+ ptr = data;
+ alpha = alpha_buf;
+ for(n=0; n < width*height; n++, ptr++, alpha++) {
+ *alpha = colormap[*ptr].alpha;
+ }
+ }
+ }
+
+ delete data;
+ return 0;
+}
+
diff --git a/core/multimedia/opieplayer/libflash/bitmap.h b/core/multimedia/opieplayer/libflash/bitmap.h
new file mode 100644
index 0000000..7925309
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/bitmap.h
@@ -0,0 +1,72 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _BITMAP_H_
+#define _BITMAP_H_
+
+struct MyErrorHandler {
+ struct jpeg_error_mgr pub;
+ jmp_buf setjmp_buffer;
+};
+
+class Bitmap : public Character {
+ public:
+ long width;
+ long height;
+ long bpl;
+ long depth;
+
+ unsigned char *pixels; // Array of Pixels
+ Color *colormap; // Array of color definitions
+ long nbColors;
+
+ unsigned char *alpha_buf; // Array of alpha values (no alpha if NULL)
+
+ int defLevel;
+
+// Class Variables
+
+ static int haveTables;
+ static struct jpeg_decompress_struct jpegObject;
+ static struct jpeg_source_mgr jpegSourceManager;
+ static MyErrorHandler jpegErrorMgr;
+
+public:
+ Bitmap(long id, int level = 1);
+ ~Bitmap();
+
+ // JPEG handling methods
+ int buildFromJpegInterchangeData(unsigned char *stream, int alpha, long offset); // Complete
+ int buildFromJpegAbbreviatedData(unsigned char *stream); // Abbreviated
+
+ // Class Method
+ static int readJpegTables(unsigned char *stream); // Tables Only
+
+ // ZLIB handling methods
+ int buildFromZlibData(unsigned char *buffer,
+ int width, int height,
+ int format, int tableSize, int tableHasAlpha);
+
+ long getWidth();
+ long getHeight();
+ Color *getColormap(long *n);
+ unsigned char *getPixels();
+};
+
+#endif /* _BITMAP_H_ */
diff --git a/core/multimedia/opieplayer/libflash/button.cc b/core/multimedia/opieplayer/libflash/button.cc
new file mode 100644
index 0000000..7d8369d
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/button.cc
@@ -0,0 +1,328 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+#define PRINT 0
+
+// Contructor
+
+Button::Button(long id, int level) : Character(ButtonType, id)
+{
+ defLevel = level;
+ actionRecords = 0;
+ buttonRecords = 0;
+ conditionList = 0;
+ reset();
+ isMenu = 0;
+ sound[0] = sound[1] = sound[2] = sound[3] = 0;
+}
+
+// Destructor
+
+Button::~Button()
+{
+ if (actionRecords) {
+ ActionRecord *ar,*del;
+ for(ar = actionRecords; ar;) {
+ del = ar;
+ ar = ar->next;
+ delete del;
+ }
+ }
+ if (buttonRecords) {
+ ButtonRecord *br,*del;
+ for(br = buttonRecords; br;) {
+ del = br;
+ br = br->next;
+ if (del->cxform)
+ delete del->cxform;
+ delete del;
+ }
+ }
+ if (conditionList) {
+ Condition *cond,*del;
+ for(cond = conditionList; cond;) {
+ ActionRecord *ar,*d;
+
+ for(ar = cond->actions; ar;) {
+ d = ar;
+ ar = ar->next;
+ delete d;
+ }
+
+ del = cond;
+ cond = cond->next;
+ delete del;
+ }
+ }
+}
+
+ButtonRecord *
+Button::getButtonRecords()
+{
+ return buttonRecords;
+}
+
+ActionRecord *
+Button::getActionRecords()
+{
+ return actionRecords;
+}
+
+Sound **
+Button::getSounds()
+{
+ return sound;
+}
+
+Condition *
+Button::getConditionList()
+{
+ return conditionList;
+}
+
+void
+Button::setButtonSound(Sound *s, int state)
+{
+ if (state >=0 && state < 4) {
+ sound[state] = s;
+ }
+}
+
+void
+Button::setButtonMenu(int menu)
+{
+ isMenu = menu;
+}
+
+void
+Button::addButtonRecord( ButtonRecord *br )
+{
+#if 0
+ /* SURTOUT PAS !!! */
+ ButtonRecord **l;
+
+ /* sort by layer */
+ l=&buttonRecords;
+ while (*l != NULL && (*l)->layer < br->layer) l = &(*l)->next;
+ br->next = *l;
+ *l = br;
+#else
+ br->next = 0;
+
+ if (buttonRecords == 0) {
+ buttonRecords = br;
+ } else {
+ ButtonRecord *current;
+
+ for(current = buttonRecords; current->next; current = current->next);
+
+ current->next = br;
+ }
+#endif
+}
+
+void
+Button::addCondition( long transition )
+{
+ Condition *condition;
+
+ condition = new Condition;
+ if (condition == NULL) return;
+
+ condition->transition = transition;
+ condition->next = conditionList;
+
+ // Move current actionRecords to this condition
+ condition->actions = actionRecords;
+ actionRecords = 0;
+
+ conditionList = condition;
+}
+
+void
+Button::addActionRecord( ActionRecord *ar )
+{
+ ar->next = 0;
+
+ if (actionRecords == 0) {
+ actionRecords = ar;
+ } else {
+ ActionRecord *current;
+
+ for(current = actionRecords; current->next; current = current->next);
+
+ current->next = ar;
+ }
+}
+
+void
+Button::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func)
+{
+ ButtonRecord *br;
+
+ for (br = buttonRecords; br; br = br->next)
+ {
+ if ((br->state & stateHitTest) && br->character /* Temporaire */) {
+ Matrix mat;
+
+ mat = (*matrix) * br->buttonMatrix;
+ br->character->getRegion(gd, &mat, id, scan_line_func);
+ }
+ }
+}
+
+int
+Button::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ButtonState renderState)
+{
+ ButtonRecord *br;
+ int sprite = 0;
+ Cxform *cxf = 0;
+
+#if PRINT==2
+ printf("Rendering Button %d for State(s) ", getTagId());
+#endif
+ for (br = buttonRecords; br; br = br->next)
+ {
+ if ((br->state & renderState) && br->character != NULL) {
+ Matrix mat;
+
+#if PRINT==2
+ printf("%d ", br->state);
+#endif
+ mat = (*matrix) * br->buttonMatrix;
+
+ if (cxform) {
+ cxf = cxform;
+ } else if (br->cxform) {
+ cxf = br->cxform;
+ }
+
+ if (br->character->execute(gd, &mat, cxf)) {
+ sprite = 1;
+ }
+ }
+ }
+#if PRINT==2
+ printf("\n");
+#endif
+ return sprite;
+}
+
+ActionRecord *
+Button::getActionFromTransition(ButtonState cur, ButtonState old)
+{
+ Condition *cond;
+ long mask;
+
+ if (old == cur) return NULL;
+
+ /* transitions */
+ mask = 0;
+ if (old == stateUp && cur == stateOver)
+ mask |= 0x001;
+ else if (old == stateOver && cur == stateUp)
+ mask |= 0x002;
+ else if (old == stateOver && cur == stateDown)
+ mask |= 0x004;
+ else if (old == stateDown && cur == stateOver)
+ mask |= 0x008;
+
+ if (!isMenu) {
+ /* push button transitions (XXX: not quite correct) */
+ if (old == stateDown && cur == stateUp)
+ mask = 0x010;
+ else if (old == stateUp && cur == stateDown)
+ mask = 0x020;
+ /* XXX: what is transition 0x040 ?? */
+ } else {
+ /* menu button transitions (XXX: not quite correct) */
+ if (old == stateUp && cur == stateDown)
+ mask = 0x080;
+ else if (old == stateDown && cur == stateUp)
+ mask = 0x100;
+ }
+
+ for (cond = conditionList; cond; cond = cond->next) {
+ if (cond->transition & mask) {
+ return cond->actions;
+ }
+ }
+ return 0;
+}
+
+void
+Button::getBoundingBox(Rect *bbox, DisplayListEntry *e)
+{
+ ButtonRecord *br;
+
+ bbox->reset();
+ for (br = buttonRecords; br; br = br->next)
+ {
+ if (br->state & e->renderState) {
+ if (br->character) {
+ Rect bb;
+
+ bb.reset();
+ br->character->getBoundingBox(&bb,e);
+ transformBoundingBox(bbox, &br->buttonMatrix, &bb, 0);
+ }
+ }
+ }
+}
+
+/* Get current render character, actually it should be a list of characters
+ so a DisplayList after all */
+Character *
+Button::getRenderCharacter(ButtonState state)
+{
+ ButtonRecord *br;
+
+ for (br = buttonRecords; br; br = br->next)
+ {
+ if (br->state & state) {
+ return br->character;
+ }
+ }
+ return 0;
+}
+
+void
+Button::updateButtonState(DisplayListEntry *e)
+{
+ ButtonRecord *br;
+
+ e->buttonCharacter = 0;
+ for (br = buttonRecords; br; br = br->next)
+ {
+ if (br->state & e->renderState) {
+ e->buttonCharacter = br->character;
+ e->buttonMatrix = br->buttonMatrix;
+ return;
+ }
+ }
+}
diff --git a/core/multimedia/opieplayer/libflash/button.h b/core/multimedia/opieplayer/libflash/button.h
new file mode 100644
index 0000000..75781b2
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/button.h
@@ -0,0 +1,88 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _BUTTON_H_
+#define _BUTTON_H_
+
+struct ButtonRecord {
+ ButtonState state;
+ Character *character;
+ long layer;
+ Matrix buttonMatrix;
+ Cxform *cxform;
+
+ struct ButtonRecord *next;
+};
+
+struct Condition {
+ long transition;
+ ActionRecord *actions;
+
+ Condition *next;
+};
+
+class Button : public Character {
+public:
+ long defLevel;
+
+ ButtonRecord *buttonRecords;
+ ActionRecord *actionRecords;
+ Condition *conditionList;
+
+ long isMenu;
+
+ Sound *sound[4];
+
+ Button(long id, int level = 1);
+ ~Button();
+ void addActionRecord( ActionRecord *ar );
+ void addButtonRecord( ButtonRecord *br );
+ void addCondition( long transition );
+ int execute(GraphicDevice *gd, Matrix *matrix,
+ Cxform *cxform, ButtonState renderState);
+ ActionRecord *getActionFromTransition(ButtonState currentState,
+ ButtonState old);
+ void getRegion(GraphicDevice *gd, Matrix *matrix,
+ void *id, ScanLineFunc scan_line_func);
+ ButtonRecord *getButtonRecords();
+ void setButtonSound(Sound *, int);
+ void setButtonMenu(int);
+
+ ActionRecord *getActionRecords();
+ Condition *getConditionList();
+ Sound **getSounds();
+
+ void getBoundingBox(Rect *bb, DisplayListEntry *);
+
+ void updateButtonState(DisplayListEntry *);
+ Character *getRenderCharacter(ButtonState state);
+
+ // Builtin
+ int isButton() {
+ return 1;
+ };
+
+#ifdef DUMP
+ void dump(BitStream *);
+ void dumpButtonRecords(BitStream *, int putCxform = 0);
+ void dumpButtonConditions(BitStream *);
+#endif
+};
+
+#endif /* _BUTTON_H_ */
diff --git a/core/multimedia/opieplayer/libflash/character.cc b/core/multimedia/opieplayer/libflash/character.cc
new file mode 100644
index 0000000..4b5ce36
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/character.cc
@@ -0,0 +1,233 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+///// Character member definitions
+
+Character::Character(ObjectType objectType, long tagid)
+{
+ type = objectType;
+ tagId = tagid;
+ name = NULL;
+}
+
+Character::~Character()
+{
+ delete name;
+}
+
+int
+Character::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
+{
+ printf("Cannot be executed\n");
+ return 0;
+}
+
+ActionRecord *
+Character::eventHandler(GraphicDevice *gd, FlashEvent *ev)
+{
+ fprintf(stderr,"Unable to handle event !!!\n");
+ return 0;
+}
+
+int
+Character::isButton()
+{
+ return 0;
+}
+
+int
+Character::isSprite(void)
+{
+ return 0;
+}
+
+char *
+Character::getName()
+{
+ return name;
+}
+
+void
+Character::getBoundingBox(Rect *bb, DisplayListEntry *e)
+{
+ //fprintf(stderr,"Unable to handle getBoundingBox !!!\n");
+ bb->xmin = LONG_MAX;
+ bb->ymin = LONG_MAX;
+ bb->ymax = LONG_MIN;
+ bb->ymax = LONG_MIN;
+ return;
+}
+
+void
+Character::getRegion(GraphicDevice *gd, Matrix *matrix,
+ void *id, ScanLineFunc scan_line_func)
+{
+ fprintf(stderr,"Unable to handle getRegion !!!\n");
+ return;
+}
+
+long
+Character::getTagId()
+{
+ return tagId;
+}
+
+void
+Character::reset()
+{
+}
+
+ObjectType
+Character::getType()
+{
+ return type;
+}
+
+char *
+Character::getTypeString()
+{
+ switch (type) {
+ case BitmapType:
+ return "Bitmap";
+ case FontType:
+ return "Font";
+ case ButtonType:
+ return "Button";
+ case SpriteType:
+ return "Sprite";
+ case ShapeType:
+ return "Shape";
+ case SoundType:
+ return "Sound";
+ case TextType:
+ return "Text";
+ default:
+ return "Unknown";
+ }
+}
+
+void
+Character::setName(char* string)
+{
+ name = strdup(string);
+}
+
+///// Dict methods definitions
+
+Dict::Dict()
+{
+ head = 0;
+}
+
+Dict::~Dict()
+{
+ struct sCharCell *cell,*del;
+
+ for(cell = head; cell;)
+ {
+ del = cell;
+ cell = cell->next;
+ delete del->elt;
+ delete del;
+ }
+}
+
+void
+Dict::addCharacter(Character *character)
+{
+ struct sCharCell *cell;
+
+ cell = new sCharCell;
+ if (cell == NULL) {
+ delete character;
+ return;
+ }
+ cell->elt = character;
+ cell->next = head;
+
+ head = cell;
+}
+
+Character *
+Dict::getCharacter(long id)
+{
+ struct sCharCell *cell;
+
+ for(cell = head; cell; cell = cell->next)
+ {
+ if (id == cell->elt->getTagId()) return cell->elt;
+ }
+ return 0;
+}
+
+void
+Dict::dictRewind()
+{
+ currentCell = head;
+}
+
+Character *
+Dict::dictNextCharacter()
+{
+ if (currentCell) {
+ struct sCharCell *cell;
+
+ cell = currentCell;
+ currentCell = currentCell->next;
+ return cell->elt;
+ } else {
+ return 0;
+ }
+}
+
+void
+Dict::nameCharacter(long id, char *string)
+{
+ struct sCharCell *cell;
+
+ for(cell = head; cell; cell = cell->next)
+ {
+ if (cell->elt->getTagId() == id) {
+ cell->elt->setName(string);
+ break;
+ }
+ }
+}
+
+#ifdef DUMP
+void
+Dict::dictSetUnsaved()
+{
+ struct sCharCell *cell;
+
+ for(cell = head; cell; cell = cell->next)
+ {
+ cell->elt->saved = 0;
+ }
+}
+#endif
diff --git a/core/multimedia/opieplayer/libflash/character.h b/core/multimedia/opieplayer/libflash/character.h
new file mode 100644
index 0000000..583cb17
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/character.h
@@ -0,0 +1,90 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _CHARACTER_H_
+#define _CHARACTER_H_
+
+enum ObjectType {
+ ShapeType,
+ TextType,
+ FontType,
+ SoundType,
+ BitmapType,
+ SpriteType,
+ ButtonType
+};
+
+class DisplayListEntry;
+
+// Character definition
+
+class Character {
+ long tagId;
+ ObjectType type;
+ char *name;
+
+public:
+ Character(ObjectType type, long tagId);
+ virtual ~Character();
+
+ virtual int execute(GraphicDevice *, Matrix *, Cxform *); // Display, play or whatever
+ virtual int isButton(void); // True if Character is a button
+ virtual int isSprite(void);
+ virtual ActionRecord *eventHandler(GraphicDevice *, FlashEvent *);
+ virtual void getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func);
+ virtual void reset(); // Reset internal state of object
+ virtual void getBoundingBox(Rect *bb, DisplayListEntry *de);
+#ifdef DUMP
+ virtual void dump(BitStream *main);
+
+ int saved;
+#endif
+
+ long getTagId(); // Return tagId
+ ObjectType getType();
+ char *getTypeString();
+ char *getName();
+ void setName(char *);
+};
+
+struct sCharCell {
+ Character *elt;
+ struct sCharCell *next;
+};
+
+class Dict {
+ struct sCharCell *head;
+ struct sCharCell *currentCell; // Iteration variable for dictNextCharacter
+
+public:
+ Dict();
+ ~Dict();
+
+ void addCharacter(Character *character);
+ void nameCharacter(long id, char *string);
+ Character *getCharacter(long id);
+ void dictRewind();
+ Character *dictNextCharacter();
+
+#ifdef DUMP
+ void dictSetUnsaved();
+#endif
+};
+
+#endif /* _CHARACTER_H_ */
diff --git a/core/multimedia/opieplayer/libflash/cxform.cc b/core/multimedia/opieplayer/libflash/cxform.cc
new file mode 100644
index 0000000..b448f5d
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/cxform.cc
@@ -0,0 +1,79 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#ifdef RCSID
+static char *rcsid = "$Id";
+#endif
+
+long
+Cxform::getRed(long v) {
+ long val;
+
+ val = (long)(ra*v+rb);
+ if (val > 255) val = 255;
+ else if (val < 0) val = 0;
+ return val;
+}
+
+long
+Cxform::getGreen(long v) {
+ long val;
+
+ val = (long)(ga*v+gb);
+ if (val > 255) val = 255;
+ else if (val < 0) val = 0;
+ return val;
+}
+
+long
+Cxform::getBlue(long v) {
+ long val;
+
+ val = (long)(ba*v+bb);
+ if (val > 255) val = 255;
+ else if (val < 0) val = 0;
+ return val;
+}
+
+long
+Cxform::getAlpha(long v) {
+ long val;
+
+ val = (long)(aa*v+ab);
+ if (val > 255) val = 255;
+ else if (val < 0) val = 0;
+ return val;
+}
+
+Color
+Cxform::getColor(Color color) {
+ Color newColor;
+
+ newColor.red = getRed(color.red);
+ newColor.green = getGreen(color.green);
+ newColor.blue = getBlue(color.blue);
+ newColor.alpha = getAlpha(color.alpha);
+
+ return newColor;
+}
diff --git a/core/multimedia/opieplayer/libflash/cxform.h b/core/multimedia/opieplayer/libflash/cxform.h
new file mode 100644
index 0000000..14f7189
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/cxform.h
@@ -0,0 +1,46 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _CXFORM_H_
+#define _CXFORM_H_
+
+struct Color {
+ unsigned char red,green,blue,alpha;
+ long pixel;
+};
+
+struct Cxform
+{
+ float aa; long ab; // a is multiply factor, b is addition factor
+ float ra; long rb;
+ float ga; long gb;
+ float ba; long bb;
+
+ long getRed(long v);
+ long getGreen(long v);
+ long getBlue(long v);
+ long getAlpha(long v);
+ Color getColor(Color color);
+
+#ifdef DUMP
+ void dump(BitStream *bs, int alpha = 0);
+#endif
+};
+
+#endif /* _CXFORM_H_ */
diff --git a/core/multimedia/opieplayer/libflash/displaylist.cc b/core/multimedia/opieplayer/libflash/displaylist.cc
new file mode 100644
index 0000000..d71cfb7
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/displaylist.cc
@@ -0,0 +1,708 @@
+////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+#define PRINT 0
+
+void deleteButton(FlashMovie *movie, DisplayListEntry *e)
+{
+ /* save the focus */
+ if (movie->mouse_active == 0 && e->renderState == stateOver) {
+ movie->lost_over = (Button *)e->character;
+ movie->cur_focus = NULL;
+ }
+
+ if (e == movie->cur_focus) {
+ movie->cur_focus = NULL;
+ }
+}
+
+void addButton(FlashMovie *movie, DisplayListEntry *e)
+{
+ if (movie->mouse_active == 0 &&
+ movie->cur_focus == NULL &&
+ movie->lost_over == (Button *)e->character) {
+ /* restore the lost focus */
+ e->renderState = stateOver;
+ e->oldState = stateOver;
+ ((Button *)e->character)->updateButtonState(e);
+ movie->lost_over = NULL;
+ movie->cur_focus = e;
+ }
+}
+
+DisplayList::DisplayList(FlashMovie *movie)
+{
+ list = NULL;
+ this->movie = movie;
+ bbox.reset();
+ isSprite = 0;
+}
+
+DisplayList::~DisplayList()
+{
+ clearList();
+}
+
+void
+DisplayList::clearList()
+{
+ DisplayListEntry *del, *e;
+
+ for(e = list; e;)
+ {
+ updateBoundingBox(e);
+ if (e->character->isButton()) {
+ deleteButton(movie,e);
+ }
+ del = e;
+ e = e->next;
+ delete del;
+ }
+ list = 0;
+}
+
+DisplayListEntry *
+DisplayList::getList()
+{
+ return list;
+}
+
+static void bbox(Rect *rect, Matrix *m, long x1, long y1)
+{
+ long x,y;
+
+ x = m->getX(x1,y1);
+ y = m->getY(x1,y1);
+ if (x < rect->xmin) rect->xmin = x;
+ if (x > rect->xmax) rect->xmax = x;
+ if (y < rect->ymin) rect->ymin = y;
+ if (y > rect->ymax) rect->ymax = y;
+}
+
+// Update bb to include boundary, optional reset of bb
+void transformBoundingBox(Rect *bb, Matrix *matrix, Rect *boundary, int reset)
+{
+ if (reset) {
+ bb->reset();
+ }
+
+ if (boundary->xmin != LONG_MAX) {
+ bbox(bb, matrix, boundary->xmin, boundary->ymin);
+ bbox(bb, matrix, boundary->xmax, boundary->ymin);
+ bbox(bb, matrix, boundary->xmin, boundary->ymax);
+ bbox(bb, matrix, boundary->xmax, boundary->ymax);
+ }
+}
+
+void
+DisplayList::placeObject(GraphicDevice *gd,Character *character, long depth, Matrix *matrix, Cxform *cxform, char *name)
+{
+ DisplayListEntry *n,*e,*prev;
+
+ n = new DisplayListEntry;
+ if (n == NULL) return;
+
+ n->depth = depth;
+ n->matrix = matrix;
+ n->cxform = cxform;
+ n->character = character;
+ n->instanceName = name;
+ n->owner = this;
+
+#if 0
+ printf("Dl %lx: placeObject: depth=%d character=%d cxform=%p\n",
+ this, n->depth,n->character ? n->character->getTagId() : 0, cxform);
+#endif
+
+ if (character == 0 || matrix == 0 || cxform == 0) {
+ for (e = list; e; prev = e, e = e->next) {
+ if (e->depth == n->depth) {
+ if (character == 0) {
+ n->character = e->character;
+ }
+ if (matrix == 0) {
+ n->matrix = e->matrix;
+ }
+ if (cxform == 0) {
+ n->cxform = e->cxform;
+ }
+ break;
+ }
+ }
+ }
+
+ if (n->character == 0) {
+ // Not found !!! Should not happen
+ // printf("PlaceObject cannot find character at depth %ld\n", n->depth);
+ delete n;
+ return;
+ }
+
+ prev = 0;
+ for (e = list; e; prev = e, e = e->next)
+ {
+ if (e->depth == n->depth) {
+ if (e->character->isButton()) {
+ deleteButton(movie, e);
+ }
+
+ // Do update, object has moved or been resized
+ updateBoundingBox(e);
+
+ // Replace object
+ e->depth = n->depth;
+ e->matrix = n->matrix;
+ e->cxform = n->cxform;
+ e->character = n->character;
+ /* if it is a button, we must update its state */
+ if (e->character->isButton()) {
+ movie->buttons_updated = 1;
+ addButton(movie, e);
+ }
+
+ updateBoundingBox(e);
+
+ delete n;
+ return;
+ }
+ if (e->depth > n->depth) break;
+ }
+ /* new object */
+
+ /* button instantiation */
+ if (n->character->isButton()) {
+ n->renderState = stateUp;
+ n->oldState = stateUp;
+ ((Button *)n->character)->updateButtonState(n);
+ addButton(movie,n);
+ }
+
+ updateBoundingBox(n);
+
+ if (prev == 0) {
+ // Object comes at first place
+ n->next = list;
+ list = n;
+ } else {
+ // Insert object
+ n->next = prev->next;
+ prev->next = n;
+ }
+}
+
+
+Character *
+DisplayList::removeObject(GraphicDevice *gd,Character *character, long depth)
+{
+ DisplayListEntry *e,*prev;
+
+ // List should not be empty
+ if (list == 0) return 0;
+
+#if 0
+ printf("removeObject: depth=%d character=%d\n",
+ depth,character ? character->getTagId() : 0);
+#endif
+
+ prev = 0;
+ for (e = list; e; prev = e, e = e->next) {
+ if (e->depth == depth) {
+ if (prev) {
+ prev->next = e->next;
+ } else {
+ list = e->next;
+ }
+ if (character == 0) {
+ character = e->character;
+ }
+ if (e->character->isButton()) {
+ deleteButton(movie, e);
+ }
+ if (e->character->isSprite()) {
+ ((Sprite*)e->character)->reset();
+ }
+
+ updateBoundingBox(e);
+
+ delete e;
+ return character;
+ }
+ }
+ return 0; // Should not happen
+}
+
+void
+DisplayList::updateBoundingBox(DisplayListEntry *e)
+{
+ Rect rect;
+
+ //rect.reset();
+ e->character->getBoundingBox(&rect,e);
+ transformBoundingBox(&this->bbox, e->matrix, &rect, 0);
+}
+
+int
+DisplayList::updateSprites()
+{
+ Sprite *sprite;
+ DisplayListEntry *e;
+ int refresh = 0;
+
+ for (e = this->list; e != NULL; e = e->next) {
+ if (e->character->isButton() && e->buttonCharacter) {
+ if (e->buttonCharacter->isSprite()) {
+ Matrix mat;
+
+ sprite = (Sprite *)e->buttonCharacter;
+ refresh |= sprite->program->dl->updateSprites();
+ refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform);
+ mat = (*e->matrix) * e->buttonMatrix;
+ transformBoundingBox(&this->bbox, &mat,
+ &(sprite->program->dl->bbox),
+ 0);
+ }
+ }
+ if (e->character->isSprite()) {
+ sprite = (Sprite *)e->character;
+ refresh |= sprite->program->dl->updateSprites();
+ refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform);
+ transformBoundingBox(&this->bbox, e->matrix,
+ &(sprite->program->dl->bbox),
+ 0);
+ }
+ }
+ return refresh;
+}
+
+/* Function can return either 0,1 or 2
+ 0: Nothing match, continue
+ 1: Something matches, but continue searching
+ 2: Something matches, but stop searching
+*/
+
+static int exploreButtons1(Program *prg, void *opaque,
+ ExploreButtonFunc func)
+{
+ DisplayListEntry *e;
+ int ret, ret2 = 0;
+
+ for(e=prg->dl->list; e != NULL; e = e->next) {
+ if (e->character == NULL) continue;
+ if (e->character->isButton()) {
+ ret = func(opaque,prg,e);
+ if (ret == 2) return ret; // Func asks to return at once !!!
+ if (ret) ret2 = 1;
+ }
+ if (e->character->isSprite()) {
+ ret = exploreButtons1(((Sprite *)e->character)->program,
+ opaque,func);
+ if (ret == 2) return ret; // Func asks to return at once !!!
+ if (ret) ret2 = 1;
+ }
+ }
+ return ret2;
+}
+
+int exploreButtons(FlashMovie *movie, void *opaque, ExploreButtonFunc func)
+{
+ CInputScript *script;
+ int ret;
+
+ script = movie->main;
+ while (script != NULL) {
+ if (script->program) {
+ ret = exploreButtons1(script->program, opaque, func);
+ if (ret) return ret;
+ }
+ script = script->next;
+ }
+ return 0;
+}
+
+typedef struct {
+ long x,y;
+ int hit;
+ DisplayListEntry *bhit;
+} HitTable;
+
+static void button_hit_func(void *id, long y, long start, long end)
+{
+ HitTable *h = (HitTable *) id;
+ if ( y == h->y && (h->x >= start && h->x < end) )
+ h->hit = 1;
+}
+
+typedef struct {
+ FlashMovie *movie;
+ DisplayListEntry *bhit;
+} ButtonHit;
+
+static int button_hit(void *opaque, Program *prg, DisplayListEntry *e)
+{
+ ButtonHit *h = (ButtonHit *) opaque;
+ HitTable hit_table;
+ FlashMovie *movie = h->movie;
+ Rect bb,boundary;
+ Matrix mat;
+ ButtonState save;
+
+ hit_table.x = movie->mouse_x;
+ hit_table.y = movie->mouse_y / FRAC;
+ hit_table.hit = 0;
+
+ // Compute the bounding box in screen coordinates
+ save = e->renderState;
+ e->renderState = stateHitTest;
+ e->character->getBoundingBox(&boundary,e);
+ e->renderState = save;
+ mat = (*movie->gd->adjust) * e->renderMatrix;
+ transformBoundingBox(&bb, &mat, &boundary, 1);
+ // Check if mouse is within bb
+ if (movie->mouse_x < bb.xmin) return 0;
+ if (movie->mouse_x > bb.xmax) return 0;
+ if (movie->mouse_y < bb.ymin) return 0;
+ if (movie->mouse_y > bb.ymax) return 0;
+
+ e->character->getRegion(movie->gd, &e->renderMatrix,
+ &hit_table, button_hit_func);
+
+ if (hit_table.hit) {
+ h->bhit = e;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int button_reset(void *opaque, Program *prg, DisplayListEntry *e)
+{
+ if (e->renderState != stateUp) {
+ e->owner->updateBoundingBox(e);
+ e->oldState = e->renderState;
+ e->renderState = stateUp;
+ ((Button *)e->character)->updateButtonState(e);
+ e->owner->updateBoundingBox(e);
+ }
+ return 0;
+}
+
+/* update the button states according to the current mouse state & return the list of actions */
+void
+DisplayList::updateButtons(FlashMovie *movie)
+{
+ DisplayListEntry *bhit;
+ ButtonHit h;
+
+ if (movie->mouse_active) {
+
+ h.bhit = NULL;
+ h.movie = movie;
+
+ exploreButtons(movie, &h, button_hit);
+
+ bhit = h.bhit;
+
+ /* set every button to not hit */
+ exploreButtons(movie, NULL, button_reset);
+
+ if (bhit) {
+ ButtonState state;
+
+ if (movie->button_pressed) {
+ state = stateDown;
+ } else {
+ state = stateOver;
+ }
+ if (state != bhit->renderState) {
+ bhit->owner->updateBoundingBox(bhit);
+ bhit->renderState = state;
+ ((Button *)bhit->character)->updateButtonState(bhit);
+ bhit->owner->updateBoundingBox(bhit);
+ movie->cur_focus = bhit;
+ if (movie->cursorOnOff)
+ movie->cursorOnOff(1,movie->cursorOnOffClientData);
+ }
+ } else {
+ if (movie->cursorOnOff)
+ movie->cursorOnOff(0,movie->cursorOnOffClientData);
+ }
+ }
+}
+
+typedef struct {
+ ActionRecord *action; // Action to do
+ Program *prg; // Context program
+} ButtonAction;
+
+static int button_action(void *opaque, Program *prg, DisplayListEntry *e)
+{
+ ButtonAction *h = (ButtonAction *)opaque;
+ static ActionRecord actionRefresh;
+ static ActionRecord soundFx;
+ Button *b;
+ ActionRecord **paction;
+ int n;
+
+ actionRefresh.action = ActionRefresh;
+ actionRefresh.next = 0;
+
+ soundFx.action = ActionPlaySound;
+ soundFx.next = &actionRefresh;
+
+ b = (Button *)e->character;
+
+ if (e->oldState != e->renderState) {
+
+ paction = &actionRefresh.next;
+
+ if (b->conditionList) {
+ *paction = b->getActionFromTransition(e->renderState, e->oldState);
+ } else if (e->renderState == stateDown) {
+ /* if the button is pressed and
+ no condition list is defined*/
+ *paction = b->actionRecords;
+ }
+
+ switch(e->renderState) {
+ case stateUp:
+ n = 0;
+ break;
+ case stateOver:
+ n = 1;
+ break;
+ default:
+ /* case stateDown: */
+ n = 2;
+ break;
+ }
+
+ if (b->sound[n]) {
+ soundFx.sound = b->sound[n];
+ h->action = &soundFx;
+ } else {
+ h->action = &actionRefresh;
+ }
+
+ e->oldState = e->renderState;
+
+ h->prg = prg;
+ return 2;
+ }
+ h->action = 0; // Nothing to do about this
+ return 0;
+}
+
+int computeActions(FlashMovie *movie, Program **prg, ActionRecord **ar)
+{
+ ButtonAction h;
+
+ h.action = NULL;
+ exploreButtons(movie, &h, button_action);
+ if (h.action) {
+ *prg = h.prg;
+ *ar = h.action;
+ return 1;
+ }
+ return 0;
+}
+
+#define FOCUS_ZOOM 1.5
+/* in pixels */
+#define FOCUS_SIZE_MIN 50
+#define FOCUS_TRANSLATE 15
+
+int
+DisplayList::render(GraphicDevice *gd, Matrix *render_matrix, Cxform *cxform)
+{
+ DisplayListEntry *e,*cur_focus;
+ int sprite = 0;
+ long n = 0;
+ Cxform cxf,*cxf1;
+ Rect bb,boundary;
+
+ cur_focus = NULL;
+
+ /*
+ if (isSprite == 0) {
+ if (this->bbox.xmin == LONG_MAX) return 0;
+ gd->updateClippingRegion(&this->bbox, render_matrix);
+ gd->clearCanvas();
+ }
+ */
+
+ for (e = list; e; e = e->next)
+ {
+#if PRINT
+ printf("Character %3d @ %3d\n", e->character ? e->character->getTagId() : 0, e->depth);
+#endif
+ if (e->character) {
+ Matrix mat;
+
+ if (render_matrix) {
+ mat = *render_matrix;
+ }
+
+ if (e->matrix) {
+ mat = mat * (*e->matrix);
+ }
+
+ /* fast clipping */
+ // If object boundaries are outside current clip region give up with rendering
+ e->character->getBoundingBox(&boundary,e);
+ if (boundary.xmin != LONG_MAX) {
+ Matrix tmat;
+
+ tmat = (*gd->adjust) * mat;
+ transformBoundingBox(&bb, &tmat, &boundary, 1);
+
+ bb.xmin = bb.xmin >> FRAC_BITS;
+ bb.ymin = bb.ymin >> FRAC_BITS;
+ bb.xmax = (bb.xmax + FRAC - 1) >> FRAC_BITS;
+ bb.ymax = (bb.ymax + FRAC - 1) >> FRAC_BITS;
+
+ if (bb.xmin >= gd->clip_rect.xmax ||
+ bb.xmax <= gd->clip_rect.xmin ||
+ bb.ymin >= gd->clip_rect.ymax ||
+ bb.ymax <= gd->clip_rect.ymin) {
+ continue;
+ }
+ }
+
+ if (cxform == NULL) {
+ cxf1 = e->cxform;
+ }
+ else if (e->cxform == NULL) {
+ cxf1 = cxform;
+ }
+ else {
+ cxf1 = &cxf;
+ cxf.ra = cxform->ra * e->cxform->ra;
+ cxf.ga = cxform->ga * e->cxform->ga;
+ cxf.ba = cxform->ba * e->cxform->ba;
+ cxf.aa = cxform->aa * e->cxform->aa;
+
+ cxf.rb = (long)(cxform->ra * e->cxform->rb + cxform->rb);
+ cxf.gb = (long)(cxform->ga * e->cxform->gb + cxform->gb);
+ cxf.bb = (long)(cxform->ba * e->cxform->bb + cxform->bb);
+ cxf.ab = (long)(cxform->aa * e->cxform->ab + cxform->ab);
+ }
+
+ if (e->character->isButton()) {
+ Button *b = (Button *) e->character;
+
+ e->renderMatrix = mat;
+
+ if (e->renderState != stateUp && movie->mouse_active == 0) {
+ cur_focus = e;
+ ((Button *)e->character)->updateButtonState(e);
+ }
+
+ if (b->execute(gd, &mat, cxf1, e->renderState)) {
+ sprite = 1;
+ }
+ } else {
+ if (e->character->execute(gd, &mat, cxf1)) {
+ sprite = 1;
+ }
+ }
+
+ n++;
+ }
+ }
+
+#if 0
+ {
+ /* display the bounding box (debug) */
+ Matrix tmat;
+ long x1,x2,y1,y2;
+ Color white;
+
+ white.red = 255;
+ white.green = white.blue = 0;
+ gd->setForegroundColor(white);
+
+ if (render_matrix) {
+ tmat = (*gd->adjust) * (*render_matrix);
+ } else {
+ tmat = *gd->adjust;
+ }
+ x1 = bbox.xmin;
+ y1 = bbox.ymin;
+ x2 = bbox.xmax;
+ y2 = bbox.ymax;
+ gd->drawLine(tmat.getX(x1,y1),tmat.getY(x1,y1),tmat.getX(x2,y1),tmat.getY(x2,y1),10*FRAC);
+ gd->drawLine(tmat.getX(x2,y1),tmat.getY(x2,y1),tmat.getX(x2,y2),tmat.getY(x2,y2),10*FRAC);
+ gd->drawLine(tmat.getX(x2,y2),tmat.getY(x2,y2),tmat.getX(x1,y2),tmat.getY(x1,y2),10*FRAC);
+ gd->drawLine(tmat.getX(x1,y2),tmat.getY(x1,y2),tmat.getX(x1,y1),tmat.getY(x1,y1),10*FRAC);
+ bbox.print();
+ }
+#endif
+
+ // Reset clipping zone
+ bbox.reset();
+
+ return sprite;
+}
+
+void
+DisplayList::getBoundary(Rect *bb)
+{
+ DisplayListEntry *e;
+ Rect boundary;
+
+ bb->reset();
+ for (e = list; e; e = e->next)
+ {
+ if (e->character) {
+ e->character->getBoundingBox(&boundary,e);
+ transformBoundingBox(bb, e->matrix, &boundary, 0);
+ }
+ }
+}
+
+extern "C" {
+
+void dump_buttons(FlashHandle flashHandle)
+{
+#if 0
+ Rect rect;
+ DisplayListEntry *e;
+ FlashMovie *movie;
+
+ movie = (FlashMovie *)flashHandle;
+
+ for (e = movie->first_button; e; e = e->next_button) {
+ computeBBox(movie,&rect,e);
+ printf("button: id=%d pos=%d %d %d %d\n",
+ e->character->getTagId(),
+ rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ }
+#endif
+}
+
+}
diff --git a/core/multimedia/opieplayer/libflash/displaylist.h b/core/multimedia/opieplayer/libflash/displaylist.h
new file mode 100644
index 0000000..536f628
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/displaylist.h
@@ -0,0 +1,80 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _DISPLAYLIST_H_
+#define _DISPLAYLIST_H_
+
+class Character;
+class Program;
+
+struct DisplayList;
+
+// Display List management
+struct DisplayListEntry {
+ Character *character;
+ long depth;
+ Matrix *matrix;
+ Cxform *cxform;
+ char *instanceName;
+
+ /* button state */
+ ButtonState renderState;
+ ButtonState oldState;
+ Character *buttonCharacter;
+ Matrix buttonMatrix;
+ Matrix renderMatrix; /* last render matrix */
+
+ DisplayListEntry *next;
+
+ DisplayList *owner; // Parent
+};
+
+struct DisplayList {
+ DisplayListEntry *list;
+ FlashMovie *movie;
+ Rect bbox; // Delta clipping region
+ int isSprite;
+public:
+ DisplayList(FlashMovie *movie);
+ ~DisplayList();
+ DisplayListEntry *getList();
+ void clearList();
+ void placeObject(GraphicDevice *gd,Character *character, long depth, Matrix *matrix = 0, Cxform *cxform = 0, char *name = 0);
+ Character *removeObject(GraphicDevice *gd, Character *character, long depth);
+
+ int render(GraphicDevice *gd, Matrix *m = 0, Cxform *cxform = 0);
+ void updateBoundingBox(DisplayListEntry *);
+ void updateButtons (FlashMovie *);
+ void getBoundary(Rect *bb); // Returns boundary of current displayed objects
+ int updateSprites(); // Update sprites in the display list
+};
+
+typedef void (*DisplayListFunc)(DisplayListEntry *e, void *opaque);
+
+void updateButtons(FlashMovie *m);
+int computeActions(FlashMovie *m, Program **prog, ActionRecord **ar);
+void renderFocus(FlashMovie *movie);
+
+typedef int (*ExploreButtonFunc)(void *opaque, Program *prg, DisplayListEntry *e);
+int exploreButtons(FlashMovie *movie, void *opaque, ExploreButtonFunc func);
+void updateBoundingBox(DisplayListEntry *e);
+void transformBoundingBox(Rect *bb, Matrix *matrix, Rect *boundary, int reset);
+void updateButtonState(DisplayListEntry *e, ButtonState state);
+
+#endif /* _DISPLAYLIST_H_ */
diff --git a/core/multimedia/opieplayer/libflash/flash.cc b/core/multimedia/opieplayer/libflash/flash.cc
new file mode 100644
index 0000000..75d351c
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/flash.cc
@@ -0,0 +1,275 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+#include "graphic16.h"
+#include "graphic24.h"
+#include "graphic32.h"
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+// Interface with standard C
+extern "C" {
+
+FlashHandle
+FlashNew()
+{
+ FlashMovie *fh;
+
+ fh = new FlashMovie;
+
+ fh->main = new CInputScript;
+
+ return (FlashHandle)fh;
+}
+
+int
+FlashParse(FlashHandle flashHandle, int level, char *data, long size)
+{
+ FlashMovie *fh;
+ CInputScript *script;
+ int status = FLASH_PARSE_ERROR;
+
+ fh = (FlashMovie *)flashHandle;
+
+ for(script = fh->main; script != NULL; script = script->next) {
+ if (script->level == level) {
+ status = script->ParseData(fh, data, size);
+
+ if (status & FLASH_PARSE_START) {
+ fh->msPerFrame = 1000/fh->main->frameRate;
+ script->program->rewindMovie();
+ }
+ break;
+ }
+ }
+
+ return status;
+}
+
+void
+FlashGetInfo(FlashHandle flashHandle, struct FlashInfo *fi)
+{
+ FlashMovie *fh;
+
+ fh = (FlashMovie *)flashHandle;
+
+ fi->version = fh->main->m_fileVersion;
+ fi->frameRate = fh->main->frameRate;
+ fi->frameCount = fh->main->frameCount;
+ fi->frameWidth = fh->main->frameRect.xmax - fh->main->frameRect.xmin;
+ fi->frameHeight = fh->main->frameRect.ymax - fh->main->frameRect.ymin;
+}
+
+long FlashGraphicInit(FlashHandle flashHandle, FlashDisplay *fd)
+{
+ FlashMovie *fh;
+
+ fh = (FlashMovie *)flashHandle;
+
+ switch (fd->bpp) {
+ case 4:
+ fh->gd = new GraphicDevice32(fd);
+ break;
+ case 3:
+ fh->gd = new GraphicDevice24(fd);
+ break;
+ case 2:
+ fh->gd = new GraphicDevice16(fd);
+ break;
+ default:
+ fprintf(stderr, "Unsupported depth\n");
+ }
+
+ fh->gd->setMovieDimension(fh->main->frameRect.xmax - fh->main->frameRect.xmin,
+ fh->main->frameRect.ymax - fh->main->frameRect.ymin);
+
+ return 1; // Ok
+}
+
+void
+FlashSoundInit(FlashHandle flashHandle, char *device)
+{
+ FlashMovie *fh;
+
+ fh = (FlashMovie *)flashHandle;
+
+ fh->sm = new SoundMixer(device);
+}
+
+void
+FlashZoom(FlashHandle flashHandle, int zoom)
+{
+ FlashMovie *fh;
+
+ fh = (FlashMovie *)flashHandle;
+
+ fh->gd->setMovieZoom(zoom);
+}
+
+void
+FlashOffset(FlashHandle flashHandle, int x, int y)
+{
+ FlashMovie *fh;
+
+ fh = (FlashMovie *)flashHandle;
+
+ fh->gd->setMovieOffset(x,y);
+}
+
+long
+FlashExec(FlashHandle flashHandle, long flag,
+ FlashEvent *fe, struct timeval *wakeDate)
+{
+ FlashMovie *fh;
+ long wakeUp = 0;
+
+ fh = (FlashMovie *)flashHandle;
+
+ if (fh->main == NULL) return 0; // Not ready
+ if (fh->main->program == NULL) return 0; // Not ready
+ if (fh->main->program->nbFrames == 0) return 0; // Still not ready
+ if (fh->gd == 0) return 0;
+
+ switch (flag & FLASH_CMD_MASK) {
+ case FLASH_STOP:
+ fh->main->program->pauseMovie();
+ wakeUp = 0;
+ break;
+ case FLASH_CONT:
+ fh->main->program->continueMovie();
+ wakeUp = FLASH_STATUS_WAKEUP;
+ break;
+ case FLASH_REWIND:
+ fh->main->program->rewindMovie();
+ wakeUp = 0;
+ break;
+ case FLASH_STEP:
+ fh->main->program->nextStepMovie();
+ wakeUp = 0;
+ break;
+ }
+
+ if (flag & FLASH_WAKEUP) {
+ // Compute next wakeup time
+ gettimeofday(wakeDate,0);
+ wakeDate->tv_usec += fh->msPerFrame*1000;
+ if (wakeDate->tv_usec > 1000000) {
+ wakeDate->tv_usec -= 1000000;
+ wakeDate->tv_sec++;
+ }
+
+ // Play frame
+ wakeUp = fh->processMovie(fh->gd, fh->sm);
+ }
+
+ if (checkFlashTimer(&fh->scheduledTime)) {
+ if (fh->handleEvent(fh->gd, fh->sm, &fh->scheduledEvent)) {
+ wakeUp = 1;
+ }
+
+ setFlashTimer(&fh->scheduledTime, -1);
+ }
+
+ if (flag & FLASH_EVENT) {
+ wakeUp = fh->handleEvent(fh->gd, fh->sm, fe);
+ if (wakeUp) {
+ /* Wake up at once, except for mouse move (40 ms after) */
+ gettimeofday(wakeDate,0);
+ if (fe->type == FeMouseMove) {
+ wakeDate->tv_usec += 40*1000;
+ if (wakeDate->tv_usec > 1000000) {
+ wakeDate->tv_usec -= 1000000;
+ wakeDate->tv_sec++;
+ }
+ }
+ }
+ }
+
+ return wakeUp || (fh->scheduledTime.tv_sec != -1);
+}
+
+void FlashSetGetSwfMethod(FlashHandle flashHandle, void (*getSwf)(char *url, int level, void *clientData), void *clientData)
+{
+ FlashMovie *fh;
+
+ fh = (FlashMovie *)flashHandle;
+
+ fh->getSwf = getSwf;
+ fh->getSwfClientData = clientData;
+}
+
+
+void
+FlashSetCursorOnOffMethod(FlashHandle flashHandle, void (*cursorOnOff)(int , void *), void *clientData)
+{
+ FlashMovie *fh;
+
+ fh = (FlashMovie *)flashHandle;
+
+ fh->cursorOnOff = cursorOnOff;
+ fh->cursorOnOffClientData = clientData;
+}
+
+void
+FlashSetGetUrlMethod(FlashHandle flashHandle, void (*getUrl)(char *, char *, void *), void *clientData)
+{
+ FlashMovie *fh;
+
+ fh = (FlashMovie *)flashHandle;
+
+ fh->getUrl = getUrl;
+ fh->getUrlClientData = clientData;
+}
+
+void
+FlashClose(FlashHandle flashHandle)
+{
+ FlashMovie *fh;
+
+ fh = (FlashMovie *)flashHandle;
+
+ delete fh;
+}
+
+void
+FlashSettings(FlashHandle flashHandle, long settings)
+{
+ FlashMovie *fh;
+
+ fh = (FlashMovie *)flashHandle;
+
+ fh->main->program->modifySettings( settings );
+}
+
+int shape_size,shape_nb,shaperecord_size,shaperecord_nb,style_size,style_nb;
+
+void flash_dump(void)
+{
+ printf("flash: shape_size=%d (nb=%d)\n",shape_size,shape_nb);
+ printf("flash: shaperecord_size=%d (nb=%d)\n",shaperecord_size,shaperecord_nb);
+ printf("flash: style_size=%d (nb=%d)\n",style_size,style_nb);
+}
+
+}; /* end of extern C */
diff --git a/core/multimedia/opieplayer/libflash/flash.h b/core/multimedia/opieplayer/libflash/flash.h
new file mode 100644
index 0000000..9330713
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/flash.h
@@ -0,0 +1,129 @@
+/*///////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////// */
+#ifndef _FLASH_H_
+#define _FLASH_H_
+
+#define PLUGIN_NAME "Shockwave Flash"
+#define FLASH_VERSION_STRING "Version 0.4.10"
+
+/* Flags to pass to FlashExec */
+#define FLASH_WAKEUP 0x01
+#define FLASH_EVENT 0x02
+#define FLASH_CMD 0x04
+
+/* Mask to extract commands */
+#define FLASH_CMD_MASK 0xf0
+/* Commands */
+#define FLASH_STOP 0x10 /* Pause the movie */
+#define FLASH_CONT 0x20 /* Continue the movie after pause */
+#define FLASH_REWIND 0x30 /* Rewind the movie and pause */
+#define FLASH_STEP 0x40 /* Frame by frame operation */
+
+/* return codes of FlashExec */
+#define FLASH_STATUS_WAKEUP 0x01 /* FlashExec must be called again after a given time */
+
+struct FlashInfo {
+ long frameRate;
+ long frameCount;
+ long frameWidth;
+ long frameHeight;
+ long version;
+};
+
+/* Player settings */
+#define PLAYER_LOOP (1<<0)
+#define PLAYER_QUALITY (1<<1)
+#define PLAYER_MENU (1<<2)
+
+/* Parser status */
+#define FLASH_PARSE_ERROR 0
+#define FLASH_PARSE_START 1
+#define FLASH_PARSE_NEED_DATA 2
+#define FLASH_PARSE_EOM 4
+#define FLASH_PARSE_WAKEUP 8
+#define FLASH_PARSE_OOM 16 /* Out Of Memory */
+
+typedef void *FlashHandle;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+enum FlashEventType {
+ FeNone,
+ FeMouseMove,
+ FeButtonPress,
+ FeButtonRelease,
+ FeRefresh,
+ FeKeyPress,
+ /* internal events */
+ FeKeyRelease,
+};
+
+enum FlashKey {
+ FeKeyUp = 1,
+ FeKeyDown,
+ FeKeyLeft,
+ FeKeyRight,
+ FeKeyEnter,
+ FeKeyNext
+};
+
+
+
+typedef struct FlashEvent {
+ enum FlashEventType type;
+ int x,y; /* Mouse coordinates,
+ relative to upper-left window corner */
+ enum FlashKey key;
+} FlashEvent;
+
+typedef struct FlashDisplay {
+ void *pixels;
+ int bpl; /* bytes per line */
+ int width;
+ int height;
+ int depth;
+ int bpp;
+ int flash_refresh;
+ /* Clipping region */
+ int clip_x, clip_y;
+ int clip_width, clip_height;
+} FlashDisplay;
+
+extern FlashHandle FlashNew();
+extern void FlashGetInfo(FlashHandle fh, struct FlashInfo *fi);
+extern long FlashGraphicInit(FlashHandle fh, FlashDisplay *fd);
+extern void FlashSoundInit(FlashHandle fh, char *device);
+extern int FlashParse(FlashHandle fh, int level, char *data, long size);
+extern long FlashExec(FlashHandle fh, long flag, FlashEvent *fe, struct timeval *wakeDate);
+extern void FlashClose(FlashHandle fh);
+extern void FlashSetGetUrlMethod(FlashHandle flashHandle, void (*getUrl)(char *, char *, void *), void *);
+extern void FlashSetGetSwfMethod(FlashHandle flashHandle, void (*getSwf)(char *url, int level, void *clientData), void *clientData);
+extern void FlashSetCursorOnOffMethod(FlashHandle flashHandle, void (*cursorOnOff)(int , void *), void *clientData);
+extern void FlashZoom(FlashHandle fh, int zoom);
+extern void FlashOffset(FlashHandle fh, int x, int y);
+extern void FlashSettings(FlashHandle fh, long settings);
+
+#if defined(__cplusplus) || defined(c_plusplus)
+};
+#endif
+
+#endif /* _FLASH_H_ */
diff --git a/core/multimedia/opieplayer/libflash/font.cc b/core/multimedia/opieplayer/libflash/font.cc
new file mode 100644
index 0000000..d937276
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/font.cc
@@ -0,0 +1,105 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+SwfFont::SwfFont(long id) : Character(FontType, id)
+{
+ glyphs = 0;
+ nbGlyphs = 0;
+ name = NULL;
+ setFontName("Unknown");
+ flags = (FontFlags)0;
+ lookUpTable = 0;
+}
+
+SwfFont::~SwfFont()
+{
+ if (lookUpTable) {
+ delete lookUpTable;
+ }
+ delete name;
+ delete [] glyphs;
+}
+
+void
+SwfFont::setFontFlags(FontFlags f)
+{
+ flags = f;
+}
+
+char *
+SwfFont::getName()
+{
+ return name;
+}
+
+FontFlags
+SwfFont::getFlags()
+{
+ return flags;
+}
+
+long
+SwfFont::getNbGlyphs()
+{
+ return nbGlyphs;
+}
+
+Shape *
+SwfFont::getGlyph(long index)
+{
+ if (index >= nbGlyphs) return 0;
+ return &glyphs[index];
+}
+
+long
+SwfFont::getGlyphCode(long index)
+{
+ if (lookUpTable == 0 || index >= nbGlyphs) return 0;
+ return lookUpTable[index];
+}
+
+void
+SwfFont::setFontName(char *str)
+{
+ delete name;
+ name = new char[strlen(str)+1];
+ strcpy(name,str);
+}
+
+void
+SwfFont::setFontLookUpTable(long *lut)
+{
+ lookUpTable = lut;
+}
+
+void
+SwfFont::setFontShapeTable(Shape *shapes, long n)
+{
+ glyphs = shapes;
+ nbGlyphs = n;
+}
diff --git a/core/multimedia/opieplayer/libflash/font.h b/core/multimedia/opieplayer/libflash/font.h
new file mode 100644
index 0000000..bc151ca
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/font.h
@@ -0,0 +1,56 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _SWFFONT_H_
+#define _SWFFONT_H_
+
+class SwfFont : public Character {
+ Shape *glyphs; // Array
+ long nbGlyphs;
+ char *name;
+ FontFlags flags;
+ long *lookUpTable; // Array
+
+ // Font2
+ long ascent;
+ long descent;
+ long leading;
+
+public:
+ SwfFont(long id);
+ ~SwfFont();
+
+ void setFontShapeTable(Shape *shapes, long n);
+ void setFontName(char *str);
+ void setFontLookUpTable(long *lut);
+ void setFontFlags(FontFlags f);
+ long getGlyphCode(long index);
+ long getNbGlyphs();
+ Shape *getGlyph(long index);
+
+ char *getName();
+ FontFlags getFlags();
+
+#ifdef DUMP
+ void dump(BitStream *bs);
+ void dumpFontInfo(BitStream *bs);
+#endif
+};
+
+#endif /* _SWFFONT_H_ */
diff --git a/core/multimedia/opieplayer/libflash/graphic.cc b/core/multimedia/opieplayer/libflash/graphic.cc
new file mode 100644
index 0000000..f65011e
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/graphic.cc
@@ -0,0 +1,632 @@
+////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+#define PRINT 0
+
+// Public
+
+GraphicDevice::GraphicDevice(FlashDisplay *fd)
+{
+ flashDisplay = fd;
+
+ bgInitialized = 0;
+
+ // Reset flash refresh flag
+ flashDisplay->flash_refresh = 0;
+
+ /* 16 bits, RGB565 */
+ redMask = 0xF800;
+ greenMask = 0x07E0;
+ blueMask = 0x001F;
+
+ /* should be the actual window size */
+ targetWidth = fd->width;
+ targetHeight = fd->height;
+ bpl = fd->bpl;
+
+#if PRINT
+ printf("Target Width = %d\n", targetWidth);
+ printf("Target Height = %d\n", targetHeight);
+#endif
+
+ zoom = FRAC;
+ movieWidth = targetWidth;
+ movieHeight = targetHeight;
+
+ viewPort.xmin = 0;
+ viewPort.xmax = targetWidth-1;
+ viewPort.ymin = 0;
+ viewPort.ymax = targetHeight-1;
+
+ canvasBuffer = (unsigned char *) fd->pixels;
+
+ adjust = new Matrix;
+ foregroundColor.red = 0;
+ foregroundColor.green = 0;
+ foregroundColor.blue = 0;
+ foregroundColor.alpha = ALPHA_OPAQUE;
+
+ backgroundColor.red = 0;
+ backgroundColor.green = 0;
+ backgroundColor.blue = 0;
+ backgroundColor.alpha = ALPHA_OPAQUE;
+
+ showMore = 0;
+
+ setClipping(0); // Reset
+ setClipping(1);
+
+ /* polygon rasterizer : handle memory errors ! */
+
+ height = targetHeight;
+ segs = (Segment **)malloc(height * sizeof(Segment *));
+ memset(segs, 0, height * sizeof(Segment *));
+ ymin = height;
+ ymax = -1;
+
+ seg_pool = (Segment *)malloc(NB_SEGMENT_MAX * sizeof(Segment));
+ seg_pool_cur = seg_pool;
+}
+
+GraphicDevice::~GraphicDevice()
+{
+ free(segs);
+ free(seg_pool);
+
+ if (adjust) {
+ delete adjust;
+ }
+}
+
+Color *
+GraphicDevice::getColormap(Color *old, long n, Cxform *cxform)
+{
+ Color *newCmp;
+
+ newCmp = new Color[n];
+ if (newCmp == NULL) return NULL;
+
+ if (cxform) {
+ for(long i = 0; i < n; i++)
+ {
+ newCmp[i] = cxform->getColor(old[i]);
+ newCmp[i].pixel = allocColor(newCmp[i]);
+ }
+ } else {
+ for(long i = 0; i < n; i++)
+ {
+ newCmp[i] = old[i];
+ newCmp[i].pixel = allocColor(old[i]);
+ }
+ }
+
+ return newCmp;
+}
+
+long
+GraphicDevice::getHeight()
+{
+ return targetHeight;
+}
+
+long
+GraphicDevice::getWidth()
+{
+ return targetWidth;
+}
+
+Color
+GraphicDevice::getForegroundColor()
+{
+ return foregroundColor;
+}
+
+void
+GraphicDevice::setForegroundColor(Color color)
+{
+ foregroundColor = color;
+}
+
+Color
+GraphicDevice::getBackgroundColor()
+{
+ return backgroundColor;
+}
+
+int
+GraphicDevice::setBackgroundColor(Color color)
+{
+ if (bgInitialized == 0) {
+ backgroundColor = color;
+ clearCanvas();
+ bgInitialized = 1;
+ return 1;
+ }
+ return 0;
+}
+
+void
+GraphicDevice::setMovieDimension(long width, long height)
+{
+ float xAdjust, yAdjust;
+
+ movieWidth = width;
+ movieHeight = height;
+
+ xAdjust = (float)targetWidth*zoom/(float)width;
+ yAdjust = (float)targetHeight*zoom/(float)height;
+
+ if (xAdjust < yAdjust) {
+ adjust->a = xAdjust;
+ adjust->d = xAdjust;
+ adjust->ty = ((targetHeight*zoom) - (long)(height * xAdjust))/2;
+ viewPort.ymin = adjust->ty/zoom;
+ viewPort.ymax = targetHeight-viewPort.ymin-1;
+ } else {
+ adjust->a = yAdjust;
+ adjust->d = yAdjust;
+ adjust->tx = ((targetWidth*zoom) - (long)(width * yAdjust))/2;
+ viewPort.xmin = adjust->tx/zoom;
+ viewPort.xmax = targetWidth-viewPort.xmin-1;
+ }
+
+ if (viewPort.xmin < 0) viewPort.xmin = 0;
+ if (viewPort.ymin < 0) viewPort.ymin = 0;
+ if (viewPort.xmax >= targetWidth) viewPort.xmax = targetWidth-1;
+ if (viewPort.ymax >= targetHeight) viewPort.ymax = targetHeight-1;
+}
+
+void
+GraphicDevice::setMovieZoom(int z)
+{
+ z *= FRAC;
+ if (z <= 0 || z > 100) return;
+ zoom = z;
+ setMovieDimension(movieWidth,movieHeight);
+}
+
+void
+GraphicDevice::setMovieOffset(long x, long y)
+{
+ adjust->tx = -zoom*x;
+ adjust->ty = -zoom*y;
+}
+
+long
+GraphicDevice::clip(long &y, long &start, long &end)
+{
+ long xmin,xend;
+
+ if (y < clip_rect.ymin ||
+ y >= clip_rect.ymax) return 1;
+ if (end <= start)
+ return 1;
+ xmin = clip_rect.xmin * FRAC;
+ xend = clip_rect.xmax * FRAC;
+
+ if (end <= xmin || start >= xend) return 1;
+
+ if (start < xmin) start = xmin;
+ if (end > xend) end = xend;
+
+ return 0;
+}
+
+void
+GraphicDevice::drawBox(long x1, long y1, long x2, long y2)
+{
+ int i;
+
+ for(i=0;i<FRAC*2;i++) {
+ drawLine(x1+i, y1+i, x2-i, y1+i, 0);
+ drawLine(x1+i, y2-i, x2-i, y2-i, 0);
+
+ drawLine(x1+i, y1+i+1, x1+i, y2-i-1, 0);
+ drawLine(x2-i, y1+i+1, x2-i, y2-i-1, 0);
+ }
+}
+
+/* polygon rasteriser */
+
+inline Segment *
+GraphicDevice::allocSeg()
+{
+ Segment *seg;
+
+ if ( (seg_pool_cur - seg_pool) >= NB_SEGMENT_MAX )
+ return NULL;
+ seg = seg_pool_cur++;
+
+ return seg;
+}
+
+/* add a segment to the current path */
+void
+GraphicDevice::addSegment(long x1, long y1, long x2, long y2,
+ FillStyleDef *f0,
+ FillStyleDef *f1,
+ int aa)
+{
+ Segment *seg,**segs;
+ long dX, X, Y, ymin, ymax, tmp;
+ FillStyleDef *ff;
+
+ if ( y1 == y2 ) {
+ return;
+ }
+
+ if (y1 < y2) {
+ ymin = y1;
+ ymax = y2;
+ ff = f0;
+ f0 = f1;
+ f1 = ff;
+ } else {
+ ymin = y2;
+ ymax = y1;
+ tmp = x1;
+ x1 = x2;
+ x2 = tmp;
+ }
+
+ if (ymax>>FRAC_BITS < clip_rect.ymin) {
+ return;
+ }
+ if (ymin>>FRAC_BITS > clip_rect.ymax) {
+ return;
+ }
+
+ X = x1 << SEGFRAC;
+ dX = ((x2 - x1)<<SEGFRAC)/(ymax-ymin);
+
+ if (ymin < 0) {
+ X += dX * (-ymin);
+ ymin = 0;
+ }
+
+ Y = (ymin + (FRAC-1)) & ~(FRAC-1);
+ if (Y > ymax) {
+ //printf("Elimine @ y = %d ymin = %d, ymax = %d\n", Y, ymin, seg->ymax);
+ return;
+ }
+ X += dX * (Y-ymin);
+
+ Y >>= FRAC_BITS;
+ if (Y >= clip_rect.ymax) {
+ return;
+ }
+
+ seg = allocSeg();
+ if (seg == NULL) {
+ return;
+ }
+
+ seg->next = 0;
+ seg->nextValid = 0;
+ seg->aa = aa;
+ seg->ymax = ymax;
+ seg->x1 = x1;
+ seg->x2 = x2;
+ seg->X = X;
+ seg->dX = dX;
+ seg->fs[0] = f0;
+ seg->fs[1] = f1;
+
+ if (Y < this->ymin) this->ymin = Y;
+ ymax = (seg->ymax + FRAC - 1) >> FRAC_BITS;
+ if (ymax >= this->height) ymax = this->height-1;
+ if (ymax > this->ymax) this->ymax = ymax;
+
+ segs = this->segs;
+
+ if (segs[Y] == 0) {
+ segs[Y] = seg;
+ } else {
+ Segment *s,*prev;
+
+ prev = 0;
+ for(s = segs[Y]; s; prev = s, s = s->next) {
+ if (s->X > seg->X) {
+ if (prev) {
+ prev->next = seg;
+ seg->next = s;
+ } else {
+ seg->next = segs[Y];
+ segs[Y] = seg;
+ }
+ break;
+ }
+ }
+ if (s == 0) {
+ prev->next = seg;
+ seg->next = s;
+ }
+ }
+}
+
+inline Segment *
+GraphicDevice::progressSegments(Segment * curSegs, long y)
+{
+ Segment *seg,*prev;
+
+ // Update current segments
+ seg = curSegs;
+ prev = 0;
+ while(seg)
+ {
+ if ((y*FRAC) > seg->ymax) {
+ // Remove this segment, no more valid
+ if (prev) {
+ prev->nextValid = seg->nextValid;
+ } else {
+ curSegs = seg->nextValid;
+ }
+ seg = seg->nextValid;
+ } else {
+ seg->X += seg->dX * FRAC;
+ prev = seg;
+ seg = seg->nextValid;
+ }
+ }
+ return curSegs;
+}
+
+inline Segment *
+GraphicDevice::newSegments(Segment *curSegs, Segment *newSegs)
+{
+ Segment *s,*seg,*prev;
+
+ s = curSegs;
+ prev = 0;
+
+ // Check for new segments
+ for (seg = newSegs; seg; seg=seg->next)
+ {
+ // Place it at the correct position according to X
+ if (curSegs == 0) {
+ curSegs = seg;
+ seg->nextValid = 0;
+ } else {
+ for(; s; prev = s, s = s->nextValid)
+ {
+ if ( s->X > seg->X ||
+ ( (s->X == seg->X) &&
+ ( (seg->x1 == s->x1 && seg->dX < s->dX) ||
+ (seg->x2 == s->x2 && seg->dX > s->dX)
+ ))) {
+ // Insert before s
+ if (prev) {
+ seg->nextValid = s;
+ prev->nextValid = seg;
+ } else {
+ seg->nextValid = curSegs;
+ curSegs = seg;
+ }
+ break;
+ }
+ }
+ // Append at the end
+ if (s == 0) {
+ prev->nextValid = seg;
+ seg->nextValid = 0;
+ }
+ }
+
+ s = seg;
+ }
+
+ return curSegs;
+}
+
+#if 0
+static void
+printSeg(Segment *seg)
+{
+ /*
+ printf("Seg %08x : X = %5d, Ft = %d, Cl = %2x/%2x/%2x, Cr = %2x/%2x/%2x, x1=%5d, x2=%5d, ymin=%5d, ymax=%5d\n", seg,
+ seg->X>>SEGFRAC,
+ seg->right ? seg->right->type: -1,
+ seg->left ? seg->left->color.red : -1,
+ seg->left ? seg->left->color.green : -1,
+ seg->left ? seg->left->color.blue : -1,
+ seg->right ? seg->right->color.red : -1,
+ seg->right ? seg->right->color.green : -1,
+ seg->right ? seg->right->color.blue : -1,
+ seg->x1, seg->x2, seg->ymin, seg->ymax);
+ */
+}
+#endif
+
+inline void
+GraphicDevice::renderScanLine(long y, Segment *curSegs)
+{
+ Segment *seg;
+ long width;
+ int fi = 1;
+ FillStyleDef *f;
+
+ width = targetWidth * FRAC;
+
+ if (curSegs && curSegs->fs[0] && curSegs->fs[1] == 0) {
+ fi = 0;
+ }
+ for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid)
+ {
+ if (seg->nextValid->X <0) continue;
+ if ((seg->X>>SEGFRAC) > width) break;
+ f = seg->fs[fi];
+ if (f) {
+ switch (f->type) {
+ case f_Solid:
+ if (seg->aa) {
+ fillLineAA(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
+ } else {
+ fillLine(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
+ }
+ break;
+ case f_TiledBitmap:
+ case f_clippedBitmap:
+ fillLineBitmap(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
+ break;
+ case f_LinearGradient:
+ fillLineLG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
+ break;
+ case f_RadialGradient:
+ fillLineRG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
+ break;
+ case f_None:
+ break;
+ }
+ }
+ }
+}
+
+/* draw the current path */
+void
+GraphicDevice::drawPolygon(void)
+{
+ long y;
+ Segment *curSegs,*seg;
+
+ // no segments ?
+ if (this->ymax == -1)
+ return;
+
+ // Foreach scanline
+ curSegs = 0;
+ for(y=this->ymin; y <= this->ymax; y++) {
+
+ // Make X values progess and remove unuseful segments
+ curSegs = progressSegments(curSegs, y);
+
+ // Add the new segment starting at the y position.
+ curSegs = newSegments(curSegs, this->segs[y]);
+
+ // Render the scanline
+ if (this->scan_line_func == NULL) {
+ renderScanLine(y, curSegs);
+ } else {
+ for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid) {
+ if (seg->nextValid->X >= seg->X) {
+ scan_line_func(this->scan_line_func_id, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
+ }
+ }
+ }
+ }
+
+ /* free the segments */
+ memset(this->segs + this->ymin, 0,
+ (this->ymax - this->ymin + 1) * sizeof(Segment *));
+
+ this->ymax = -1;
+ this->ymin = this->height;
+
+ this->seg_pool_cur = this->seg_pool;
+}
+
+void
+GraphicDevice::updateClippingRegion(Rect *rect)
+{
+ if (!clipping) return;
+
+ transformBoundingBox(&clip_rect, adjust, rect, 1);
+ clip_rect.xmin >>= FRAC_BITS;
+ clip_rect.xmax >>= FRAC_BITS;
+ clip_rect.ymin >>= FRAC_BITS;
+ clip_rect.ymax >>= FRAC_BITS;
+
+ clip_rect.xmin-=2;
+ clip_rect.ymin-=2;
+ clip_rect.xmax+=2;
+ clip_rect.ymax+=2;
+
+ if (clip_rect.xmin < viewPort.xmin) clip_rect.xmin = viewPort.xmin;
+ if (clip_rect.xmax < viewPort.xmin) clip_rect.xmax = viewPort.xmin;
+ if (clip_rect.ymin < viewPort.ymin) clip_rect.ymin = viewPort.ymin;
+ if (clip_rect.ymax < viewPort.ymin) clip_rect.ymax = viewPort.ymin;
+
+ if (clip_rect.xmax > viewPort.xmax) clip_rect.xmax = viewPort.xmax;
+ if (clip_rect.ymax > viewPort.ymax) clip_rect.ymax = viewPort.ymax;
+ if (clip_rect.xmin > viewPort.xmax) clip_rect.xmin = viewPort.xmax;
+ if (clip_rect.ymin > viewPort.ymax) clip_rect.ymin = viewPort.ymax;
+}
+
+void
+GraphicDevice::setClipping(int value)
+{
+ clipping = value;
+ if (clipping == 0) {
+ // Reset region
+ clip_rect.xmin = viewPort.xmin;
+ clip_rect.xmax = viewPort.xmax;
+ clip_rect.ymin = viewPort.ymin;
+ clip_rect.ymax = viewPort.ymax;
+ }
+}
+
+// Virtual
+void
+GraphicDevice::clearCanvas()
+{
+}
+
+long
+GraphicDevice::allocColor(Color color)
+{
+ return 0;
+}
+
+void
+GraphicDevice::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
+{
+}
+
+void
+GraphicDevice::fillLineLG(Gradient *grad, long y, long start, long end)
+{
+}
+
+void
+GraphicDevice::fillLineRG(Gradient *grad, long y, long start, long end)
+{
+}
+
+void
+GraphicDevice::fillLine(FillStyleDef *f, long y, long start, long end)
+{
+}
+
+void
+GraphicDevice::fillLineAA(FillStyleDef *f, long y, long start, long end)
+{
+}
+
+void
+GraphicDevice::drawLine(long x1, long y1, long x2, long y2, long width)
+{
+}
diff --git a/core/multimedia/opieplayer/libflash/graphic.h b/core/multimedia/opieplayer/libflash/graphic.h
new file mode 100644
index 0000000..63ebd99
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/graphic.h
@@ -0,0 +1,174 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _GRAPHIC_H_
+#define _GRAPHIC_H_
+
+#define ALPHA_OPAQUE 255
+
+enum FillType {
+ f_Solid = 0x00,
+ f_LinearGradient = 0x10,
+ f_RadialGradient = 0x12,
+ f_TiledBitmap = 0x40,
+ f_clippedBitmap = 0x41,
+ f_None = 0x80
+};
+
+struct Gradient {
+ int nbGradients;
+ unsigned char ratio[8];
+ Color color[8];
+ // For rendering
+ Color *ramp;
+ Matrix imat;
+ int has_alpha;
+};
+
+
+struct FillStyleDef {
+ FillType type; // See enum FillType
+
+ // Solid
+ Color color;
+
+ // Gradient
+ Gradient gradient;
+
+ // Bitmap
+ Bitmap *bitmap;
+ Matrix bitmap_matrix;
+ Color *cmap;
+ unsigned char *alpha_table;
+
+ // Gradient or Bitmap
+ Matrix matrix;
+
+ FillStyleDef() {
+ style_size += sizeof(FillStyleDef);
+ style_nb++;
+ }
+};
+
+struct Segment {
+ long x1,x2;
+ long ymax;
+ FillStyleDef *fs[2]; // 0 is left 1 is right
+ int aa;
+ long dX;
+ long X;
+
+ struct Segment *next;
+ struct Segment *nextValid;
+};
+
+/* fractional bits (we don't use twips here... too expensive) */
+#define FRAC_BITS 5
+#define FRAC (1 << FRAC_BITS)
+#define NB_SEGMENT_MAX (2048*4)
+#define SEGFRAC 8
+
+class GraphicDevice {
+ int targetWidth;
+ int targetHeight;
+ Rect viewPort;
+ int movieWidth;
+ int movieHeight;
+ int zoom;
+ unsigned long redMask;
+ unsigned long greenMask;
+ unsigned long blueMask;
+ int clipping;
+
+public:
+ FlashDisplay *flashDisplay;
+ int bgInitialized;
+ Color backgroundColor;
+ Color foregroundColor;
+
+public:
+ void *scan_line_func_id;
+ ScanLineFunc scan_line_func;
+ Rect clip_rect;
+
+private:
+ Segment **segs;
+ int ymin,ymax;
+ int height;
+ Segment *seg_pool;
+ Segment *seg_pool_cur;
+
+ Segment * allocSeg();
+ Segment * progressSegments(Segment * curSegs, long y);
+ Segment * newSegments(Segment *curSegs, Segment *newSegs);
+ void renderScanLine(long y, Segment *curSegs);
+
+protected:
+ long clip(long &y, long &start, long &end);
+
+public:
+ Matrix *adjust; // Matrix to fit window (shrink or expand)
+
+ long showMore; // Used for debugging
+
+ // For Direct Graphics
+ unsigned char *canvasBuffer; // A pointer to canvas'memory
+ long bpl; // Bytes per line
+ long bpp; // Bytes per pixel
+ long pad; // Scanline pad in byte
+
+ GraphicDevice(FlashDisplay *fd);
+ virtual ~GraphicDevice();
+
+ int setBackgroundColor(Color);
+ void setForegroundColor(Color);
+ Color getBackgroundColor();
+ Color getForegroundColor();
+ void setMovieDimension(long width, long height);
+ void setMovieZoom(int zoom);
+ void setMovieOffset(long x, long y);
+ long getWidth();
+ long getHeight();
+ Color *getColormap(Color *old, long n, Cxform *cxform);
+
+ void drawBox(long x1, long y1, long x2, long y2);
+
+ void addSegment(long x1, long y1, long x2, long y2,
+ FillStyleDef *f0,
+ FillStyleDef *f1,
+ int aa);
+
+ void drawPolygon(void);
+
+ void updateClippingRegion(Rect *);
+ void setClipping(int);
+
+ // Virtual functions
+ virtual void clearCanvas();
+ virtual long allocColor(Color color);
+ virtual void fillLineBitmap(FillStyleDef *f, long y, long start, long end);
+ virtual void fillLineLG(Gradient *grad, long y, long start, long end);
+ virtual void fillLineRG(Gradient *grad, long y, long start, long end);
+ virtual void fillLine(FillStyleDef *f, long y, long start, long end);
+ virtual void fillLineAA(FillStyleDef *f, long y, long start, long end);
+ virtual void drawLine(long x1, long y1, long x2, long y2, long width);
+
+};
+
+#endif /* _GRAPHIC_H_ */
diff --git a/core/multimedia/opieplayer/libflash/graphic16.cc b/core/multimedia/opieplayer/libflash/graphic16.cc
new file mode 100644
index 0000000..24d0c20
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/graphic16.cc
@@ -0,0 +1,658 @@
+////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#include "graphic16.h"
+
+extern unsigned char SQRT[];
+
+#define FULL_AA
+
+#define PRINT 0
+
+typedef unsigned short TYPE;
+
+GraphicDevice16::GraphicDevice16(FlashDisplay *fd) : GraphicDevice(fd)
+{
+}
+
+long
+GraphicDevice16::allocColor(Color color)
+{
+ return (color.red >> 3)<<11 | (color.green>>2)<<5 | (color.blue>>3);
+}
+
+void
+GraphicDevice16::clearCanvas()
+{
+ TYPE pixel;
+ TYPE *point,*p;
+ long h, w,n;
+
+ if (!bgInitialized) return;
+
+ pixel = allocColor(backgroundColor);
+
+ point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin;
+ w = clip_rect.xmax - clip_rect.xmin;
+ h = clip_rect.ymax - clip_rect.ymin;
+
+ while (h--) {
+ p = point;
+ n = w;
+ while (n--) {
+ *p++ = pixel;
+ }
+
+ point = (TYPE *)((char *)point + bpl);
+ }
+
+ flashDisplay->flash_refresh = 1;
+ flashDisplay->clip_x = clip_rect.xmin;
+ flashDisplay->clip_y = clip_rect.ymin;
+ flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin;
+ flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin;
+}
+
+#define RED_MASK 0xF800
+#define GREEN_MASK 0x07E0
+#define BLUE_MASK 0x001F
+
+/* alpha = 0 : select c1, alpha = 255 select c2 */
+static inline unsigned long
+mix_alpha(unsigned long c1,
+ unsigned long c2, int alpha)
+{
+ long r1,r2,r;
+ long g1,g2,g;
+ long b1,b2,b;
+
+ r1 = c1 & RED_MASK;
+ r2 = c2 & RED_MASK;
+ r = (((r2-r1)*alpha + r1 * 256) >> 8) & RED_MASK;
+
+ g1 = c1 & GREEN_MASK;
+ g2 = c2 & GREEN_MASK;
+ g = (((g2-g1)*alpha + g1 * 256) >> 8) & GREEN_MASK;
+
+ b1 = c1 & BLUE_MASK;
+ b2 = c2 & BLUE_MASK;
+ b = (((b2-b1)*alpha + b1 * 256) >> 8) & BLUE_MASK;
+
+ return (r|g|b);
+}
+
+void
+GraphicDevice16::fillLineAA(FillStyleDef *f, long y, long start, long end)
+{
+ register long n;
+ TYPE *line;
+ TYPE *point,pixel;
+ unsigned int alpha, start_alpha,end_alpha;
+
+ if (clip(y,start,end)) return;
+
+ line = (TYPE *)(canvasBuffer + bpl*y);
+
+ alpha = f->color.alpha;
+ pixel = f->color.pixel;
+
+ if (alpha == ALPHA_OPAQUE) {
+
+ start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
+ end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
+
+ start >>= FRAC_BITS;
+ end >>= FRAC_BITS;
+
+ point = &line[start];
+
+ if (start == end) {
+ *point = mix_alpha(*point, pixel, start_alpha + end_alpha - 255);
+ } else {
+ n = end-start;
+ if (start_alpha < 255) {
+ *point = mix_alpha(*point, pixel, start_alpha);
+ point++;
+ n--;
+ }
+ while (n > 0) {
+ *point = pixel;
+ point++;
+ n--;
+ }
+ if (end_alpha > 0) {
+ *point = mix_alpha(*point, pixel, end_alpha);
+ }
+ }
+ } else {
+
+ start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
+ end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
+
+ start >>= FRAC_BITS;
+ end >>= FRAC_BITS;
+
+ point = &line[start];
+
+ if (start == end) {
+ *point = mix_alpha(*point, pixel,
+ ((start_alpha + end_alpha - 255) * alpha) >> 8);
+ } else {
+ n = end-start;
+ if (start_alpha < 255) {
+ *point = mix_alpha(*point, pixel, (start_alpha * alpha) >> 8);
+ point++;
+ n--;
+ }
+ while (n > 0) {
+ *point = mix_alpha(*point, pixel, alpha);
+ point++;
+ n--;
+ }
+ if (end_alpha > 0) {
+ *point = mix_alpha(*point, pixel, (end_alpha * alpha) >> 8);
+ }
+ }
+ }
+}
+
+void
+GraphicDevice16::fillLine(FillStyleDef *f, long y, long start, long end)
+{
+ register long n;
+ TYPE *line,*point;
+ TYPE pixel;
+ unsigned int alpha;
+
+ if (clip(y,start,end)) return;
+
+ start >>= FRAC_BITS;
+ end >>= FRAC_BITS;
+
+ line = (TYPE *)(canvasBuffer + bpl*y);
+ point = &line[start];
+ n = end-start;
+ pixel = f->color.pixel;
+ alpha = f->color.alpha;
+ if (alpha == ALPHA_OPAQUE) {
+ while (n--) {
+ *point = pixel;
+ point++;
+ }
+ } else {
+ while (n--) {
+ *point = mix_alpha(*point, pixel, alpha);
+ point++;
+ }
+ }
+}
+
+void
+GraphicDevice16::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
+{
+ int n;
+ long x1,y1,dx,dy;
+ Matrix *m = &f->bitmap_matrix;
+ Bitmap *b = f->bitmap;
+ unsigned char *pixels;
+ TYPE *p;
+ Color *cmap;
+ long pixbpl;
+ TYPE pixel;
+ int offset;
+ unsigned char *alpha_table;
+
+ /* safety test) */
+ if (!b) return;
+
+ if (clip(y,start,end)) return;
+
+ start /= FRAC;
+ end /= FRAC;
+ n = end - start;
+ p = (TYPE *) (this->canvasBuffer + this->bpl*y + start * 2);
+
+ /* the coordinates in the image are normalized to 16 bits */
+ x1 = (long) (m->a * start + m->b * y + m->tx);
+ y1 = (long) (m->c * start + m->d * y + m->ty);
+ dx = (long) (m->a);
+ dy = (long) (m->c);
+
+ pixels = b->pixels;
+ pixbpl = b->bpl;
+ cmap = f->cmap;
+
+ if (b->alpha_buf == NULL) {
+ while (n) {
+ if (x1 >= 0 && y1 >= 0 &&
+ (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
+
+ pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]].pixel;
+ *p = pixel;
+ }
+ x1 += dx;
+ y1 += dy;
+ p++;
+ n--;
+ }
+ } else if (f->alpha_table) {
+ alpha_table = f->alpha_table;
+ while (n) {
+ if (x1 >= 0 && y1 >= 0 &&
+ (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
+
+ offset = (y1 >> 16) * pixbpl + (x1 >> 16);
+ pixel = cmap[pixels[offset]].pixel;
+ *p = mix_alpha(*p, pixel, alpha_table[b->alpha_buf[offset]]);
+ }
+ x1 += dx;
+ y1 += dy;
+ p++;
+ n--;
+ }
+ } else {
+ while (n) {
+ if (x1 >= 0 && y1 >= 0 &&
+ (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
+
+ offset = (y1 >> 16) * pixbpl + (x1 >> 16);
+ pixel = cmap[pixels[offset]].pixel;
+ *p = mix_alpha(*p, pixel, b->alpha_buf[offset]);
+ }
+ x1 += dx;
+ y1 += dy;
+ p++;
+ n--;
+ }
+ }
+}
+
+void
+GraphicDevice16::fillLineLG(Gradient *grad, long y, long start, long end)
+{
+ long dr,r,v,r2;
+ register long n;
+ TYPE *line;
+ TYPE *point;
+ Color *cp,*ramp;
+ Matrix *m = &grad->imat;
+ unsigned int start_alpha,end_alpha;
+
+ if (clip(y,start,end)) return;
+
+ start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
+ end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
+
+ start /= FRAC;
+ end /= FRAC;
+
+ n = end-start;
+
+ r = (long) (m->a * start + m->b * y + m->tx);
+ dr = (long) (m->a);
+
+ ramp = grad->ramp;
+
+ line = (TYPE *)(canvasBuffer + bpl*y);
+ point = &line[start];
+
+ r2 = r + n * dr;
+ if ( ((r | r2) & ~255) == 0 ) {
+ if (!grad->has_alpha) {
+#ifdef FULL_AA
+ if (start_alpha < 255) {
+ v = r>>16;
+ *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
+ point++;
+ r += dr;
+ n--;
+ }
+#endif /* FULL_AA */
+ while (n>0) {
+ v = r>>16;
+ *point = (TYPE)ramp[v].pixel;
+ point++;
+ r += dr;
+ n--;
+ }
+#ifdef FULL_AA
+ if (end_alpha > 0) {
+ v = r>>16;
+ *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
+ }
+#endif /* FULL_AA */
+ } else {
+ while (n--) {
+ v = r>>16;
+ cp = &ramp[v];
+ *point = mix_alpha(*point, cp->pixel, cp->alpha);
+ point++;
+ r += dr;
+ }
+ }
+ } else {
+ if (!grad->has_alpha) {
+#ifdef FULL_AA
+ if (start_alpha < 255) {
+ v = r>>16;
+ if (v < 0) v = 0;
+ else if (v > 255) v = 255;
+ *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
+ point++;
+ r += dr;
+ n--;
+ }
+#endif /* FULL_AA */
+ while (n>0) {
+ v = r>>16;
+ if (v < 0) v = 0;
+ else if (v > 255) v = 255;
+ *point = (TYPE)ramp[v].pixel;
+ point++;
+ r += dr;
+ n--;
+ }
+#ifdef FULL_AA
+ if (end_alpha > 0) {
+ v = r>>16;
+ if (v < 0) v = 0;
+ else if (v > 255) v = 255;
+ *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
+ }
+#endif /* FULL_AA */
+ } else {
+ while (n--) {
+ v = r>>16;
+ if (v < 0) v = 0;
+ else if (v > 255) v = 255;
+ cp = &ramp[v];
+ *point = mix_alpha(*point, cp->pixel, cp->alpha);
+ point++;
+ r += dr;
+ }
+ }
+ }
+}
+
+void
+GraphicDevice16::fillLineRG(Gradient *grad, long y, long start, long end)
+{
+ long X,dx,r,Y,dy;
+ long dist2;
+ register long n;
+ Color *cp,*ramp;
+ TYPE *line;
+ TYPE *point;
+ Matrix *m = &grad->imat;
+ unsigned int start_alpha,end_alpha;
+
+ if (clip(y,start,end)) return;
+
+ start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
+ end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
+
+ start /= FRAC;
+ end /= FRAC;
+
+ n = end-start;
+
+ X = (long) (m->a * start + m->b * y + m->tx);
+ Y = (long) (m->c * start + m->d * y + m->ty);
+ dx = (long) (m->a);
+ dy = (long) (m->c);
+
+ ramp = grad->ramp;
+
+ line = (TYPE *)(canvasBuffer + bpl*y);
+ point = &line[start];
+
+ if (!grad->has_alpha) {
+#ifdef FULL_AA
+ if (start == end) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r = SQRT[dist2];
+ }
+ *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha + end_alpha - 255);
+ } else {
+ if (start_alpha < 255) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r = SQRT[dist2];
+ }
+ *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha);
+ point++;
+ X += dx;
+ Y += dy;
+ n--;
+ }
+#endif /* FULL_AA */
+ while (n>0) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r= SQRT[dist2];
+ }
+ *point = (TYPE)ramp[r].pixel;
+ point++;
+ X += dx;
+ Y += dy;
+ n--;
+ }
+#ifdef FULL_AA
+ if (end_alpha > 0) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r= SQRT[dist2];
+ }
+ *point = mix_alpha(*point, (TYPE)ramp[r].pixel, end_alpha);
+ }
+ }
+#endif /* FULL_AA */
+
+ } else {
+ while (n--) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r= SQRT[dist2];
+ }
+ cp = &ramp[r];
+ *point = mix_alpha(*point, cp->pixel, cp->alpha);
+ point++;
+ X += dx;
+ Y += dy;
+ }
+ }
+}
+
+void
+GraphicDevice16::drawLine(long x1, long y1, long x2, long y2, long width)
+{
+ int n,adr,dx,dy,sx,color;
+ register int a;
+ register TYPE *pp;
+ int alpha;
+
+ x1 = (x1) >> FRAC_BITS;
+ y1 = (y1) >> FRAC_BITS;
+ x2 = (x2) >> FRAC_BITS;
+ y2 = (y2) >> FRAC_BITS;
+
+ if (y1 > y2 || (y1 == y2 && x1 > x2)) {
+ long tmp;
+
+ tmp=x1;
+ x1=x2;
+ x2=tmp;
+
+ tmp=y1;
+ y1=y2;
+ y2=tmp;
+ }
+
+ if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return;
+ if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return;
+ if (x1 == x2 && y1 == y2) return; // Bad !!!
+
+ if (y1 < clip_rect.ymin && y1 != y2) {
+ x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1);
+ y1 = clip_rect.ymin;
+ }
+
+ if (y2 > clip_rect.ymax && y1 != y2) {
+ x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1);
+ y2 = clip_rect.ymax;
+ }
+
+ if (x1 < x2) {
+ if (x1 < clip_rect.xmin && x1 != x2) {
+ y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1);
+ x1 = clip_rect.xmin;
+ }
+
+ if (x2 > clip_rect.xmax && x1 != x2) {
+ y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1);
+ x2 = clip_rect.xmax;
+ }
+ }
+
+ if (x1 > x2) {
+ if (x2 < clip_rect.xmin && x2 != x1) {
+ y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2);
+ x2 = clip_rect.xmin;
+ }
+
+ if (x1 > clip_rect.xmax && x2 != x1) {
+ y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2);
+ x1 = clip_rect.xmax;
+ }
+ }
+
+ // Check again
+ if (x1 == x2 && y1 == y2) return;
+ if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return;
+ if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return;
+ if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return;
+ if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return;
+
+ sx=bpl >> 1;
+ adr=(y1 * sx + x1);
+ pp = (TYPE *)canvasBuffer + adr;
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+
+ color = allocColor(foregroundColor);
+ alpha = foregroundColor.alpha;
+
+ if (alpha == ALPHA_OPAQUE) {
+
+#define PUTPIXEL() \
+ { \
+ *pp=color; \
+ }
+
+#define DRAWLINE(dx,dy,inc_1,inc_2) \
+ n=dx;\
+ a=2*dy-dx;\
+ dy=2*dy;\
+ dx=2*dx-dy;\
+ do {\
+ PUTPIXEL();\
+ if (a>0) { pp+=(inc_1); a-=dx; }\
+ else { pp+=(inc_2); a+=dy; }\
+ } while (--n >= 0);
+
+/* fin macro */
+
+ if (dx == 0 && dy == 0) {
+ PUTPIXEL();
+ } else if (dx > 0) {
+ if (dx >= dy) {
+ DRAWLINE(dx, dy, sx + 1, 1);
+ } else {
+ DRAWLINE(dy, dx, sx + 1, sx);
+ }
+ } else {
+ dx = -dx;
+ if (dx >= dy) {
+ DRAWLINE(dx, dy, sx - 1, -1);
+ } else {
+ DRAWLINE(dy, dx, sx - 1, sx);
+ }
+ }
+
+
+#undef DRAWLINE
+#undef PUTPIXEL
+ } else {
+#define PUTPIXEL() \
+ { \
+ *pp=mix_alpha(*pp,color,alpha); \
+ }
+
+#define DRAWLINE(dx,dy,inc_1,inc_2) \
+ n=dx;\
+ a=2*dy-dx;\
+ dy=2*dy;\
+ dx=2*dx-dy;\
+ do {\
+ PUTPIXEL();\
+ if (a>0) { pp+=(inc_1); a-=dx; }\
+ else { pp+=(inc_2); a+=dy; }\
+ } while (--n >= 0);
+
+/* fin macro */
+
+ if (dx == 0 && dy == 0) {
+ PUTPIXEL();
+ } else if (dx > 0) {
+ if (dx >= dy) {
+ DRAWLINE(dx, dy, sx + 1, 1);
+ } else {
+ DRAWLINE(dy, dx, sx + 1, sx);
+ }
+ } else {
+ dx = -dx;
+ if (dx >= dy) {
+ DRAWLINE(dx, dy, sx - 1, -1);
+ } else {
+ DRAWLINE(dy, dx, sx - 1, sx);
+ }
+ }
+
+
+#undef DRAWLINE
+#undef PUTPIXEL
+ }
+}
diff --git a/core/multimedia/opieplayer/libflash/graphic16.h b/core/multimedia/opieplayer/libflash/graphic16.h
new file mode 100644
index 0000000..938d856
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/graphic16.h
@@ -0,0 +1,39 @@
+////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+class GraphicDevice16: public GraphicDevice {
+private:
+ long GraphicDevice16::allocColor(Color color);
+
+public:
+ GraphicDevice16(FlashDisplay *fd);
+
+ void clearCanvas();
+ void fillLineAA(FillStyleDef *f, long y, long start, long end);
+ void fillLine(FillStyleDef *f, long y, long start, long end);
+ void fillLineBitmap(FillStyleDef *f, long y, long start, long end);
+ void fillLineLG(Gradient *grad, long y, long start, long end);
+ void fillLineRG(Gradient *grad, long y, long start, long end);
+ void drawLine(long x1, long y1, long x2, long y2, long width);
+};
diff --git a/core/multimedia/opieplayer/libflash/graphic24.cc b/core/multimedia/opieplayer/libflash/graphic24.cc
new file mode 100644
index 0000000..6d15019
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/graphic24.cc
@@ -0,0 +1,648 @@
+////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#include "graphic24.h"
+
+extern unsigned char SQRT[];
+
+#define FULL_AA
+
+#define PRINT 0
+
+typedef unsigned char TYPE;
+#define BPP 3
+
+GraphicDevice24::GraphicDevice24(FlashDisplay *fd) : GraphicDevice(fd)
+{
+}
+
+long
+GraphicDevice24::allocColor(Color color)
+{
+ return 0;
+}
+
+void
+GraphicDevice24::clearCanvas()
+{
+ TYPE *point,*p;
+ long h, w,n;
+
+ if (!bgInitialized) return;
+
+ point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin*BPP;
+ w = clip_rect.xmax - clip_rect.xmin;
+ h = clip_rect.ymax - clip_rect.ymin;
+
+ while (h--) {
+ p = point;
+ n = w;
+ while (n--) {
+ *p++ = backgroundColor.blue;
+ *p++ = backgroundColor.green;
+ *p++ = backgroundColor.red;
+ }
+
+ point = (TYPE *)((char *)point + bpl);
+ }
+
+ flashDisplay->flash_refresh = 1;
+ flashDisplay->clip_x = clip_rect.xmin;
+ flashDisplay->clip_y = clip_rect.ymin;
+ flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin;
+ flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin;
+}
+
+/* alpha = 0 : select c1, alpha = 255 select c2 */
+static inline void mix_alpha(TYPE *c1, Color c2, int alpha)
+{
+ *c1 = (((c2.blue- (*c1))*alpha + (*c1) * 256) >> 8);
+ c1++;
+ *c1 = (((c2.green- (*c1))*alpha + (*c1) * 256) >> 8);
+ c1++;
+ *c1 = (((c2.red- (*c1))*alpha + (*c1) * 256) >> 8);
+}
+
+void
+GraphicDevice24::fillLineAA(FillStyleDef *f, long y, long start, long end)
+{
+ register long n;
+ TYPE *line;
+ TYPE *point;
+ Color pixel;
+ unsigned int alpha, start_alpha,end_alpha;
+
+ if (clip(y,start,end)) return;
+
+ line = (TYPE *)(canvasBuffer + bpl*y);
+
+ alpha = f->color.alpha;
+ pixel = f->color;
+
+ if (alpha == ALPHA_OPAQUE) {
+
+ start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
+ end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
+
+ start >>= FRAC_BITS;
+ end >>= FRAC_BITS;
+
+ point = &line[start*BPP];
+
+ if (start == end) {
+ mix_alpha(point, pixel, start_alpha + end_alpha - 255);
+ } else {
+ n = end-start;
+ if (start_alpha < 255) {
+ mix_alpha(point, pixel, start_alpha);
+ point += BPP;
+ n--;
+ }
+ while (n > 0) {
+ *point++ = pixel.blue;
+ *point++ = pixel.green;
+ *point++ = pixel.red;
+ n--;
+ }
+ if (end_alpha > 0) {
+ mix_alpha(point, pixel, end_alpha);
+ }
+ }
+ } else {
+
+ start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
+ end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
+
+ start >>= FRAC_BITS;
+ end >>= FRAC_BITS;
+
+ point = &line[start*BPP];
+
+ if (start == end) {
+ mix_alpha(point, pixel, ((start_alpha + end_alpha - 255) * alpha) >> 8);
+ } else {
+ n = end-start;
+ if (start_alpha < 255) {
+ mix_alpha(point, pixel, (start_alpha * alpha) >> 8);
+ point+=BPP;
+ n--;
+ }
+ while (n > 0) {
+ mix_alpha(point, pixel, alpha);
+ point+=BPP;
+ n--;
+ }
+ if (end_alpha > 0) {
+ mix_alpha(point, pixel, (end_alpha * alpha) >> 8);
+ }
+ }
+ }
+}
+
+void
+GraphicDevice24::fillLine(FillStyleDef *f, long y, long start, long end)
+{
+ register long n;
+ TYPE *line,*point;
+ Color pixel;
+ unsigned int alpha;
+
+ if (clip(y,start,end)) return;
+
+ start >>= FRAC_BITS;
+ end >>= FRAC_BITS;
+
+ line = (TYPE *)(canvasBuffer + bpl*y);
+ point = &line[start*BPP];
+ n = end-start;
+ alpha = f->color.alpha;
+ pixel = f->color;
+ if (alpha == ALPHA_OPAQUE) {
+ while (n--) {
+ *point++ = pixel.blue;
+ *point++ = pixel.green;
+ *point++ = pixel.red;
+ }
+ } else {
+ while (n--) {
+ mix_alpha(point, pixel, alpha);
+ point+=BPP;
+ }
+ }
+}
+
+void
+GraphicDevice24::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
+{
+ int n;
+ long x1,y1,dx,dy;
+ Matrix *m = &f->bitmap_matrix;
+ Bitmap *b = f->bitmap;
+ unsigned char *pixels;
+ TYPE *p;
+ Color *cmap;
+ long pixbpl;
+ Color pixel;
+ int offset;
+ unsigned char *alpha_table;
+
+ /* safety test) */
+ if (!b) return;
+
+ if (clip(y,start,end)) return;
+
+ start /= FRAC;
+ end /= FRAC;
+ n = end - start;
+ p = (TYPE *) (canvasBuffer + bpl*y + start*BPP);
+
+ x1 = (long) (m->a * start + m->b * y + m->tx);
+ y1 = (long) (m->c * start + m->d * y + m->ty);
+ dx = (long) (m->a);
+ dy = (long) (m->c);
+
+ pixels = b->pixels;
+ pixbpl = b->bpl;
+ cmap = f->cmap;
+
+ if (b->alpha_buf == NULL) {
+ while (n) {
+ if (x1 >= 0 && y1 >= 0 &&
+ (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
+
+ pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]];
+ *p++ = pixel.blue;
+ *p++ = pixel.green;
+ *p++ = pixel.red;
+ } else {
+ p+=BPP;
+ }
+ x1 += dx;
+ y1 += dy;
+ n--;
+ }
+ } else if (f->alpha_table) {
+ alpha_table = f->alpha_table;
+ while (n) {
+ if (x1 >= 0 && y1 >= 0 &&
+ (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
+
+ offset = (y1 >> 16) * pixbpl + (x1 >> 16);
+ mix_alpha(p, cmap[pixels[offset]], alpha_table[b->alpha_buf[offset]]);
+ }
+ p+=BPP;
+ x1 += dx;
+ y1 += dy;
+ n--;
+ }
+ } else {
+ while (n) {
+ if (x1 >= 0 && y1 >= 0 &&
+ (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
+
+ offset = (y1 >> 16) * pixbpl + (x1 >> 16);
+ mix_alpha(p, cmap[pixels[offset]], b->alpha_buf[offset]);
+ }
+ p+=BPP;
+ x1 += dx;
+ y1 += dy;
+ n--;
+ }
+ }
+}
+
+void
+GraphicDevice24::fillLineLG(Gradient *grad, long y, long start, long end)
+{
+ long dr,r,v,r2;
+ register long n;
+ TYPE *line;
+ TYPE *point;
+ Color *cp,*ramp;
+ Matrix *m = &grad->imat;
+ unsigned int start_alpha,end_alpha;
+
+ if (clip(y,start,end)) return;
+
+ start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
+ end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
+
+ start /= FRAC;
+ end /= FRAC;
+
+ n = end-start;
+
+ r = (long) (m->a * start + m->b * y + m->tx);
+ dr = (long) (m->a);
+
+ ramp = grad->ramp;
+
+ line = (TYPE *)(canvasBuffer + bpl*y);
+ point = &line[start*BPP];
+
+ r2 = r + n * dr;
+ if ( ((r | r2) & ~255) == 0 ) {
+ if (!grad->has_alpha) {
+#ifdef FULL_AA
+ if (start_alpha < 255) {
+ v = r>>16;
+ mix_alpha(point, ramp[v], start_alpha);
+ point+=BPP;
+ r += dr;
+ n--;
+ }
+#endif /* FULL_AA */
+ while (n>0) {
+ v = r>>16;
+ *point++ = ramp[v].blue;
+ *point++ = ramp[v].green;
+ *point++ = ramp[v].red;
+ r += dr;
+ n--;
+ }
+#ifdef FULL_AA
+ if (end_alpha > 0) {
+ v = r>>16;
+ mix_alpha(point, ramp[v], end_alpha);
+ }
+#endif /* FULL_AA */
+ } else {
+ while (n--) {
+ v = r>>16;
+ cp = &ramp[v];
+ mix_alpha(point, *cp, cp->alpha);
+ point+=BPP;
+ r += dr;
+ }
+ }
+ } else {
+ if (!grad->has_alpha) {
+#ifdef FULL_AA
+ if (start_alpha < 255) {
+ v = r>>16;
+ if (v < 0) v = 0;
+ else if (v > 255) v = 255;
+ mix_alpha(point, ramp[v], start_alpha);
+ point+=BPP;
+ r += dr;
+ n--;
+ }
+#endif /* FULL_AA */
+ while (n>0) {
+ v = r>>16;
+ if (v < 0) v = 0;
+ else if (v > 255) v = 255;
+ *point++ = ramp[v].blue;
+ *point++ = ramp[v].green;
+ *point++ = ramp[v].red;
+ r += dr;
+ n--;
+ }
+#ifdef FULL_AA
+ if (end_alpha > 0) {
+ v = r>>16;
+ if (v < 0) v = 0;
+ else if (v > 255) v = 255;
+ mix_alpha(point, ramp[v], end_alpha);
+ }
+#endif /* FULL_AA */
+ } else {
+ while (n--) {
+ v = r>>16;
+ if (v < 0) v = 0;
+ else if (v > 255) v = 255;
+ cp = &ramp[v];
+ mix_alpha(point, *cp, cp->alpha);
+ point+=BPP;
+ r += dr;
+ }
+ }
+ }
+}
+
+void
+GraphicDevice24::fillLineRG(Gradient *grad, long y, long start, long end)
+{
+ long X,dx,r,Y,dy;
+ long dist2;
+ register long n;
+ Color *cp,*ramp;
+ TYPE *line;
+ TYPE *point;
+ Matrix *m = &grad->imat;
+ unsigned int start_alpha,end_alpha;
+
+ if (clip(y,start,end)) return;
+
+ start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
+ end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
+
+ start /= FRAC;
+ end /= FRAC;
+
+ n = end-start;
+
+ X = (long) (m->a * start + m->b * y + m->tx);
+ Y = (long) (m->c * start + m->d * y + m->ty);
+ dx = (long) (m->a);
+ dy = (long) (m->c);
+
+ ramp = grad->ramp;
+
+ line = (TYPE *)(canvasBuffer + bpl*y);
+ point = &line[start*BPP];
+
+ if (!grad->has_alpha) {
+#ifdef FULL_AA
+ if (start == end) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r= SQRT[dist2];
+ }
+ mix_alpha(point, ramp[r], start_alpha + end_alpha - 255);
+ } else {
+ if (start_alpha < 255) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r= SQRT[dist2];
+ }
+ mix_alpha(point, ramp[r], start_alpha);
+ point+=BPP;
+ X += dx;
+ Y += dy;
+ n--;
+ }
+#endif /* FULL_AA */
+ while (n>0) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r= SQRT[dist2];
+ }
+ *point++ = ramp[r].blue;
+ *point++ = ramp[r].green;
+ *point++ = ramp[r].red;
+ X += dx;
+ Y += dy;
+ n--;
+ }
+#ifdef FULL_AA
+ if (end_alpha > 0) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r= SQRT[dist2];
+ }
+ mix_alpha(point, ramp[r], end_alpha);
+ }
+ }
+#endif /* FULL_AA */
+
+ } else {
+ while (n--) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r= SQRT[dist2];
+ }
+ cp = &ramp[r];
+ mix_alpha(point, *cp, cp->alpha);
+ point+=BPP;
+ X += dx;
+ Y += dy;
+ }
+ }
+}
+
+void
+GraphicDevice24::drawLine(long x1, long y1, long x2, long y2, long width)
+{
+ int n,adr,dx,dy,sx;
+ Color color;
+ register int a;
+ register TYPE *pp;
+ int alpha;
+
+ x1 = (x1) >> FRAC_BITS;
+ y1 = (y1) >> FRAC_BITS;
+ x2 = (x2) >> FRAC_BITS;
+ y2 = (y2) >> FRAC_BITS;
+
+ if (y1 > y2 || (y1 == y2 && x1 > x2)) {
+ long tmp;
+
+ tmp=x1;
+ x1=x2;
+ x2=tmp;
+
+ tmp=y1;
+ y1=y2;
+ y2=tmp;
+ }
+
+ if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return;
+ if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return;
+ if (x1 == x2 && y1 == y2) return; // Bad !!!
+
+ if (y1 < clip_rect.ymin && y1 != y2) {
+ x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1);
+ y1 = clip_rect.ymin;
+ }
+
+ if (y2 > clip_rect.ymax && y1 != y2) {
+ x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1);
+ y2 = clip_rect.ymax;
+ }
+
+ if (x1 < x2) {
+ if (x1 < clip_rect.xmin && x1 != x2) {
+ y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1);
+ x1 = clip_rect.xmin;
+ }
+
+ if (x2 > clip_rect.xmax && x1 != x2) {
+ y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1);
+ x2 = clip_rect.xmax;
+ }
+ }
+
+ if (x1 > x2) {
+ if (x2 < clip_rect.xmin && x2 != x1) {
+ y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2);
+ x2 = clip_rect.xmin;
+ }
+
+ if (x1 > clip_rect.xmax && x2 != x1) {
+ y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2);
+ x1 = clip_rect.xmax;
+ }
+ }
+
+ // Check again
+ if (x1 == x2 && y1 == y2) return;
+ if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return;
+ if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return;
+ if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return;
+ if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return;
+
+ sx=bpl >> 1;
+ adr=(y1 * sx + x1);
+ pp = (TYPE *)canvasBuffer + adr;
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+
+ color = foregroundColor;
+ alpha = foregroundColor.alpha;
+
+ if (alpha == ALPHA_OPAQUE) {
+
+#define PUTPIXEL() \
+ { \
+ *pp++=color.red; \
+ *pp++=color.green; \
+ *pp++=color.blue; \
+ }
+
+#define DRAWLINE(dx,dy,inc_1,inc_2) \
+ n=dx;\
+ a=2*dy-dx;\
+ dy=2*dy;\
+ dx=2*dx-dy;\
+ do {\
+ PUTPIXEL();\
+ if (a>0) { pp+=(inc_1); a-=dx; }\
+ else { pp+=(inc_2); a+=dy; }\
+ } while (--n >= 0);
+
+/* fin macro */
+
+ if (dx == 0 && dy == 0) {
+ PUTPIXEL();
+ } else if (dx > 0) {
+ if (dx >= dy) {
+ DRAWLINE(dx, dy, sx + 1, 1);
+ } else {
+ DRAWLINE(dy, dx, sx + 1, sx);
+ }
+ } else {
+ dx = -dx;
+ if (dx >= dy) {
+ DRAWLINE(dx, dy, sx - 1, -1);
+ } else {
+ DRAWLINE(dy, dx, sx - 1, sx);
+ }
+ }
+
+
+#undef DRAWLINE
+#undef PUTPIXEL
+ } else {
+#define PUTPIXEL() \
+ { \
+ mix_alpha(pp,color,alpha); \
+ }
+
+#define DRAWLINE(dx,dy,inc_1,inc_2) \
+ n=dx;\
+ a=2*dy-dx;\
+ dy=2*dy;\
+ dx=2*dx-dy;\
+ do {\
+ PUTPIXEL();\
+ if (a>0) { pp+=(inc_1*BPP); a-=dx; }\
+ else { pp+=(inc_2*BPP); a+=dy; }\
+ } while (--n >= 0);
+
+/* fin macro */
+
+ if (dx == 0 && dy == 0) {
+ PUTPIXEL();
+ } else if (dx > 0) {
+ if (dx >= dy) {
+ DRAWLINE(dx, dy, sx + 1, 1);
+ } else {
+ DRAWLINE(dy, dx, sx + 1, sx);
+ }
+ } else {
+ dx = -dx;
+ if (dx >= dy) {
+ DRAWLINE(dx, dy, sx - 1, -1);
+ } else {
+ DRAWLINE(dy, dx, sx - 1, sx);
+ }
+ }
+
+
+#undef DRAWLINE
+#undef PUTPIXEL
+ }
+}
diff --git a/core/multimedia/opieplayer/libflash/graphic24.h b/core/multimedia/opieplayer/libflash/graphic24.h
new file mode 100644
index 0000000..4c10e49
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/graphic24.h
@@ -0,0 +1,39 @@
+////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+class GraphicDevice24: public GraphicDevice {
+private:
+ long GraphicDevice24::allocColor(Color color);
+
+public:
+ GraphicDevice24(FlashDisplay *fd);
+
+ void clearCanvas();
+ void fillLineAA(FillStyleDef *f, long y, long start, long end);
+ void fillLine(FillStyleDef *f, long y, long start, long end);
+ void fillLineBitmap(FillStyleDef *f, long y, long start, long end);
+ void fillLineLG(Gradient *grad, long y, long start, long end);
+ void fillLineRG(Gradient *grad, long y, long start, long end);
+ void drawLine(long x1, long y1, long x2, long y2, long width);
+};
diff --git a/core/multimedia/opieplayer/libflash/graphic32.cc b/core/multimedia/opieplayer/libflash/graphic32.cc
new file mode 100644
index 0000000..b9c2008
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/graphic32.cc
@@ -0,0 +1,657 @@
+////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#include "graphic32.h"
+
+extern unsigned char SQRT[];
+
+#define FULL_AA
+
+#define PRINT 0
+
+typedef unsigned long TYPE;
+
+GraphicDevice32::GraphicDevice32(FlashDisplay *fd) : GraphicDevice(fd)
+{
+}
+
+long
+GraphicDevice32::allocColor(Color color)
+{
+ return (color.red)<<16 | (color.green)<<8 | (color.blue);
+}
+
+void
+GraphicDevice32::clearCanvas()
+{
+ TYPE pixel;
+ TYPE *point,*p;
+ long h, w,n;
+
+ if (!bgInitialized) return;
+
+ pixel = allocColor(backgroundColor);
+
+ point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin;
+ w = clip_rect.xmax - clip_rect.xmin;
+ h = clip_rect.ymax - clip_rect.ymin;
+
+ while (h--) {
+ p = point;
+ n = w;
+ while (n--) {
+ *p++ = pixel;
+ }
+
+ point = (TYPE *)((char *)point + bpl);
+ }
+
+ flashDisplay->flash_refresh = 1;
+ flashDisplay->clip_x = clip_rect.xmin;
+ flashDisplay->clip_y = clip_rect.ymin;
+ flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin;
+ flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin;
+}
+
+#define RED_MASK 0xFF0000
+#define GREEN_MASK 0x00FF00
+#define BLUE_MASK 0x0000FF
+
+/* alpha = 0 : select c1, alpha = 255 select c2 */
+static inline unsigned long
+mix_alpha(unsigned long c1, unsigned long c2, int alpha)
+{
+ long r1,r2,r;
+ long g1,g2,g;
+ long b1,b2,b;
+
+ r1 = c1 & RED_MASK;
+ r2 = c2 & RED_MASK;
+ r = (((r2-r1)*alpha + r1 * 256) >> 8) & RED_MASK;
+
+ g1 = c1 & GREEN_MASK;
+ g2 = c2 & GREEN_MASK;
+ g = (((g2-g1)*alpha + g1 * 256) >> 8) & GREEN_MASK;
+
+ b1 = c1 & BLUE_MASK;
+ b2 = c2 & BLUE_MASK;
+ b = (((b2-b1)*alpha + b1 * 256) >> 8) & BLUE_MASK;
+
+ return (r|g|b);
+}
+
+void
+GraphicDevice32::fillLineAA(FillStyleDef *f, long y, long start, long end)
+{
+ register long n;
+ TYPE *line;
+ TYPE *point,pixel;
+ unsigned int alpha, start_alpha,end_alpha;
+
+ if (clip(y,start,end)) return;
+
+ line = (TYPE *)(canvasBuffer + bpl*y);
+
+ alpha = f->color.alpha;
+ pixel = f->color.pixel;
+
+ if (alpha == ALPHA_OPAQUE) {
+
+ start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
+ end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
+
+ start >>= FRAC_BITS;
+ end >>= FRAC_BITS;
+
+ point = &line[start];
+
+ if (start == end) {
+ *point = mix_alpha(*point, pixel, start_alpha + end_alpha - 255);
+ } else {
+ n = end-start;
+ if (start_alpha < 255) {
+ *point = mix_alpha(*point, pixel, start_alpha);
+ point++;
+ n--;
+ }
+ while (n > 0) {
+ *point = pixel;
+ point++;
+ n--;
+ }
+ if (end_alpha > 0) {
+ *point = mix_alpha(*point, pixel, end_alpha);
+ }
+ }
+ } else {
+
+ start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
+ end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
+
+ start >>= FRAC_BITS;
+ end >>= FRAC_BITS;
+
+ point = &line[start];
+
+ if (start == end) {
+ *point = mix_alpha(*point, pixel,
+ ((start_alpha + end_alpha - 255) * alpha) >> 8);
+ } else {
+ n = end-start;
+ if (start_alpha < 255) {
+ *point = mix_alpha(*point, pixel, (start_alpha * alpha) >> 8);
+ point++;
+ n--;
+ }
+ while (n > 0) {
+ *point = mix_alpha(*point, pixel, alpha);
+ point++;
+ n--;
+ }
+ if (end_alpha > 0) {
+ *point = mix_alpha(*point, pixel, (end_alpha * alpha) >> 8);
+ }
+ }
+ }
+}
+
+void
+GraphicDevice32::fillLine(FillStyleDef *f, long y, long start, long end)
+{
+ register long n;
+ TYPE *line,*point;
+ TYPE pixel;
+ unsigned int alpha;
+
+ if (clip(y,start,end)) return;
+
+ start >>= FRAC_BITS;
+ end >>= FRAC_BITS;
+
+ line = (TYPE *)(canvasBuffer + bpl*y);
+ point = &line[start];
+ n = end-start;
+ pixel = f->color.pixel;
+ alpha = f->color.alpha;
+ if (alpha == ALPHA_OPAQUE) {
+ while (n--) {
+ *point = pixel;
+ point++;
+ }
+ } else {
+ while (n--) {
+ *point = mix_alpha(*point, pixel, alpha);
+ point++;
+ }
+ }
+}
+
+void
+GraphicDevice32::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
+{
+ int n;
+ long x1,y1,dx,dy;
+ Matrix *m = &f->bitmap_matrix;
+ Bitmap *b = f->bitmap;
+ unsigned char *pixels;
+ TYPE *p;
+ Color *cmap;
+ long pixbpl;
+ TYPE pixel;
+ int offset;
+ unsigned char *alpha_table;
+
+ /* safety test) */
+ if (!b) return;
+
+ if (clip(y,start,end)) return;
+
+ start /= FRAC;
+ end /= FRAC;
+ n = end - start;
+ p = (TYPE *) (this->canvasBuffer + this->bpl*y + start * sizeof(TYPE));
+
+ /* the coordinates in the image are normalized to 16 bits */
+ x1 = (long) (m->a * start + m->b * y + m->tx);
+ y1 = (long) (m->c * start + m->d * y + m->ty);
+ dx = (long) (m->a);
+ dy = (long) (m->c);
+
+ pixels = b->pixels;
+ pixbpl = b->bpl;
+ cmap = f->cmap;
+
+ if (b->alpha_buf == NULL) {
+ while (n) {
+ if (x1 >= 0 && y1 >= 0 &&
+ (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
+
+ pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]].pixel;
+ *p = pixel;
+ }
+ x1 += dx;
+ y1 += dy;
+ p++;
+ n--;
+ }
+ } else if (f->alpha_table) {
+ alpha_table = f->alpha_table;
+ while (n) {
+ if (x1 >= 0 && y1 >= 0 &&
+ (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
+
+ offset = (y1 >> 16) * pixbpl + (x1 >> 16);
+ pixel = cmap[pixels[offset]].pixel;
+ *p = mix_alpha(*p, pixel, alpha_table[b->alpha_buf[offset]]);
+ }
+ x1 += dx;
+ y1 += dy;
+ p++;
+ n--;
+ }
+ } else {
+ while (n) {
+ if (x1 >= 0 && y1 >= 0 &&
+ (x1 >> 16) < b->width && (y1 >> 16) < b->height) {
+
+ offset = (y1 >> 16) * pixbpl + (x1 >> 16);
+ pixel = cmap[pixels[offset]].pixel;
+ *p = mix_alpha(*p, pixel, b->alpha_buf[offset]);
+ }
+ x1 += dx;
+ y1 += dy;
+ p++;
+ n--;
+ }
+ }
+}
+
+void
+GraphicDevice32::fillLineLG(Gradient *grad, long y, long start, long end)
+{
+ long dr,r,v,r2;
+ register long n;
+ TYPE *line;
+ TYPE *point;
+ Color *cp,*ramp;
+ Matrix *m = &grad->imat;
+ unsigned int start_alpha,end_alpha;
+
+ if (clip(y,start,end)) return;
+
+ start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
+ end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
+
+ start /= FRAC;
+ end /= FRAC;
+
+ n = end-start;
+
+ r = (long) (m->a * start + m->b * y + m->tx);
+ dr = (long) (m->a);
+
+ ramp = grad->ramp;
+
+ line = (TYPE *)(canvasBuffer + bpl*y);
+ point = &line[start];
+
+ r2 = r + n * dr;
+ if ( ((r | r2) & ~255) == 0 ) {
+ if (!grad->has_alpha) {
+#ifdef FULL_AA
+ if (start_alpha < 255) {
+ v = r>>16;
+ *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
+ point++;
+ r += dr;
+ n--;
+ }
+#endif /* FULL_AA */
+ while (n>0) {
+ v = r>>16;
+ *point = (TYPE)ramp[v].pixel;
+ point++;
+ r += dr;
+ n--;
+ }
+#ifdef FULL_AA
+ if (end_alpha > 0) {
+ v = r>>16;
+ *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
+ }
+#endif /* FULL_AA */
+ } else {
+ while (n--) {
+ v = r>>16;
+ cp = &ramp[v];
+ *point = mix_alpha(*point, cp->pixel, cp->alpha);
+ point++;
+ r += dr;
+ }
+ }
+ } else {
+ if (!grad->has_alpha) {
+#ifdef FULL_AA
+ if (start_alpha < 255) {
+ v = r>>16;
+ if (v < 0) v = 0;
+ else if (v > 255) v = 255;
+ *point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
+ point++;
+ r += dr;
+ n--;
+ }
+#endif /* FULL_AA */
+ while (n>0) {
+ v = r>>16;
+ if (v < 0) v = 0;
+ else if (v > 255) v = 255;
+ *point = (TYPE)ramp[v].pixel;
+ point++;
+ r += dr;
+ n--;
+ }
+#ifdef FULL_AA
+ if (end_alpha > 0) {
+ v = r>>16;
+ if (v < 0) v = 0;
+ else if (v > 255) v = 255;
+ *point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
+ }
+#endif /* FULL_AA */
+ } else {
+ while (n--) {
+ v = r>>16;
+ if (v < 0) v = 0;
+ else if (v > 255) v = 255;
+ cp = &ramp[v];
+ *point = mix_alpha(*point, cp->pixel, cp->alpha);
+ point++;
+ r += dr;
+ }
+ }
+ }
+}
+
+void
+GraphicDevice32::fillLineRG(Gradient *grad, long y, long start, long end)
+{
+ long X,dx,r,Y,dy;
+ long dist2;
+ register long n;
+ Color *cp,*ramp;
+ TYPE *line;
+ TYPE *point;
+ Matrix *m = &grad->imat;
+ unsigned int start_alpha,end_alpha;
+
+ if (clip(y,start,end)) return;
+
+ start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
+ end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
+
+ start /= FRAC;
+ end /= FRAC;
+
+ n = end-start;
+
+ X = (long) (m->a * start + m->b * y + m->tx);
+ Y = (long) (m->c * start + m->d * y + m->ty);
+ dx = (long) (m->a);
+ dy = (long) (m->c);
+
+ ramp = grad->ramp;
+
+ line = (TYPE *)(canvasBuffer + bpl*y);
+ point = &line[start];
+
+ if (!grad->has_alpha) {
+#ifdef FULL_AA
+ if (start == end) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r = SQRT[dist2];
+ }
+ *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha + end_alpha - 255);
+ } else {
+ if (start_alpha < 255) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r = SQRT[dist2];
+ }
+ *point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha);
+ point++;
+ X += dx;
+ Y += dy;
+ n--;
+ }
+#endif /* FULL_AA */
+ while (n>0) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r= SQRT[dist2];
+ }
+ *point = (TYPE)ramp[r].pixel;
+ point++;
+ X += dx;
+ Y += dy;
+ n--;
+ }
+#ifdef FULL_AA
+ if (end_alpha > 0) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r= SQRT[dist2];
+ }
+ *point = mix_alpha(*point, (TYPE)ramp[r].pixel, end_alpha);
+ }
+ }
+#endif /* FULL_AA */
+
+ } else {
+ while (n--) {
+ dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
+ if ((unsigned long)dist2 >= 65536) {
+ r = 255;
+ } else {
+ r= SQRT[dist2];
+ }
+ cp = &ramp[r];
+ *point = mix_alpha(*point, cp->pixel, cp->alpha);
+ point++;
+ X += dx;
+ Y += dy;
+ }
+ }
+}
+
+void
+GraphicDevice32::drawLine(long x1, long y1, long x2, long y2, long width)
+{
+ int n,adr,dx,dy,sx,color;
+ register int a;
+ register TYPE *pp;
+ int alpha;
+
+ x1 = (x1) >> FRAC_BITS;
+ y1 = (y1) >> FRAC_BITS;
+ x2 = (x2) >> FRAC_BITS;
+ y2 = (y2) >> FRAC_BITS;
+
+ if (y1 > y2 || (y1 == y2 && x1 > x2)) {
+ long tmp;
+
+ tmp=x1;
+ x1=x2;
+ x2=tmp;
+
+ tmp=y1;
+ y1=y2;
+ y2=tmp;
+ }
+
+ if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return;
+ if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return;
+ if (x1 == x2 && y1 == y2) return; // Bad !!!
+
+ if (y1 < clip_rect.ymin && y1 != y2) {
+ x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1);
+ y1 = clip_rect.ymin;
+ }
+
+ if (y2 > clip_rect.ymax && y1 != y2) {
+ x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1);
+ y2 = clip_rect.ymax;
+ }
+
+ if (x1 < x2) {
+ if (x1 < clip_rect.xmin && x1 != x2) {
+ y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1);
+ x1 = clip_rect.xmin;
+ }
+
+ if (x2 > clip_rect.xmax && x1 != x2) {
+ y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1);
+ x2 = clip_rect.xmax;
+ }
+ }
+
+ if (x1 > x2) {
+ if (x2 < clip_rect.xmin && x2 != x1) {
+ y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2);
+ x2 = clip_rect.xmin;
+ }
+
+ if (x1 > clip_rect.xmax && x2 != x1) {
+ y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2);
+ x1 = clip_rect.xmax;
+ }
+ }
+
+ // Check again
+ if (x1 == x2 && y1 == y2) return;
+ if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return;
+ if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return;
+ if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return;
+ if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return;
+
+ sx=bpl >> 1;
+ adr=(y1 * sx + x1);
+ pp = (TYPE *)canvasBuffer + adr;
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+
+ color = allocColor(foregroundColor);
+ alpha = foregroundColor.alpha;
+
+ if (alpha == ALPHA_OPAQUE) {
+
+#define PUTPIXEL() \
+ { \
+ *pp=color; \
+ }
+
+#define DRAWLINE(dx,dy,inc_1,inc_2) \
+ n=dx;\
+ a=2*dy-dx;\
+ dy=2*dy;\
+ dx=2*dx-dy;\
+ do {\
+ PUTPIXEL();\
+ if (a>0) { pp+=(inc_1); a-=dx; }\
+ else { pp+=(inc_2); a+=dy; }\
+ } while (--n >= 0);
+
+/* fin macro */
+
+ if (dx == 0 && dy == 0) {
+ PUTPIXEL();
+ } else if (dx > 0) {
+ if (dx >= dy) {
+ DRAWLINE(dx, dy, sx + 1, 1);
+ } else {
+ DRAWLINE(dy, dx, sx + 1, sx);
+ }
+ } else {
+ dx = -dx;
+ if (dx >= dy) {
+ DRAWLINE(dx, dy, sx - 1, -1);
+ } else {
+ DRAWLINE(dy, dx, sx - 1, sx);
+ }
+ }
+
+
+#undef DRAWLINE
+#undef PUTPIXEL
+ } else {
+#define PUTPIXEL() \
+ { \
+ *pp=mix_alpha(*pp,color,alpha); \
+ }
+
+#define DRAWLINE(dx,dy,inc_1,inc_2) \
+ n=dx;\
+ a=2*dy-dx;\
+ dy=2*dy;\
+ dx=2*dx-dy;\
+ do {\
+ PUTPIXEL();\
+ if (a>0) { pp+=(inc_1); a-=dx; }\
+ else { pp+=(inc_2); a+=dy; }\
+ } while (--n >= 0);
+
+/* fin macro */
+
+ if (dx == 0 && dy == 0) {
+ PUTPIXEL();
+ } else if (dx > 0) {
+ if (dx >= dy) {
+ DRAWLINE(dx, dy, sx + 1, 1);
+ } else {
+ DRAWLINE(dy, dx, sx + 1, sx);
+ }
+ } else {
+ dx = -dx;
+ if (dx >= dy) {
+ DRAWLINE(dx, dy, sx - 1, -1);
+ } else {
+ DRAWLINE(dy, dx, sx - 1, sx);
+ }
+ }
+
+
+#undef DRAWLINE
+#undef PUTPIXEL
+ }
+}
diff --git a/core/multimedia/opieplayer/libflash/graphic32.h b/core/multimedia/opieplayer/libflash/graphic32.h
new file mode 100644
index 0000000..3d75a4d
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/graphic32.h
@@ -0,0 +1,39 @@
+////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+class GraphicDevice32: public GraphicDevice {
+private:
+ long GraphicDevice32::allocColor(Color color);
+
+public:
+ GraphicDevice32(FlashDisplay *fd);
+
+ void clearCanvas();
+ void fillLineAA(FillStyleDef *f, long y, long start, long end);
+ void fillLine(FillStyleDef *f, long y, long start, long end);
+ void fillLineBitmap(FillStyleDef *f, long y, long start, long end);
+ void fillLineLG(Gradient *grad, long y, long start, long end);
+ void fillLineRG(Gradient *grad, long y, long start, long end);
+ void drawLine(long x1, long y1, long x2, long y2, long width);
+};
diff --git a/core/multimedia/opieplayer/libflash/jconfig.h b/core/multimedia/opieplayer/libflash/jconfig.h
new file mode 100644
index 0000000..9594ec5
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/jconfig.h
@@ -0,0 +1,45 @@
+/* jconfig.h. Generated automatically by configure. */
+/* jconfig.cfg --- source file edited by configure script */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+#undef void
+#undef const
+#undef CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#undef NEED_FAR_POINTERS
+#undef NEED_SHORT_EXTERNAL_NAMES
+/* Define this if you get warnings about undefined structures. */
+#undef INCOMPLETE_TYPES_BROKEN
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+#define INLINE __inline__
+/* These are for configuring the JPEG memory manager. */
+#undef DEFAULT_MAX_MEM
+#undef NO_MKTEMP
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+#undef TWO_FILE_COMMANDLINE
+#undef NEED_SIGNAL_CATCHER
+#undef DONT_USE_B_MODE
+
+/* Define this if you want percent-done progress reports from cjpeg/djpeg. */
+#undef PROGRESS_REPORT
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/core/multimedia/opieplayer/libflash/jerror.h b/core/multimedia/opieplayer/libflash/jerror.h
new file mode 100644
index 0000000..fc2fffe
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/jerror.h
@@ -0,0 +1,291 @@
+/*
+ * jerror.h
+ *
+ * Copyright (C) 1994-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file defines the error and message codes for the JPEG library.
+ * Edit this file to add new codes, or to translate the message strings to
+ * some other language.
+ * A set of error-reporting macros are defined too. Some applications using
+ * the JPEG library may wish to include this file to get the error codes
+ * and/or the macros.
+ */
+
+/*
+ * To define the enum list of message codes, include this file without
+ * defining macro JMESSAGE. To create a message string table, include it
+ * again with a suitable JMESSAGE definition (see jerror.c for an example).
+ */
+#ifndef JMESSAGE
+#ifndef JERROR_H
+/* First time through, define the enum list */
+#define JMAKE_ENUM_LIST
+#else
+/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
+#define JMESSAGE(code,string)
+#endif /* JERROR_H */
+#endif /* JMESSAGE */
+
+#ifdef JMAKE_ENUM_LIST
+
+typedef enum {
+
+#define JMESSAGE(code,string) code ,
+
+#endif /* JMAKE_ENUM_LIST */
+
+JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
+
+/* For maintenance convenience, list is alphabetical by message code name */
+JMESSAGE(JERR_ARITH_NOTIMPL,
+ "Sorry, there are legal restrictions on arithmetic coding")
+JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
+JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
+JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
+JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
+JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
+JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
+JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
+JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
+JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
+JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
+JMESSAGE(JERR_BAD_LIB_VERSION,
+ "Wrong JPEG library version: library is %d, caller expects %d")
+JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
+JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
+JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
+JMESSAGE(JERR_BAD_PROGRESSION,
+ "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
+JMESSAGE(JERR_BAD_PROG_SCRIPT,
+ "Invalid progressive parameters at scan script entry %d")
+JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
+JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
+JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
+JMESSAGE(JERR_BAD_STRUCT_SIZE,
+ "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
+JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
+JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
+JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
+JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
+JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
+JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
+JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
+JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
+JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
+JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
+JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
+JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
+JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
+JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
+JMESSAGE(JERR_FILE_READ, "Input file read error")
+JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
+JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
+JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
+JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
+JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
+JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
+JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
+JMESSAGE(JERR_MISMATCHED_QUANT_TABLE,
+ "Cannot transcode due to multiple use of quantization table %d")
+JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
+JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
+JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
+JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
+JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
+JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
+JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image")
+JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined")
+JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
+JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
+JMESSAGE(JERR_QUANT_COMPONENTS,
+ "Cannot quantize more than %d color components")
+JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
+JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
+JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
+JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
+JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
+JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
+JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
+JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
+JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
+JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
+JMESSAGE(JERR_TFILE_WRITE,
+ "Write failed on temporary file --- out of disk space?")
+JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
+JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
+JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
+JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
+JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
+JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
+JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
+JMESSAGE(JMSG_VERSION, JVERSION)
+JMESSAGE(JTRC_16BIT_TABLES,
+ "Caution: quantization tables are too coarse for baseline JPEG")
+JMESSAGE(JTRC_ADOBE,
+ "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
+JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
+JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
+JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
+JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
+JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d")
+JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
+JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
+JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
+JMESSAGE(JTRC_EOI, "End Of Image")
+JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d")
+JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d")
+JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
+ "Warning: thumbnail image size does not match data length %u")
+JMESSAGE(JTRC_JFIF_EXTENSION,
+ "JFIF extension marker: type 0x%02x, length %u")
+JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image")
+JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
+JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
+JMESSAGE(JTRC_QUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u")
+JMESSAGE(JTRC_QUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
+JMESSAGE(JTRC_QUANT_NCOLORS, "Quantizing to %d colors")
+JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization")
+JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
+JMESSAGE(JTRC_RST, "RST%d")
+JMESSAGE(JTRC_SMOOTH_NOTIMPL,
+ "Smoothing not supported with nonstandard sampling ratios")
+JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
+JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d")
+JMESSAGE(JTRC_SOI, "Start of Image")
+JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
+JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d")
+JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d")
+JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
+JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
+JMESSAGE(JTRC_THUMB_JPEG,
+ "JFIF extension marker: JPEG-compressed thumbnail image, length %u")
+JMESSAGE(JTRC_THUMB_PALETTE,
+ "JFIF extension marker: palette thumbnail image, length %u")
+JMESSAGE(JTRC_THUMB_RGB,
+ "JFIF extension marker: RGB thumbnail image, length %u")
+JMESSAGE(JTRC_UNKNOWN_IDS,
+ "Unrecognized component IDs %d %d %d, assuming YCbCr")
+JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
+JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
+JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
+JMESSAGE(JWRN_BOGUS_PROGRESSION,
+ "Inconsistent progression sequence for component %d coefficient %d")
+JMESSAGE(JWRN_EXTRANEOUS_DATA,
+ "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
+JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
+JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
+JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
+JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
+JMESSAGE(JWRN_MUST_RESYNC,
+ "Corrupt JPEG data: found marker 0x%02x instead of RST%d")
+JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG")
+JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
+
+#ifdef JMAKE_ENUM_LIST
+
+ JMSG_LASTMSGCODE
+} J_MESSAGE_CODE;
+
+#undef JMAKE_ENUM_LIST
+#endif /* JMAKE_ENUM_LIST */
+
+/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
+#undef JMESSAGE
+
+
+#ifndef JERROR_H
+#define JERROR_H
+
+/* Macros to simplify using the error and trace message stuff */
+/* The first parameter is either type of cinfo pointer */
+
+/* Fatal errors (print message and exit) */
+#define ERREXIT(cinfo,code) \
+ ((cinfo)->err->msg_code = (code), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT1(cinfo,code,p1) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT2(cinfo,code,p1,p2) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT3(cinfo,code,p1,p2,p3) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (cinfo)->err->msg_parm.i[2] = (p3), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (cinfo)->err->msg_parm.i[2] = (p3), \
+ (cinfo)->err->msg_parm.i[3] = (p4), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXITS(cinfo,code,str) \
+ ((cinfo)->err->msg_code = (code), \
+ strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+
+#define MAKESTMT(stuff) do { stuff } while (0)
+
+/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
+#define WARNMS(cinfo,code) \
+ ((cinfo)->err->msg_code = (code), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
+#define WARNMS1(cinfo,code,p1) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
+#define WARNMS2(cinfo,code,p1,p2) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
+
+/* Informational/debugging messages */
+#define TRACEMS(cinfo,lvl,code) \
+ ((cinfo)->err->msg_code = (code), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+#define TRACEMS1(cinfo,lvl,code,p1) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+#define TRACEMS2(cinfo,lvl,code,p1,p2) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \
+ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
+ (cinfo)->err->msg_code = (code); \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \
+ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
+ (cinfo)->err->msg_code = (code); \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \
+ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
+ _mp[4] = (p5); \
+ (cinfo)->err->msg_code = (code); \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \
+ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
+ _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
+ (cinfo)->err->msg_code = (code); \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMSS(cinfo,lvl,code,str) \
+ ((cinfo)->err->msg_code = (code), \
+ strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+
+#endif /* JERROR_H */
diff --git a/core/multimedia/opieplayer/libflash/jmorecfg.h b/core/multimedia/opieplayer/libflash/jmorecfg.h
new file mode 100644
index 0000000..54a7d1c
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/jmorecfg.h
@@ -0,0 +1,363 @@
+/*
+ * jmorecfg.h
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file contains additional configuration options that customize the
+ * JPEG software for special applications or support machine-dependent
+ * optimizations. Most users will not need to touch this file.
+ */
+
+
+/*
+ * Define BITS_IN_JSAMPLE as either
+ * 8 for 8-bit sample values (the usual setting)
+ * 12 for 12-bit sample values
+ * Only 8 and 12 are legal data precisions for lossy JPEG according to the
+ * JPEG standard, and the IJG code does not support anything else!
+ * We do not support run-time selection of data precision, sorry.
+ */
+
+#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */
+
+
+/*
+ * Maximum number of components (color channels) allowed in JPEG image.
+ * To meet the letter of the JPEG spec, set this to 255. However, darn
+ * few applications need more than 4 channels (maybe 5 for CMYK + alpha
+ * mask). We recommend 10 as a reasonable compromise; use 4 if you are
+ * really short on memory. (Each allowed component costs a hundred or so
+ * bytes of storage, whether actually used in an image or not.)
+ */
+
+#define MAX_COMPONENTS 10 /* maximum number of image components */
+
+
+/*
+ * Basic data types.
+ * You may need to change these if you have a machine with unusual data
+ * type sizes; for example, "char" not 8 bits, "short" not 16 bits,
+ * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits,
+ * but it had better be at least 16.
+ */
+
+/* Representation of a single sample (pixel element value).
+ * We frequently allocate large arrays of these, so it's important to keep
+ * them small. But if you have memory to burn and access to char or short
+ * arrays is very slow on your hardware, you might want to change these.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+/* JSAMPLE should be the smallest type that will hold the values 0..255.
+ * You can use a signed char by having GETJSAMPLE mask it with 0xFF.
+ */
+
+#ifdef HAVE_UNSIGNED_CHAR
+
+typedef unsigned char JSAMPLE;
+#define GETJSAMPLE(value) ((int) (value))
+
+#else /* not HAVE_UNSIGNED_CHAR */
+
+typedef char JSAMPLE;
+#ifdef CHAR_IS_UNSIGNED
+#define GETJSAMPLE(value) ((int) (value))
+#else
+#define GETJSAMPLE(value) ((int) (value) & 0xFF)
+#endif /* CHAR_IS_UNSIGNED */
+
+#endif /* HAVE_UNSIGNED_CHAR */
+
+#define MAXJSAMPLE 255
+#define CENTERJSAMPLE 128
+
+#endif /* BITS_IN_JSAMPLE == 8 */
+
+
+#if BITS_IN_JSAMPLE == 12
+/* JSAMPLE should be the smallest type that will hold the values 0..4095.
+ * On nearly all machines "short" will do nicely.
+ */
+
+typedef short JSAMPLE;
+#define GETJSAMPLE(value) ((int) (value))
+
+#define MAXJSAMPLE 4095
+#define CENTERJSAMPLE 2048
+
+#endif /* BITS_IN_JSAMPLE == 12 */
+
+
+/* Representation of a DCT frequency coefficient.
+ * This should be a signed value of at least 16 bits; "short" is usually OK.
+ * Again, we allocate large arrays of these, but you can change to int
+ * if you have memory to burn and "short" is really slow.
+ */
+
+typedef short JCOEF;
+
+
+/* Compressed datastreams are represented as arrays of JOCTET.
+ * These must be EXACTLY 8 bits wide, at least once they are written to
+ * external storage. Note that when using the stdio data source/destination
+ * managers, this is also the data type passed to fread/fwrite.
+ */
+
+#ifdef HAVE_UNSIGNED_CHAR
+
+typedef unsigned char JOCTET;
+#define GETJOCTET(value) (value)
+
+#else /* not HAVE_UNSIGNED_CHAR */
+
+typedef char JOCTET;
+#ifdef CHAR_IS_UNSIGNED
+#define GETJOCTET(value) (value)
+#else
+#define GETJOCTET(value) ((value) & 0xFF)
+#endif /* CHAR_IS_UNSIGNED */
+
+#endif /* HAVE_UNSIGNED_CHAR */
+
+
+/* These typedefs are used for various table entries and so forth.
+ * They must be at least as wide as specified; but making them too big
+ * won't cost a huge amount of memory, so we don't provide special
+ * extraction code like we did for JSAMPLE. (In other words, these
+ * typedefs live at a different point on the speed/space tradeoff curve.)
+ */
+
+/* UINT8 must hold at least the values 0..255. */
+
+#ifdef HAVE_UNSIGNED_CHAR
+typedef unsigned char UINT8;
+#else /* not HAVE_UNSIGNED_CHAR */
+#ifdef CHAR_IS_UNSIGNED
+typedef char UINT8;
+#else /* not CHAR_IS_UNSIGNED */
+typedef short UINT8;
+#endif /* CHAR_IS_UNSIGNED */
+#endif /* HAVE_UNSIGNED_CHAR */
+
+/* UINT16 must hold at least the values 0..65535. */
+
+#ifdef HAVE_UNSIGNED_SHORT
+typedef unsigned short UINT16;
+#else /* not HAVE_UNSIGNED_SHORT */
+typedef unsigned int UINT16;
+#endif /* HAVE_UNSIGNED_SHORT */
+
+/* INT16 must hold at least the values -32768..32767. */
+
+#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
+typedef short INT16;
+#endif
+
+/* INT32 must hold at least signed 32-bit values. */
+
+#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
+typedef long INT32;
+#endif
+
+/* Datatype used for image dimensions. The JPEG standard only supports
+ * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
+ * "unsigned int" is sufficient on all machines. However, if you need to
+ * handle larger images and you don't mind deviating from the spec, you
+ * can change this datatype.
+ */
+
+typedef unsigned int JDIMENSION;
+
+#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
+
+
+/* These macros are used in all function definitions and extern declarations.
+ * You could modify them if you need to change function linkage conventions;
+ * in particular, you'll need to do that to make the library a Windows DLL.
+ * Another application is to make all functions global for use with debuggers
+ * or code profilers that require it.
+ */
+
+/* a function called through method pointers: */
+#define METHODDEF(type) static type
+/* a function used only in its module: */
+#define LOCAL(type) static type
+/* a function referenced thru EXTERNs: */
+#define GLOBAL(type) type
+/* a reference to a GLOBAL function: */
+#define EXTERN(type) extern type
+
+
+/* This macro is used to declare a "method", that is, a function pointer.
+ * We want to supply prototype parameters if the compiler can cope.
+ * Note that the arglist parameter must be parenthesized!
+ * Again, you can customize this if you need special linkage keywords.
+ */
+
+#ifdef HAVE_PROTOTYPES
+#define JMETHOD(type,methodname,arglist) type (*methodname) arglist
+#else
+#define JMETHOD(type,methodname,arglist) type (*methodname) ()
+#endif
+
+
+/* Here is the pseudo-keyword for declaring pointers that must be "far"
+ * on 80x86 machines. Most of the specialized coding for 80x86 is handled
+ * by just saying "FAR *" where such a pointer is needed. In a few places
+ * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
+ */
+
+#ifdef NEED_FAR_POINTERS
+#define FAR far
+#else
+#define FAR
+#endif
+
+
+/*
+ * On a few systems, type boolean and/or its values FALSE, TRUE may appear
+ * in standard header files. Or you may have conflicts with application-
+ * specific header files that you want to include together with these files.
+ * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
+ */
+
+#ifndef HAVE_BOOLEAN
+typedef int boolean;
+#endif
+#ifndef FALSE /* in case these macros already exist */
+#define FALSE 0 /* values of boolean */
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+
+/*
+ * The remaining options affect code selection within the JPEG library,
+ * but they don't need to be visible to most applications using the library.
+ * To minimize application namespace pollution, the symbols won't be
+ * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
+ */
+
+#ifdef JPEG_INTERNALS
+#define JPEG_INTERNAL_OPTIONS
+#endif
+
+#ifdef JPEG_INTERNAL_OPTIONS
+
+
+/*
+ * These defines indicate whether to include various optional functions.
+ * Undefining some of these symbols will produce a smaller but less capable
+ * library. Note that you can leave certain source files out of the
+ * compilation/linking process if you've #undef'd the corresponding symbols.
+ * (You may HAVE to do that if your compiler doesn't like null source files.)
+ */
+
+/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */
+
+/* Capability options common to encoder and decoder: */
+
+#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */
+#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */
+#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */
+
+/* Encoder capability options: */
+
+#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
+#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
+#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
+#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
+/* Note: if you selected 12-bit data precision, it is dangerous to turn off
+ * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit
+ * precision, so jchuff.c normally uses entropy optimization to compute
+ * usable tables for higher precision. If you don't want to do optimization,
+ * you'll have to supply different default Huffman tables.
+ * The exact same statements apply for progressive JPEG: the default tables
+ * don't work for progressive mode. (This may get fixed, however.)
+ */
+#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */
+
+/* Decoder capability options: */
+
+#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
+#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
+#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
+#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
+#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
+#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
+#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
+#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */
+#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
+#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */
+
+/* more capability options later, no doubt */
+
+
+/*
+ * Ordering of RGB data in scanlines passed to or from the application.
+ * If your application wants to deal with data in the order B,G,R, just
+ * change these macros. You can also deal with formats such as R,G,B,X
+ * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing
+ * the offsets will also change the order in which colormap data is organized.
+ * RESTRICTIONS:
+ * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
+ * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
+ * useful if you are using JPEG color spaces other than YCbCr or grayscale.
+ * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
+ * is not 3 (they don't understand about dummy color components!). So you
+ * can't use color quantization if you change that value.
+ */
+
+#define RGB_RED 0 /* Offset of Red in an RGB scanline element */
+#define RGB_GREEN 1 /* Offset of Green */
+#define RGB_BLUE 2 /* Offset of Blue */
+#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */
+
+
+/* Definitions for speed-related optimizations. */
+
+
+/* If your compiler supports inline functions, define INLINE
+ * as the inline keyword; otherwise define it as empty.
+ */
+
+#ifndef INLINE
+#ifdef __GNUC__ /* for instance, GNU C knows about inline */
+#define INLINE __inline__
+#endif
+#ifndef INLINE
+#define INLINE /* default is to define it as empty */
+#endif
+#endif
+
+
+/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
+ * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER
+ * as short on such a machine. MULTIPLIER must be at least 16 bits wide.
+ */
+
+#ifndef MULTIPLIER
+#define MULTIPLIER int /* type for fastest integer multiply */
+#endif
+
+
+/* FAST_FLOAT should be either float or double, whichever is done faster
+ * by your compiler. (Note that this type is only used in the floating point
+ * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
+ * Typically, float is faster in ANSI C compilers, while double is faster in
+ * pre-ANSI compilers (because they insist on converting to double anyway).
+ * The code below therefore chooses float if we have ANSI-style prototypes.
+ */
+
+#ifndef FAST_FLOAT
+#ifdef HAVE_PROTOTYPES
+#define FAST_FLOAT float
+#else
+#define FAST_FLOAT double
+#endif
+#endif
+
+#endif /* JPEG_INTERNAL_OPTIONS */
diff --git a/core/multimedia/opieplayer/libflash/jpeglib.h b/core/multimedia/opieplayer/libflash/jpeglib.h
new file mode 100644
index 0000000..d1be8dd
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/jpeglib.h
@@ -0,0 +1,1096 @@
+/*
+ * jpeglib.h
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file defines the application interface for the JPEG library.
+ * Most applications using the library need only include this file,
+ * and perhaps jerror.h if they want to know the exact error codes.
+ */
+
+#ifndef JPEGLIB_H
+#define JPEGLIB_H
+
+/*
+ * First we include the configuration files that record how this
+ * installation of the JPEG library is set up. jconfig.h can be
+ * generated automatically for many systems. jmorecfg.h contains
+ * manual configuration options that most people need not worry about.
+ */
+
+#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */
+#include "jconfig.h" /* widely used configuration options */
+#endif
+#include "jmorecfg.h" /* seldom changed options */
+
+
+/* Version ID for the JPEG library.
+ * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
+ */
+
+#define JPEG_LIB_VERSION 62 /* Version 6b */
+
+
+/* Various constants determining the sizes of things.
+ * All of these are specified by the JPEG standard, so don't change them
+ * if you want to be compatible.
+ */
+
+#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */
+#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */
+#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */
+#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */
+#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */
+#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */
+#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */
+/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard;
+ * the PostScript DCT filter can emit files with many more than 10 blocks/MCU.
+ * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU
+ * to handle it. We even let you do this from the jconfig.h file. However,
+ * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe
+ * sometimes emits noncompliant files doesn't mean you should too.
+ */
+#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */
+#ifndef D_MAX_BLOCKS_IN_MCU
+#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */
+#endif
+
+
+/* Data structures for images (arrays of samples and of DCT coefficients).
+ * On 80x86 machines, the image arrays are too big for near pointers,
+ * but the pointer arrays can fit in near memory.
+ */
+
+typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */
+typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */
+typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */
+
+typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */
+typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */
+typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */
+typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */
+
+typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */
+
+
+/* Types for JPEG compression parameters and working tables. */
+
+
+/* DCT coefficient quantization tables. */
+
+typedef struct {
+ /* This array gives the coefficient quantizers in natural array order
+ * (not the zigzag order in which they are stored in a JPEG DQT marker).
+ * CAUTION: IJG versions prior to v6a kept this array in zigzag order.
+ */
+ UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */
+ /* This field is used only during compression. It's initialized FALSE when
+ * the table is created, and set TRUE when it's been output to the file.
+ * You could suppress output of a table by setting this to TRUE.
+ * (See jpeg_suppress_tables for an example.)
+ */
+ boolean sent_table; /* TRUE when table has been output */
+} JQUANT_TBL;
+
+
+/* Huffman coding tables. */
+
+typedef struct {
+ /* These two fields directly represent the contents of a JPEG DHT marker */
+ UINT8 bits[17]; /* bits[k] = # of symbols with codes of */
+ /* length k bits; bits[0] is unused */
+ UINT8 huffval[256]; /* The symbols, in order of incr code length */
+ /* This field is used only during compression. It's initialized FALSE when
+ * the table is created, and set TRUE when it's been output to the file.
+ * You could suppress output of a table by setting this to TRUE.
+ * (See jpeg_suppress_tables for an example.)
+ */
+ boolean sent_table; /* TRUE when table has been output */
+} JHUFF_TBL;
+
+
+/* Basic info about one component (color channel). */
+
+typedef struct {
+ /* These values are fixed over the whole image. */
+ /* For compression, they must be supplied by parameter setup; */
+ /* for decompression, they are read from the SOF marker. */
+ int component_id; /* identifier for this component (0..255) */
+ int component_index; /* its index in SOF or cinfo->comp_info[] */
+ int h_samp_factor; /* horizontal sampling factor (1..4) */
+ int v_samp_factor; /* vertical sampling factor (1..4) */
+ int quant_tbl_no; /* quantization table selector (0..3) */
+ /* These values may vary between scans. */
+ /* For compression, they must be supplied by parameter setup; */
+ /* for decompression, they are read from the SOS marker. */
+ /* The decompressor output side may not use these variables. */
+ int dc_tbl_no; /* DC entropy table selector (0..3) */
+ int ac_tbl_no; /* AC entropy table selector (0..3) */
+
+ /* Remaining fields should be treated as private by applications. */
+
+ /* These values are computed during compression or decompression startup: */
+ /* Component's size in DCT blocks.
+ * Any dummy blocks added to complete an MCU are not counted; therefore
+ * these values do not depend on whether a scan is interleaved or not.
+ */
+ JDIMENSION width_in_blocks;
+ JDIMENSION height_in_blocks;
+ /* Size of a DCT block in samples. Always DCTSIZE for compression.
+ * For decompression this is the size of the output from one DCT block,
+ * reflecting any scaling we choose to apply during the IDCT step.
+ * Values of 1,2,4,8 are likely to be supported. Note that different
+ * components may receive different IDCT scalings.
+ */
+ int DCT_scaled_size;
+ /* The downsampled dimensions are the component's actual, unpadded number
+ * of samples at the main buffer (preprocessing/compression interface), thus
+ * downsampled_width = ceil(image_width * Hi/Hmax)
+ * and similarly for height. For decompression, IDCT scaling is included, so
+ * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)
+ */
+ JDIMENSION downsampled_width; /* actual width in samples */
+ JDIMENSION downsampled_height; /* actual height in samples */
+ /* This flag is used only for decompression. In cases where some of the
+ * components will be ignored (eg grayscale output from YCbCr image),
+ * we can skip most computations for the unused components.
+ */
+ boolean component_needed; /* do we need the value of this component? */
+
+ /* These values are computed before starting a scan of the component. */
+ /* The decompressor output side may not use these variables. */
+ int MCU_width; /* number of blocks per MCU, horizontally */
+ int MCU_height; /* number of blocks per MCU, vertically */
+ int MCU_blocks; /* MCU_width * MCU_height */
+ int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */
+ int last_col_width; /* # of non-dummy blocks across in last MCU */
+ int last_row_height; /* # of non-dummy blocks down in last MCU */
+
+ /* Saved quantization table for component; NULL if none yet saved.
+ * See jdinput.c comments about the need for this information.
+ * This field is currently used only for decompression.
+ */
+ JQUANT_TBL * quant_table;
+
+ /* Private per-component storage for DCT or IDCT subsystem. */
+ void * dct_table;
+} jpeg_component_info;
+
+
+/* The script for encoding a multiple-scan file is an array of these: */
+
+typedef struct {
+ int comps_in_scan; /* number of components encoded in this scan */
+ int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */
+ int Ss, Se; /* progressive JPEG spectral selection parms */
+ int Ah, Al; /* progressive JPEG successive approx. parms */
+} jpeg_scan_info;
+
+/* The decompressor can save APPn and COM markers in a list of these: */
+
+typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr;
+
+struct jpeg_marker_struct {
+ jpeg_saved_marker_ptr next; /* next in list, or NULL */
+ UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */
+ unsigned int original_length; /* # bytes of data in the file */
+ unsigned int data_length; /* # bytes of data saved at data[] */
+ JOCTET FAR * data; /* the data contained in the marker */
+ /* the marker length word is not counted in data_length or original_length */
+};
+
+/* Known color spaces. */
+
+typedef enum {
+ JCS_UNKNOWN, /* error/unspecified */
+ JCS_GRAYSCALE, /* monochrome */
+ JCS_RGB, /* red/green/blue */
+ JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
+ JCS_CMYK, /* C/M/Y/K */
+ JCS_YCCK /* Y/Cb/Cr/K */
+} J_COLOR_SPACE;
+
+/* DCT/IDCT algorithm options. */
+
+typedef enum {
+ JDCT_ISLOW, /* slow but accurate integer algorithm */
+ JDCT_IFAST, /* faster, less accurate integer method */
+ JDCT_FLOAT /* floating-point: accurate, fast on fast HW */
+} J_DCT_METHOD;
+
+#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */
+#define JDCT_DEFAULT JDCT_ISLOW
+#endif
+#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */
+#define JDCT_FASTEST JDCT_IFAST
+#endif
+
+/* Dithering options for decompression. */
+
+typedef enum {
+ JDITHER_NONE, /* no dithering */
+ JDITHER_ORDERED, /* simple ordered dither */
+ JDITHER_FS /* Floyd-Steinberg error diffusion dither */
+} J_DITHER_MODE;
+
+
+/* Common fields between JPEG compression and decompression master structs. */
+
+#define jpeg_common_fields \
+ struct jpeg_error_mgr * err; /* Error handler module */\
+ struct jpeg_memory_mgr * mem; /* Memory manager module */\
+ struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\
+ void * client_data; /* Available for use by application */\
+ boolean is_decompressor; /* So common code can tell which is which */\
+ int global_state /* For checking call sequence validity */
+
+/* Routines that are to be used by both halves of the library are declared
+ * to receive a pointer to this structure. There are no actual instances of
+ * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
+ */
+struct jpeg_common_struct {
+ jpeg_common_fields; /* Fields common to both master struct types */
+ /* Additional fields follow in an actual jpeg_compress_struct or
+ * jpeg_decompress_struct. All three structs must agree on these
+ * initial fields! (This would be a lot cleaner in C++.)
+ */
+};
+
+typedef struct jpeg_common_struct * j_common_ptr;
+typedef struct jpeg_compress_struct * j_compress_ptr;
+typedef struct jpeg_decompress_struct * j_decompress_ptr;
+
+
+/* Master record for a compression instance */
+
+struct jpeg_compress_struct {
+ jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */
+
+ /* Destination for compressed data */
+ struct jpeg_destination_mgr * dest;
+
+ /* Description of source image --- these fields must be filled in by
+ * outer application before starting compression. in_color_space must
+ * be correct before you can even call jpeg_set_defaults().
+ */
+
+ JDIMENSION image_width; /* input image width */
+ JDIMENSION image_height; /* input image height */
+ int input_components; /* # of color components in input image */
+ J_COLOR_SPACE in_color_space; /* colorspace of input image */
+
+ double input_gamma; /* image gamma of input image */
+
+ /* Compression parameters --- these fields must be set before calling
+ * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to
+ * initialize everything to reasonable defaults, then changing anything
+ * the application specifically wants to change. That way you won't get
+ * burnt when new parameters are added. Also note that there are several
+ * helper routines to simplify changing parameters.
+ */
+
+ int data_precision; /* bits of precision in image data */
+
+ int num_components; /* # of color components in JPEG image */
+ J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
+
+ jpeg_component_info * comp_info;
+ /* comp_info[i] describes component that appears i'th in SOF */
+
+ JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
+ /* ptrs to coefficient quantization tables, or NULL if not defined */
+
+ JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ /* ptrs to Huffman coding tables, or NULL if not defined */
+
+ UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
+ UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
+ UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
+
+ int num_scans; /* # of entries in scan_info array */
+ const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */
+ /* The default value of scan_info is NULL, which causes a single-scan
+ * sequential JPEG file to be emitted. To create a multi-scan file,
+ * set num_scans and scan_info to point to an array of scan definitions.
+ */
+
+ boolean raw_data_in; /* TRUE=caller supplies downsampled data */
+ boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
+ boolean optimize_coding; /* TRUE=optimize entropy encoding parms */
+ boolean CCIR601_sampling; /* TRUE=first samples are cosited */
+ int smoothing_factor; /* 1..100, or 0 for no input smoothing */
+ J_DCT_METHOD dct_method; /* DCT algorithm selector */
+
+ /* The restart interval can be specified in absolute MCUs by setting
+ * restart_interval, or in MCU rows by setting restart_in_rows
+ * (in which case the correct restart_interval will be figured
+ * for each scan).
+ */
+ unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */
+ int restart_in_rows; /* if > 0, MCU rows per restart interval */
+
+ /* Parameters controlling emission of special markers. */
+
+ boolean write_JFIF_header; /* should a JFIF marker be written? */
+ UINT8 JFIF_major_version; /* What to write for the JFIF version number */
+ UINT8 JFIF_minor_version;
+ /* These three values are not used by the JPEG code, merely copied */
+ /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */
+ /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */
+ /* ratio is defined by X_density/Y_density even when density_unit=0. */
+ UINT8 density_unit; /* JFIF code for pixel size units */
+ UINT16 X_density; /* Horizontal pixel density */
+ UINT16 Y_density; /* Vertical pixel density */
+ boolean write_Adobe_marker; /* should an Adobe marker be written? */
+
+ /* State variable: index of next scanline to be written to
+ * jpeg_write_scanlines(). Application may use this to control its
+ * processing loop, e.g., "while (next_scanline < image_height)".
+ */
+
+ JDIMENSION next_scanline; /* 0 .. image_height-1 */
+
+ /* Remaining fields are known throughout compressor, but generally
+ * should not be touched by a surrounding application.
+ */
+
+ /*
+ * These fields are computed during compression startup
+ */
+ boolean progressive_mode; /* TRUE if scan script uses progressive mode */
+ int max_h_samp_factor; /* largest h_samp_factor */
+ int max_v_samp_factor; /* largest v_samp_factor */
+
+ JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */
+ /* The coefficient controller receives data in units of MCU rows as defined
+ * for fully interleaved scans (whether the JPEG file is interleaved or not).
+ * There are v_samp_factor * DCTSIZE sample rows of each component in an
+ * "iMCU" (interleaved MCU) row.
+ */
+
+ /*
+ * These fields are valid during any one scan.
+ * They describe the components and MCUs actually appearing in the scan.
+ */
+ int comps_in_scan; /* # of JPEG components in this scan */
+ jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
+ /* *cur_comp_info[i] describes component that appears i'th in SOS */
+
+ JDIMENSION MCUs_per_row; /* # of MCUs across the image */
+ JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
+
+ int blocks_in_MCU; /* # of DCT blocks per MCU */
+ int MCU_membership[C_MAX_BLOCKS_IN_MCU];
+ /* MCU_membership[i] is index in cur_comp_info of component owning */
+ /* i'th block in an MCU */
+
+ int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
+
+ /*
+ * Links to compression subobjects (methods and private variables of modules)
+ */
+ struct jpeg_comp_master * master;
+ struct jpeg_c_main_controller * main;
+ struct jpeg_c_prep_controller * prep;
+ struct jpeg_c_coef_controller * coef;
+ struct jpeg_marker_writer * marker;
+ struct jpeg_color_converter * cconvert;
+ struct jpeg_downsampler * downsample;
+ struct jpeg_forward_dct * fdct;
+ struct jpeg_entropy_encoder * entropy;
+ jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */
+ int script_space_size;
+};
+
+
+/* Master record for a decompression instance */
+
+struct jpeg_decompress_struct {
+ jpeg_common_fields; /* Fields shared with jpeg_compress_struct */
+
+ /* Source of compressed data */
+ struct jpeg_source_mgr * src;
+
+ /* Basic description of image --- filled in by jpeg_read_header(). */
+ /* Application may inspect these values to decide how to process image. */
+
+ JDIMENSION image_width; /* nominal image width (from SOF marker) */
+ JDIMENSION image_height; /* nominal image height */
+ int num_components; /* # of color components in JPEG image */
+ J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
+
+ /* Decompression processing parameters --- these fields must be set before
+ * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes
+ * them to default values.
+ */
+
+ J_COLOR_SPACE out_color_space; /* colorspace for output */
+
+ unsigned int scale_num, scale_denom; /* fraction by which to scale image */
+
+ double output_gamma; /* image gamma wanted in output */
+
+ boolean buffered_image; /* TRUE=multiple output passes */
+ boolean raw_data_out; /* TRUE=downsampled data wanted */
+
+ J_DCT_METHOD dct_method; /* IDCT algorithm selector */
+ boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */
+ boolean do_block_smoothing; /* TRUE=apply interblock smoothing */
+
+ boolean quantize_colors; /* TRUE=colormapped output wanted */
+ /* the following are ignored if not quantize_colors: */
+ J_DITHER_MODE dither_mode; /* type of color dithering to use */
+ boolean two_pass_quantize; /* TRUE=use two-pass color quantization */
+ int desired_number_of_colors; /* max # colors to use in created colormap */
+ /* these are significant only in buffered-image mode: */
+ boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */
+ boolean enable_external_quant;/* enable future use of external colormap */
+ boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */
+
+ /* Description of actual output image that will be returned to application.
+ * These fields are computed by jpeg_start_decompress().
+ * You can also use jpeg_calc_output_dimensions() to determine these values
+ * in advance of calling jpeg_start_decompress().
+ */
+
+ JDIMENSION output_width; /* scaled image width */
+ JDIMENSION output_height; /* scaled image height */
+ int out_color_components; /* # of color components in out_color_space */
+ int output_components; /* # of color components returned */
+ /* output_components is 1 (a colormap index) when quantizing colors;
+ * otherwise it equals out_color_components.
+ */
+ int rec_outbuf_height; /* min recommended height of scanline buffer */
+ /* If the buffer passed to jpeg_read_scanlines() is less than this many rows
+ * high, space and time will be wasted due to unnecessary data copying.
+ * Usually rec_outbuf_height will be 1 or 2, at most 4.
+ */
+
+ /* When quantizing colors, the output colormap is described by these fields.
+ * The application can supply a colormap by setting colormap non-NULL before
+ * calling jpeg_start_decompress; otherwise a colormap is created during
+ * jpeg_start_decompress or jpeg_start_output.
+ * The map has out_color_components rows and actual_number_of_colors columns.
+ */
+ int actual_number_of_colors; /* number of entries in use */
+ JSAMPARRAY colormap; /* The color map as a 2-D pixel array */
+
+ /* State variables: these variables indicate the progress of decompression.
+ * The application may examine these but must not modify them.
+ */
+
+ /* Row index of next scanline to be read from jpeg_read_scanlines().
+ * Application may use this to control its processing loop, e.g.,
+ * "while (output_scanline < output_height)".
+ */
+ JDIMENSION output_scanline; /* 0 .. output_height-1 */
+
+ /* Current input scan number and number of iMCU rows completed in scan.
+ * These indicate the progress of the decompressor input side.
+ */
+ int input_scan_number; /* Number of SOS markers seen so far */
+ JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */
+
+ /* The "output scan number" is the notional scan being displayed by the
+ * output side. The decompressor will not allow output scan/row number
+ * to get ahead of input scan/row, but it can fall arbitrarily far behind.
+ */
+ int output_scan_number; /* Nominal scan number being displayed */
+ JDIMENSION output_iMCU_row; /* Number of iMCU rows read */
+
+ /* Current progression status. coef_bits[c][i] indicates the precision
+ * with which component c's DCT coefficient i (in zigzag order) is known.
+ * It is -1 when no data has yet been received, otherwise it is the point
+ * transform (shift) value for the most recent scan of the coefficient
+ * (thus, 0 at completion of the progression).
+ * This pointer is NULL when reading a non-progressive file.
+ */
+ int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */
+
+ /* Internal JPEG parameters --- the application usually need not look at
+ * these fields. Note that the decompressor output side may not use
+ * any parameters that can change between scans.
+ */
+
+ /* Quantization and Huffman tables are carried forward across input
+ * datastreams when processing abbreviated JPEG datastreams.
+ */
+
+ JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS];
+ /* ptrs to coefficient quantization tables, or NULL if not defined */
+
+ JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ /* ptrs to Huffman coding tables, or NULL if not defined */
+
+ /* These parameters are never carried across datastreams, since they
+ * are given in SOF/SOS markers or defined to be reset by SOI.
+ */
+
+ int data_precision; /* bits of precision in image data */
+
+ jpeg_component_info * comp_info;
+ /* comp_info[i] describes component that appears i'th in SOF */
+
+ boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */
+ boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
+
+ UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
+ UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
+ UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
+
+ unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */
+
+ /* These fields record data obtained from optional markers recognized by
+ * the JPEG library.
+ */
+ boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */
+ /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */
+ UINT8 JFIF_major_version; /* JFIF version number */
+ UINT8 JFIF_minor_version;
+ UINT8 density_unit; /* JFIF code for pixel size units */
+ UINT16 X_density; /* Horizontal pixel density */
+ UINT16 Y_density; /* Vertical pixel density */
+ boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */
+ UINT8 Adobe_transform; /* Color transform code from Adobe marker */
+
+ boolean CCIR601_sampling; /* TRUE=first samples are cosited */
+
+ /* Aside from the specific data retained from APPn markers known to the
+ * library, the uninterpreted contents of any or all APPn and COM markers
+ * can be saved in a list for examination by the application.
+ */
+ jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */
+
+ /* Remaining fields are known throughout decompressor, but generally
+ * should not be touched by a surrounding application.
+ */
+
+ /*
+ * These fields are computed during decompression startup
+ */
+ int max_h_samp_factor; /* largest h_samp_factor */
+ int max_v_samp_factor; /* largest v_samp_factor */
+
+ int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */
+
+ JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */
+ /* The coefficient controller's input and output progress is measured in
+ * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows
+ * in fully interleaved JPEG scans, but are used whether the scan is
+ * interleaved or not. We define an iMCU row as v_samp_factor DCT block
+ * rows of each component. Therefore, the IDCT output contains
+ * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row.
+ */
+
+ JSAMPLE * sample_range_limit; /* table for fast range-limiting */
+
+ /*
+ * These fields are valid during any one scan.
+ * They describe the components and MCUs actually appearing in the scan.
+ * Note that the decompressor output side must not use these fields.
+ */
+ int comps_in_scan; /* # of JPEG components in this scan */
+ jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
+ /* *cur_comp_info[i] describes component that appears i'th in SOS */
+
+ JDIMENSION MCUs_per_row; /* # of MCUs across the image */
+ JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
+
+ int blocks_in_MCU; /* # of DCT blocks per MCU */
+ int MCU_membership[D_MAX_BLOCKS_IN_MCU];
+ /* MCU_membership[i] is index in cur_comp_info of component owning */
+ /* i'th block in an MCU */
+
+ int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
+
+ /* This field is shared between entropy decoder and marker parser.
+ * It is either zero or the code of a JPEG marker that has been
+ * read from the data source, but has not yet been processed.
+ */
+ int unread_marker;
+
+ /*
+ * Links to decompression subobjects (methods, private variables of modules)
+ */
+ struct jpeg_decomp_master * master;
+ struct jpeg_d_main_controller * main;
+ struct jpeg_d_coef_controller * coef;
+ struct jpeg_d_post_controller * post;
+ struct jpeg_input_controller * inputctl;
+ struct jpeg_marker_reader * marker;
+ struct jpeg_entropy_decoder * entropy;
+ struct jpeg_inverse_dct * idct;
+ struct jpeg_upsampler * upsample;
+ struct jpeg_color_deconverter * cconvert;
+ struct jpeg_color_quantizer * cquantize;
+};
+
+
+/* "Object" declarations for JPEG modules that may be supplied or called
+ * directly by the surrounding application.
+ * As with all objects in the JPEG library, these structs only define the
+ * publicly visible methods and state variables of a module. Additional
+ * private fields may exist after the public ones.
+ */
+
+
+/* Error handler object */
+
+struct jpeg_error_mgr {
+ /* Error exit handler: does not return to caller */
+ JMETHOD(void, error_exit, (j_common_ptr cinfo));
+ /* Conditionally emit a trace or warning message */
+ JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level));
+ /* Routine that actually outputs a trace or error message */
+ JMETHOD(void, output_message, (j_common_ptr cinfo));
+ /* Format a message string for the most recent JPEG error or message */
+ JMETHOD(void, format_message, (j_common_ptr cinfo, char * buffer));
+#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */
+ /* Reset error state variables at start of a new image */
+ JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo));
+
+ /* The message ID code and any parameters are saved here.
+ * A message can have one string parameter or up to 8 int parameters.
+ */
+ int msg_code;
+#define JMSG_STR_PARM_MAX 80
+ union {
+ int i[8];
+ char s[JMSG_STR_PARM_MAX];
+ } msg_parm;
+
+ /* Standard state variables for error facility */
+
+ int trace_level; /* max msg_level that will be displayed */
+
+ /* For recoverable corrupt-data errors, we emit a warning message,
+ * but keep going unless emit_message chooses to abort. emit_message
+ * should count warnings in num_warnings. The surrounding application
+ * can check for bad data by seeing if num_warnings is nonzero at the
+ * end of processing.
+ */
+ long num_warnings; /* number of corrupt-data warnings */
+
+ /* These fields point to the table(s) of error message strings.
+ * An application can change the table pointer to switch to a different
+ * message list (typically, to change the language in which errors are
+ * reported). Some applications may wish to add additional error codes
+ * that will be handled by the JPEG library error mechanism; the second
+ * table pointer is used for this purpose.
+ *
+ * First table includes all errors generated by JPEG library itself.
+ * Error code 0 is reserved for a "no such error string" message.
+ */
+ const char * const * jpeg_message_table; /* Library errors */
+ int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */
+ /* Second table can be added by application (see cjpeg/djpeg for example).
+ * It contains strings numbered first_addon_message..last_addon_message.
+ */
+ const char * const * addon_message_table; /* Non-library errors */
+ int first_addon_message; /* code for first string in addon table */
+ int last_addon_message; /* code for last string in addon table */
+};
+
+
+/* Progress monitor object */
+
+struct jpeg_progress_mgr {
+ JMETHOD(void, progress_monitor, (j_common_ptr cinfo));
+
+ long pass_counter; /* work units completed in this pass */
+ long pass_limit; /* total number of work units in this pass */
+ int completed_passes; /* passes completed so far */
+ int total_passes; /* total number of passes expected */
+};
+
+
+/* Data destination object for compression */
+
+struct jpeg_destination_mgr {
+ JOCTET * next_output_byte; /* => next byte to write in buffer */
+ size_t free_in_buffer; /* # of byte spaces remaining in buffer */
+
+ JMETHOD(void, init_destination, (j_compress_ptr cinfo));
+ JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo));
+ JMETHOD(void, term_destination, (j_compress_ptr cinfo));
+};
+
+
+/* Data source object for decompression */
+
+struct jpeg_source_mgr {
+ const JOCTET * next_input_byte; /* => next byte to read from buffer */
+ size_t bytes_in_buffer; /* # of bytes remaining in buffer */
+
+ JMETHOD(void, init_source, (j_decompress_ptr cinfo));
+ JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo));
+ JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes));
+ JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired));
+ JMETHOD(void, term_source, (j_decompress_ptr cinfo));
+};
+
+
+/* Memory manager object.
+ * Allocates "small" objects (a few K total), "large" objects (tens of K),
+ * and "really big" objects (virtual arrays with backing store if needed).
+ * The memory manager does not allow individual objects to be freed; rather,
+ * each created object is assigned to a pool, and whole pools can be freed
+ * at once. This is faster and more convenient than remembering exactly what
+ * to free, especially where malloc()/free() are not too speedy.
+ * NB: alloc routines never return NULL. They exit to error_exit if not
+ * successful.
+ */
+
+#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */
+#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */
+#define JPOOL_NUMPOOLS 2
+
+typedef struct jvirt_sarray_control * jvirt_sarray_ptr;
+typedef struct jvirt_barray_control * jvirt_barray_ptr;
+
+
+struct jpeg_memory_mgr {
+ /* Method pointers */
+ JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id,
+ size_t sizeofobject));
+ JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id,
+ size_t sizeofobject));
+ JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id,
+ JDIMENSION samplesperrow,
+ JDIMENSION numrows));
+ JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id,
+ JDIMENSION blocksperrow,
+ JDIMENSION numrows));
+ JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo,
+ int pool_id,
+ boolean pre_zero,
+ JDIMENSION samplesperrow,
+ JDIMENSION numrows,
+ JDIMENSION maxaccess));
+ JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo,
+ int pool_id,
+ boolean pre_zero,
+ JDIMENSION blocksperrow,
+ JDIMENSION numrows,
+ JDIMENSION maxaccess));
+ JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo));
+ JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo,
+ jvirt_sarray_ptr ptr,
+ JDIMENSION start_row,
+ JDIMENSION num_rows,
+ boolean writable));
+ JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo,
+ jvirt_barray_ptr ptr,
+ JDIMENSION start_row,
+ JDIMENSION num_rows,
+ boolean writable));
+ JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id));
+ JMETHOD(void, self_destruct, (j_common_ptr cinfo));
+
+ /* Limit on memory allocation for this JPEG object. (Note that this is
+ * merely advisory, not a guaranteed maximum; it only affects the space
+ * used for virtual-array buffers.) May be changed by outer application
+ * after creating the JPEG object.
+ */
+ long max_memory_to_use;
+
+ /* Maximum allocation request accepted by alloc_large. */
+ long max_alloc_chunk;
+};
+
+
+/* Routine signature for application-supplied marker processing methods.
+ * Need not pass marker code since it is stored in cinfo->unread_marker.
+ */
+typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
+
+
+/* Declarations for routines called by application.
+ * The JPP macro hides prototype parameters from compilers that can't cope.
+ * Note JPP requires double parentheses.
+ */
+
+#ifdef HAVE_PROTOTYPES
+#define JPP(arglist) arglist
+#else
+#define JPP(arglist) ()
+#endif
+
+
+/* Short forms of external names for systems with brain-damaged linkers.
+ * We shorten external names to be unique in the first six letters, which
+ * is good enough for all known systems.
+ * (If your compiler itself needs names to be unique in less than 15
+ * characters, you are out of luck. Get a better compiler.)
+ */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_std_error jStdError
+#define jpeg_CreateCompress jCreaCompress
+#define jpeg_CreateDecompress jCreaDecompress
+#define jpeg_destroy_compress jDestCompress
+#define jpeg_destroy_decompress jDestDecompress
+#define jpeg_stdio_dest jStdDest
+#define jpeg_stdio_src jStdSrc
+#define jpeg_set_defaults jSetDefaults
+#define jpeg_set_colorspace jSetColorspace
+#define jpeg_default_colorspace jDefColorspace
+#define jpeg_set_quality jSetQuality
+#define jpeg_set_linear_quality jSetLQuality
+#define jpeg_add_quant_table jAddQuantTable
+#define jpeg_quality_scaling jQualityScaling
+#define jpeg_simple_progression jSimProgress
+#define jpeg_suppress_tables jSuppressTables
+#define jpeg_alloc_quant_table jAlcQTable
+#define jpeg_alloc_huff_table jAlcHTable
+#define jpeg_start_compress jStrtCompress
+#define jpeg_write_scanlines jWrtScanlines
+#define jpeg_finish_compress jFinCompress
+#define jpeg_write_raw_data jWrtRawData
+#define jpeg_write_marker jWrtMarker
+#define jpeg_write_m_header jWrtMHeader
+#define jpeg_write_m_byte jWrtMByte
+#define jpeg_write_tables jWrtTables
+#define jpeg_read_header jReadHeader
+#define jpeg_start_decompress jStrtDecompress
+#define jpeg_read_scanlines jReadScanlines
+#define jpeg_finish_decompress jFinDecompress
+#define jpeg_read_raw_data jReadRawData
+#define jpeg_has_multiple_scans jHasMultScn
+#define jpeg_start_output jStrtOutput
+#define jpeg_finish_output jFinOutput
+#define jpeg_input_complete jInComplete
+#define jpeg_new_colormap jNewCMap
+#define jpeg_consume_input jConsumeInput
+#define jpeg_calc_output_dimensions jCalcDimensions
+#define jpeg_save_markers jSaveMarkers
+#define jpeg_set_marker_processor jSetMarker
+#define jpeg_read_coefficients jReadCoefs
+#define jpeg_write_coefficients jWrtCoefs
+#define jpeg_copy_critical_parameters jCopyCrit
+#define jpeg_abort_compress jAbrtCompress
+#define jpeg_abort_decompress jAbrtDecompress
+#define jpeg_abort jAbort
+#define jpeg_destroy jDestroy
+#define jpeg_resync_to_restart jResyncRestart
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/* Default error-management setup */
+EXTERN(struct jpeg_error_mgr *) jpeg_std_error
+ JPP((struct jpeg_error_mgr * err));
+
+/* Initialization of JPEG compression objects.
+ * jpeg_create_compress() and jpeg_create_decompress() are the exported
+ * names that applications should call. These expand to calls on
+ * jpeg_CreateCompress and jpeg_CreateDecompress with additional information
+ * passed for version mismatch checking.
+ * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx.
+ */
+#define jpeg_create_compress(cinfo) \
+ jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \
+ (size_t) sizeof(struct jpeg_compress_struct))
+#define jpeg_create_decompress(cinfo) \
+ jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \
+ (size_t) sizeof(struct jpeg_decompress_struct))
+EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo,
+ int version, size_t structsize));
+EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo,
+ int version, size_t structsize));
+/* Destruction of JPEG compression objects */
+EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo));
+
+/* Standard data source and destination managers: stdio streams. */
+/* Caller is responsible for opening the file before and closing after. */
+EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile));
+EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
+
+/* Default parameter setup for compression */
+EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
+/* Compression parameter setup aids */
+EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo,
+ J_COLOR_SPACE colorspace));
+EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
+ boolean force_baseline));
+EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
+ int scale_factor,
+ boolean force_baseline));
+EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl,
+ const unsigned int *basic_table,
+ int scale_factor,
+ boolean force_baseline));
+EXTERN(int) jpeg_quality_scaling JPP((int quality));
+EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo,
+ boolean suppress));
+EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
+EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
+
+/* Main entry points for compression */
+EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,
+ boolean write_all_tables));
+EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo,
+ JSAMPARRAY scanlines,
+ JDIMENSION num_lines));
+EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo));
+
+/* Replaces jpeg_write_scanlines when writing raw downsampled data. */
+EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo,
+ JSAMPIMAGE data,
+ JDIMENSION num_lines));
+
+/* Write a special marker. See libjpeg.doc concerning safe usage. */
+EXTERN(void) jpeg_write_marker
+ JPP((j_compress_ptr cinfo, int marker,
+ const JOCTET * dataptr, unsigned int datalen));
+/* Same, but piecemeal. */
+EXTERN(void) jpeg_write_m_header
+ JPP((j_compress_ptr cinfo, int marker, unsigned int datalen));
+EXTERN(void) jpeg_write_m_byte
+ JPP((j_compress_ptr cinfo, int val));
+
+/* Alternate compression function: just write an abbreviated table file */
+EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo));
+
+/* Decompression startup: read start of JPEG datastream to see what's there */
+EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo,
+ boolean require_image));
+/* Return value is one of: */
+#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */
+#define JPEG_HEADER_OK 1 /* Found valid image datastream */
+#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */
+/* If you pass require_image = TRUE (normal case), you need not check for
+ * a TABLES_ONLY return code; an abbreviated file will cause an error exit.
+ * JPEG_SUSPENDED is only possible if you use a data source module that can
+ * give a suspension return (the stdio source module doesn't).
+ */
+
+/* Main entry points for decompression */
+EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo));
+EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo,
+ JSAMPARRAY scanlines,
+ JDIMENSION max_lines));
+EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo));
+
+/* Replaces jpeg_read_scanlines when reading raw downsampled data. */
+EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo,
+ JSAMPIMAGE data,
+ JDIMENSION max_lines));
+
+/* Additional entry points for buffered-image mode. */
+EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo));
+EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo,
+ int scan_number));
+EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo));
+EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo));
+EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo));
+EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo));
+/* Return value is one of: */
+/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */
+#define JPEG_REACHED_SOS 1 /* Reached start of new scan */
+#define JPEG_REACHED_EOI 2 /* Reached end of image */
+#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */
+#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */
+
+/* Precalculate output dimensions for current decompression parameters. */
+EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo));
+
+/* Control saving of COM and APPn markers into marker_list. */
+EXTERN(void) jpeg_save_markers
+ JPP((j_decompress_ptr cinfo, int marker_code,
+ unsigned int length_limit));
+
+/* Install a special processing method for COM or APPn markers. */
+EXTERN(void) jpeg_set_marker_processor
+ JPP((j_decompress_ptr cinfo, int marker_code,
+ jpeg_marker_parser_method routine));
+
+/* Read or write raw DCT coefficients --- useful for lossless transcoding. */
+EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo));
+EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo,
+ jvirt_barray_ptr * coef_arrays));
+EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo,
+ j_compress_ptr dstinfo));
+
+/* If you choose to abort compression or decompression before completing
+ * jpeg_finish_(de)compress, then you need to clean up to release memory,
+ * temporary files, etc. You can just call jpeg_destroy_(de)compress
+ * if you're done with the JPEG object, but if you want to clean it up and
+ * reuse it, call this:
+ */
+EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo));
+
+/* Generic versions of jpeg_abort and jpeg_destroy that work on either
+ * flavor of JPEG object. These may be more convenient in some places.
+ */
+EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo));
+EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo));
+
+/* Default restart-marker-resync procedure for use by data source modules */
+EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
+ int desired));
+
+
+/* These marker codes are exported since applications and data source modules
+ * are likely to want to use them.
+ */
+
+#define JPEG_RST0 0xD0 /* RST0 marker code */
+#define JPEG_EOI 0xD9 /* EOI marker code */
+#define JPEG_APP0 0xE0 /* APP0 marker code */
+#define JPEG_COM 0xFE /* COM marker code */
+
+
+/* If we have a brain-damaged compiler that emits warnings (or worse, errors)
+ * for structure definitions that are never filled in, keep it quiet by
+ * supplying dummy definitions for the various substructures.
+ */
+
+#ifdef INCOMPLETE_TYPES_BROKEN
+#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */
+struct jvirt_sarray_control { long dummy; };
+struct jvirt_barray_control { long dummy; };
+struct jpeg_comp_master { long dummy; };
+struct jpeg_c_main_controller { long dummy; };
+struct jpeg_c_prep_controller { long dummy; };
+struct jpeg_c_coef_controller { long dummy; };
+struct jpeg_marker_writer { long dummy; };
+struct jpeg_color_converter { long dummy; };
+struct jpeg_downsampler { long dummy; };
+struct jpeg_forward_dct { long dummy; };
+struct jpeg_entropy_encoder { long dummy; };
+struct jpeg_decomp_master { long dummy; };
+struct jpeg_d_main_controller { long dummy; };
+struct jpeg_d_coef_controller { long dummy; };
+struct jpeg_d_post_controller { long dummy; };
+struct jpeg_input_controller { long dummy; };
+struct jpeg_marker_reader { long dummy; };
+struct jpeg_entropy_decoder { long dummy; };
+struct jpeg_inverse_dct { long dummy; };
+struct jpeg_upsampler { long dummy; };
+struct jpeg_color_deconverter { long dummy; };
+struct jpeg_color_quantizer { long dummy; };
+#endif /* JPEG_INTERNALS */
+#endif /* INCOMPLETE_TYPES_BROKEN */
+
+
+/*
+ * The JPEG library modules define JPEG_INTERNALS before including this file.
+ * The internal structure declarations are read only when that is true.
+ * Applications using the library should not include jpegint.h, but may wish
+ * to include jerror.h.
+ */
+
+#ifdef JPEG_INTERNALS
+#include "jpegint.h" /* fetch private declarations */
+#include "jerror.h" /* fetch error codes too */
+#endif
+
+#endif /* JPEGLIB_H */
diff --git a/core/multimedia/opieplayer/libflash/libflash.pro b/core/multimedia/opieplayer/libflash/libflash.pro
new file mode 100644
index 0000000..d144f0b
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/libflash.pro
@@ -0,0 +1,15 @@
+TEMPLATE = lib
+CONFIG += qt warn_on release
+HEADERS = libflashplugin.h libflashpluginimpl.h
+SOURCES = libflashplugin.cpp libflashpluginimpl.cpp \
+ adpcm.cc character.cc flash.cc graphic16.cc matrix.cc script.cc \
+ sprite.cc bitmap.cc cxform.cc font.cc graphic24.cc movie.cc \
+ shape.cc sqrt.cc button.cc displaylist.cc graphic.cc graphic32.cc \
+ program.cc sound.cc text.cc
+TARGET = flashplugin
+DESTDIR = ../../plugins/codecs
+INCLUDEPATH += $(QPEDIR)/include ..
+DEPENDPATH += ../$(QPEDIR)/include ..
+LIBS += -lqpe
+VERSION = 1.0.0
+
diff --git a/core/multimedia/opieplayer/libflash/libflashplugin.cpp b/core/multimedia/opieplayer/libflash/libflashplugin.cpp
new file mode 100644
index 0000000..538c695
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/libflashplugin.cpp
@@ -0,0 +1,223 @@
+/**********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "libflashplugin.h"
+
+#if 0
+
+bool LibFlashPlugin::audioReadSamples( short *output, int channel, long samples, int stream ) {
+}
+
+
+bool LibFlashPlugin::audioReReadSamples( short *output, int channel, long samples, int stream ) {
+}
+
+
+bool LibFlashPlugin::audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ) {
+ samplesRead = samples;
+}
+
+
+bool LibFlashPlugin::audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ) {
+}
+
+
+bool LibFlashPlugin::videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ) {
+}
+
+
+bool LibFlashPlugin::videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream ) {
+/*
+ int format = MPEG3_RGB565;
+ switch ( color_model ) {
+ case RGB565: format = MPEG3_RGB565; break;
+ case RGBA8888: format = MPEG3_RGBA8888; break;
+ case BGRA8888: format = MPEG3_BGRA8888; break;
+ }
+*/
+}
+
+
+bool LibFlashPlugin::videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream ) {
+}
+
+
+FlashHandle file;
+FlashDisplay *fd;
+
+#endif
+
+
+LibFlashPlugin::LibFlashPlugin() {
+ file = NULL;
+ fd = 0;
+}
+#include <stdio.h>
+#include <stdlib.h>
+static int readFile(const char *filename, char **buffer, long *size)
+{
+ FILE *in;
+ char *buf;
+ long length;
+
+ printf("read files\n");
+
+ in = fopen(filename,"r");
+ if (in == 0) {
+ perror(filename);
+ return -1;
+ }
+ fseek(in,0,SEEK_END);
+ length = ftell(in);
+ rewind(in);
+ buf = (char *)malloc(length);
+ fread(buf,length,1,in);
+ fclose(in);
+
+ *size = length;
+ *buffer = buf;
+
+ return length;
+}
+
+static void showUrl(char *url, char * /*target*/, void * /*client_data*/) {
+ printf("get url\n");
+ printf("GetURL : %s\n", url);
+}
+
+static void getSwf(char *url, int level, void *client_data) {
+ FlashHandle flashHandle = (FlashHandle) client_data;
+ char *buffer;
+ long size;
+
+ printf("get swf\n");
+
+ printf("LoadMovie: %s @ %d\n", url, level);
+ if (readFile(url, &buffer, &size) > 0) {
+ FlashParse(flashHandle, level, buffer, size);
+ }
+}
+
+bool LibFlashPlugin::open( const QString& fileName ) {
+
+ printf("opening file\n");
+
+ delete fd;
+ fd = new FlashDisplay;
+ fd->pixels = new int[320*240*4];
+ fd->width = 200;
+ fd->bpl = 320*2;
+ fd->height = 300;
+ fd->depth = 16;
+ fd->bpp = 2;
+ fd->flash_refresh = 25;
+ fd->clip_x = 0;
+ fd->clip_y = 0;
+ fd->clip_width = 0;
+ fd->clip_height = 0;
+
+ char *buffer;
+ long size;
+ int status;
+ struct FlashInfo fi;
+
+ if (readFile(fileName.latin1(), &buffer, &size) < 0)
+ exit(2);
+
+ if (!(file = FlashNew()))
+ exit(1);
+
+ do
+ status = FlashParse(file, 0, buffer, size);
+ while (status & FLASH_PARSE_NEED_DATA);
+
+ free(buffer);
+ FlashGetInfo(file, &fi);
+ //FlashSettings(flashHandle, PLAYER_LOOP);
+ FlashGraphicInit(file, fd);
+ FlashSoundInit(file, "/dev/dsp");
+ FlashSetGetUrlMethod(file, showUrl, 0);
+ FlashSetGetSwfMethod(file, getSwf, (void*)file);
+
+ printf("opened file\n");
+}
+
+// If decoder doesn't support audio then return 0 here
+bool LibFlashPlugin::audioSetSample( long sample, int stream ) { return TRUE; }
+long LibFlashPlugin::audioGetSample( int stream ) { return 0; }
+//bool LibFlashPlugin::audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ) { return TRUE; }
+//bool LibFlashPlugin::audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ) { return FALSE; }
+bool LibFlashPlugin::audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ) { return FALSE; }
+//bool LibFlashPlugin::audioReadSamples( short *output, int channel, long samples, int stream ) { return TRUE; }
+//bool LibFlashPlugin::audioReReadSamples( short *output, int channel, long samples, int stream ) { return TRUE; }
+
+// If decoder doesn't support video then return 0 here
+int LibFlashPlugin::videoStreams() { return 1; }
+int LibFlashPlugin::videoWidth( int stream ) { return 300; }
+int LibFlashPlugin::videoHeight( int stream ) { return 200; }
+double LibFlashPlugin::videoFrameRate( int stream ) { return 25.0; }
+int LibFlashPlugin::videoFrames( int stream ) { return 1000000; }
+bool LibFlashPlugin::videoSetFrame( long frame, int stream ) { return TRUE; }
+long LibFlashPlugin::videoGetFrame( int stream ) { return 0; }
+bool LibFlashPlugin::videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ) { return TRUE; }
+#include <time.h>
+bool LibFlashPlugin::videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream ) {
+ struct timeval wd;
+ FlashEvent fe;
+
+/*
+ delete fd;
+ fd = new FlashDisplay;
+ fd->pixels = output_rows[0];
+ fd->width = 300; // out_w;
+ fd->bpl = 640; // out_w*2;
+ fd->height = 200;//out_h;
+ fd->depth = 16;
+ fd->bpp = 2;
+ fd->flash_refresh = 50;
+ fd->clip_x = 0;//in_x;
+ fd->clip_y = 0;//in_y;
+ fd->clip_width = 300;//in_w;
+ fd->clip_height = 200;//in_h;
+ FlashGraphicInit(file, fd);
+*/
+
+ long cmd = FLASH_WAKEUP;
+ FlashExec(file, cmd, 0, &wd);
+
+ fe.type = FeRefresh;
+ cmd = FLASH_EVENT;
+ FlashExec(file, cmd, &fe, &wd);
+/*
+ for (int i = 0; i < out_h; i++)
+ memcpy( output_rows[i], (char*)fd->pixels + i*fd->bpl, QMIN( fd->width * fd->bpp, out_w * fd->bpp ) );
+*/
+ memcpy( output_rows[0], (char*)fd->pixels, out_w * out_h * 2 );
+}
+
+bool LibFlashPlugin::videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream ) { return TRUE; }
+
+// Profiling
+double LibFlashPlugin::getTime() { return 0.0; }
+
+// Ignore if these aren't supported
+bool LibFlashPlugin::setSMP( int cpus ) { return TRUE; }
+bool LibFlashPlugin::setMMX( bool useMMX ) { return TRUE; }
+
+
diff --git a/core/multimedia/opieplayer/libflash/libflashplugin.h b/core/multimedia/opieplayer/libflash/libflashplugin.h
new file mode 100644
index 0000000..532bca2
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/libflashplugin.h
@@ -0,0 +1,96 @@
+/**********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef LIBFLASH_PLUGIN_H
+#define LIBFLASH_PLUGIN_H
+
+
+#include <qstring.h>
+#include <qapplication.h>
+#include "flash.h"
+#include "mediaplayerplugininterface.h"
+
+
+class LibFlashPlugin : public MediaPlayerDecoder {
+
+public:
+ LibFlashPlugin();
+ ~LibFlashPlugin() { close(); }
+
+ const char *pluginName() { return "LibFlashPlugin: " PLUGIN_NAME " " FLASH_VERSION_STRING; }
+ const char *pluginComment() { return "This is the libflash library: " PLUGIN_NAME " " FLASH_VERSION_STRING; }
+ double pluginVersion() { return 1.0; }
+
+ bool isFileSupported( const QString& fileName ) { return fileName.right(4) == ".swf"; }
+ bool open( const QString& fileName );
+ bool close() { FlashClose( file ); file = NULL; return TRUE; }
+ bool isOpen() { return file != NULL; }
+ const QString &fileInfo() { return strInfo = qApp->translate( "MediaPlayer", "No Information Available", "media plugin text" ); }
+
+ // If decoder doesn't support audio then return 0 here
+ int audioStreams() { return 1; }
+ int audioChannels( int /*stream*/ ) { return 2; }
+ int audioFrequency( int /*stream*/ ) { return 44100; }
+ int audioSamples( int /*stream*/ ) { return 1000000; }
+ bool audioSetSample( long sample, int stream );
+ long audioGetSample( int stream );
+ //bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream );
+ //bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream );
+ bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream );
+ //bool audioReadSamples( short *output, int channel, long samples, int stream );
+ //bool audioReReadSamples( short *output, int channel, long samples, int stream );
+
+ // If decoder doesn't support video then return 0 here
+ int videoStreams();
+ int videoWidth( int stream );
+ int videoHeight( int stream );
+ double videoFrameRate( int stream );
+ int videoFrames( int stream );
+ bool videoSetFrame( long frame, int stream );
+ long videoGetFrame( int stream );
+ bool videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream );
+ bool videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream );
+ bool videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream );
+
+ // Profiling
+ double getTime();
+
+ // Ignore if these aren't supported
+ bool setSMP( int cpus );
+ bool setMMX( bool useMMX );
+
+ // Capabilities
+ bool supportsAudio() { return TRUE; }
+ bool supportsVideo() { return TRUE; }
+ bool supportsYUV() { return TRUE; }
+ bool supportsMMX() { return TRUE; }
+ bool supportsSMP() { return TRUE; }
+ bool supportsStereo() { return TRUE; }
+ bool supportsScaling() { return TRUE; }
+
+private:
+ FlashHandle file;
+ FlashDisplay *fd;
+ QString strInfo;
+
+};
+
+
+#endif
+
diff --git a/core/multimedia/opieplayer/libflash/libflashpluginimpl.cpp b/core/multimedia/opieplayer/libflash/libflashpluginimpl.cpp
new file mode 100644
index 0000000..af2c07e
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/libflashpluginimpl.cpp
@@ -0,0 +1,70 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "libflashplugin.h"
+#include "libflashpluginimpl.h"
+
+
+LibFlashPluginImpl::LibFlashPluginImpl()
+ : libflashplugin(0), ref(0)
+{
+}
+
+
+LibFlashPluginImpl::~LibFlashPluginImpl()
+{
+ if ( libflashplugin )
+ delete libflashplugin;
+}
+
+
+MediaPlayerDecoder *LibFlashPluginImpl::decoder()
+{
+ if ( !libflashplugin )
+ libflashplugin = new LibFlashPlugin;
+ return libflashplugin;
+}
+
+
+MediaPlayerEncoder *LibFlashPluginImpl::encoder()
+{
+ return NULL;
+}
+
+
+#ifndef QT_NO_COMPONENT
+
+
+QRESULT LibFlashPluginImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
+{
+ *iface = 0;
+ if ( ( uuid == IID_QUnknown ) || ( uuid == IID_MediaPlayerPlugin ) )
+ *iface = this, (*iface)->addRef();
+ return QS_OK;
+}
+
+
+Q_EXPORT_INTERFACE()
+{
+ Q_CREATE_INSTANCE( LibFlashPluginImpl )
+}
+
+
+#endif
+
diff --git a/core/multimedia/opieplayer/libflash/libflashpluginimpl.h b/core/multimedia/opieplayer/libflash/libflashpluginimpl.h
new file mode 100644
index 0000000..b5cc869
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/libflashpluginimpl.h
@@ -0,0 +1,53 @@
+/**********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef LIBFLASH_PLUGIN_IMPL_H
+#define LIBFLASH_PLUGIN_IMPL_H
+
+
+#include "../mediaplayerplugininterface.h"
+
+
+class LibFlashPlugin;
+
+
+class LibFlashPluginImpl : public MediaPlayerPluginInterface
+{
+public:
+ LibFlashPluginImpl();
+ virtual ~LibFlashPluginImpl();
+
+#ifndef QT_NO_COMPONENT
+
+ QRESULT queryInterface( const QUuid&, QUnknownInterface** );
+ Q_REFCOUNT
+
+#endif
+
+ virtual MediaPlayerDecoder *decoder();
+ virtual MediaPlayerEncoder *encoder();
+
+private:
+ LibFlashPlugin *libflashplugin;
+ ulong ref;
+};
+
+
+#endif
+
diff --git a/core/multimedia/opieplayer/libflash/matrix.cc b/core/multimedia/opieplayer/libflash/matrix.cc
new file mode 100644
index 0000000..0d8c82c
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/matrix.cc
@@ -0,0 +1,68 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "matrix.h"
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+Matrix::Matrix()
+{
+ a = 1.0;
+ d = 1.0;
+ b = c = 0.0;
+ tx = ty = 0;
+}
+
+Matrix Matrix::operator*(Matrix m)
+{
+ Matrix mat;
+
+ mat.a = this->a * m.a + this->b * m.c;
+ mat.b = this->a * m.b + this->b * m.d;
+ mat.c = this->c * m.a + this->d * m.c;
+ mat.d = this->c * m.b + this->d * m.d;
+
+ mat.tx = this->getX(m.tx,m.ty);
+ mat.ty = this->getY(m.tx,m.ty);
+
+ return mat;
+}
+
+Matrix Matrix::invert()
+{
+ Matrix mat;
+ float det;
+
+ det = a*d-b*c;
+
+ mat.a = d/det;
+ mat.b = -b/det;
+ mat.c = -c/det;
+ mat.d = a/det;
+
+ mat.tx = - (long)(mat.a * tx + mat.b * ty);
+ mat.ty = - (long)(mat.c * tx + mat.d * ty);
+
+ return mat;
+}
diff --git a/core/multimedia/opieplayer/libflash/matrix.h b/core/multimedia/opieplayer/libflash/matrix.h
new file mode 100644
index 0000000..83b54c2
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/matrix.h
@@ -0,0 +1,49 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _MATRIX_H_
+#define _MATRIX_H_
+
+struct Matrix {
+ float a,b,c,d;
+ long tx,ty;
+public:
+ Matrix operator*(Matrix);
+ Matrix invert();
+ Matrix();
+
+#ifdef DUMP
+ void dump(BitStream *bs);
+#endif
+
+ inline
+ long Matrix::getX(long x, long y)
+ {
+ return (long) (x*a+y*b+tx);
+ };
+
+ inline
+ long Matrix::getY(long x, long y)
+ {
+ return (long) (x*c+y*d+ty);
+ };
+
+};
+
+#endif /* _MATRIX_H_ */
diff --git a/core/multimedia/opieplayer/libflash/movie.cc b/core/multimedia/opieplayer/libflash/movie.cc
new file mode 100644
index 0000000..349e43b
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/movie.cc
@@ -0,0 +1,171 @@
+////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+#include "movie.h"
+
+FlashMovie::FlashMovie()
+{
+ gd = NULL;
+ sm = NULL;
+ getSwf = NULL;
+ getUrl = NULL;
+ cursorOnOff = NULL;
+ buttons_updated = 0;
+ scheduledTime.tv_sec = -1;
+ cur_focus = NULL;
+ lost_over = NULL;
+ msPerFrame = 0;
+
+ /* mouse handling */
+ mouse_active = 0;
+ mouse_x = -1;
+ mouse_y = -1;
+ button_pressed = 0;
+ refresh = 1;
+}
+
+FlashMovie::~FlashMovie()
+{
+ CInputScript *n;
+
+ while (main != NULL) {
+ n = main->next;
+ delete main;
+ main = n;
+ }
+
+ if (gd) delete gd;
+ if (sm) delete sm;
+}
+
+int
+FlashMovie::processMovie(GraphicDevice *gd, SoundMixer *sm)
+{
+ CInputScript *script;
+ int wakeUp = 0;
+
+ if (sm && sm->playSounds()) {
+ wakeUp = 1;
+ }
+ for (script = this->main; script != NULL; script = script->next) {
+ if (script->program == NULL) continue;
+ if (script->program->nbFrames == 0) continue;
+ if (script->program->processMovie(gd,sm)) {
+ wakeUp = 1;
+ }
+ }
+ renderMovie();
+ return wakeUp;
+}
+
+int
+FlashMovie::handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *event)
+{
+ int wakeUp = 0;
+
+ if (sm && sm->playSounds()) {
+ wakeUp = 1;
+ }
+ if (this->main == 0) return 0;
+ if (this->main->program == 0) return 0;
+ if (this->main->program->handleEvent(gd, sm, event)) {
+ wakeUp = 1;
+ }
+ renderMovie();
+ return wakeUp;
+}
+
+/* current focus bigger and translated if needed */
+void
+FlashMovie::renderFocus()
+{
+ Rect rect,boundary;
+ Matrix mat;
+
+ if (mouse_active || !cur_focus) return;
+
+ /* rect is the bbox in screen coordinates */
+
+ // Compute the bounding box in screen coordinates
+ cur_focus->character->getBoundingBox(&boundary,cur_focus);
+ mat = (*gd->adjust) * cur_focus->renderMatrix;
+ transformBoundingBox(&rect, &mat, &boundary, 1);
+
+ gd->drawBox(rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+}
+
+void
+FlashMovie::renderMovie()
+{
+ CInputScript *script,*prev,*next;
+ Rect clipping;
+ Matrix identity;
+
+ clipping.reset();
+
+ // First pass to update the clipping region
+ for (script = this->main; script != NULL; script = script->next) {
+ if (script->level == -1) {
+ clipping.xmin = -32768;
+ clipping.ymin = -32768;
+ clipping.xmax = 32767;
+ clipping.ymax = 32767;
+ continue;
+ }
+ if (script->program == NULL) continue;
+ if (script->program->dl->bbox.xmin == LONG_MAX) continue;
+ transformBoundingBox(&clipping, &identity, &script->program->dl->bbox, 0);
+ script->program->render = 0;
+ }
+
+ if (clipping.xmin == LONG_MAX) return;
+
+ // Update the clipping region
+ gd->updateClippingRegion(&clipping);
+ gd->clearCanvas();
+
+ // Second pass to render the movie
+ for (script = this->main; script != NULL; script = script->next) {
+ if (script->level == -1) continue;
+ if (script->program == NULL) continue;
+ script->program->dl->render(gd);
+ }
+ renderFocus();
+
+ // Final pass to delete some movies
+ script = this->main;
+ prev = 0;
+ while (script != NULL) {
+ if (script->level == -1) {
+ next = script->next;
+ if (prev == 0) {
+ this->main = next;
+ } else {
+ prev->next = next;
+ }
+ delete script;
+ script = next;
+ } else {
+ prev = script;
+ script = script->next;
+ }
+ }
+}
diff --git a/core/multimedia/opieplayer/libflash/movie.h b/core/multimedia/opieplayer/libflash/movie.h
new file mode 100644
index 0000000..d83ce79
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/movie.h
@@ -0,0 +1,68 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _MOVIE_H_
+#define _MOVIE_H_
+
+#include "swf.h"
+
+struct FlashMovie {
+ /* true if a button has been moved */
+ int buttons_updated;
+
+ /* current keyboard focus */
+ DisplayListEntry *cur_focus;
+
+ /* mouse state */
+ long mouse_active;
+ long mouse_x;
+ long mouse_y;
+ int button_pressed;
+
+ Button *lost_over;
+
+ /* a button can return to a given state after some time */
+ FlashEvent scheduledEvent;
+ struct timeval scheduledTime;
+
+ int refresh;
+
+ CInputScript *main;
+ long msPerFrame;
+ GraphicDevice *gd;
+ SoundMixer *sm;
+
+ void (*getUrl)(char *,char *, void *);
+ void *getUrlClientData;
+
+ void (*getSwf)(char *url, int level, void *clientData);
+ void *getSwfClientData;
+
+ void (*cursorOnOff)(int , void *);
+ void *cursorOnOffClientData;
+
+ FlashMovie();
+ ~FlashMovie();
+ int processMovie(GraphicDevice *gd, SoundMixer *sm);
+ int handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *event);
+ void renderMovie();
+ void renderFocus();
+};
+
+#endif /* _MOVIE_H_ */
diff --git a/core/multimedia/opieplayer/libflash/program.cc b/core/multimedia/opieplayer/libflash/program.cc
new file mode 100644
index 0000000..c6e8c0f
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/program.cc
@@ -0,0 +1,921 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#define NOTHING 0x0
+#define WAKEUP 0x1
+#define GOTO 0x2
+#define REFRESH 0x4
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+#define PRINT 0
+
+int debug = 0;
+
+Program::Program(FlashMovie *movie, long n)
+{
+ long f;
+
+ this->movie = movie;
+
+ totalFrames = 0;
+
+ dl = new DisplayList(movie);
+ if (dl == NULL) return;
+ frames = new Frame[n];
+ if (frames == NULL) {
+ delete dl;
+ return;
+ }
+
+ nbFrames = 0;
+ totalFrames = n;
+ currentFrame = 0;
+ loadingFrame = 0;
+ movieWait = 1;
+ nextFrame = currentFrame;
+ for(f = 0; f < n; f++)
+ {
+ frames[f].controls = 0;
+ frames[f].label = NULL;
+ }
+
+ movieStatus = MoviePlay;
+ settings = 0;
+}
+
+Program::~Program()
+{
+ int i;
+ Control *ctrl, *ctrl1;
+
+ delete dl;
+
+ if (frames != NULL) {
+ for(i=0;i<nbFrames;i++) {
+ ctrl = frames[i].controls;
+ if (frames[i].label) free(frames[i].label);
+ while (ctrl != NULL) {
+ ctrl1 = ctrl->next;
+ ctrl->next = NULL;
+ delete ctrl;
+ ctrl = ctrl1;
+ }
+ }
+
+ delete[] frames;
+ }
+}
+
+void
+Program::validateLoadingFrame()
+{
+ nbFrames = loadingFrame;
+ loadingFrame++;
+ movieWait = 0;
+}
+
+Frame *
+Program::getFrames()
+{
+ return frames;
+}
+
+long
+Program::getNbFrames()
+{
+ return nbFrames;
+}
+
+DisplayList *
+Program::getDisplayList()
+{
+ return dl;
+}
+
+long
+Program::getCurrentFrame()
+{
+ return currentFrame;
+}
+
+void
+Program::setCurrentFrame(long n)
+{
+ currentFrame = n;
+ nextFrame = n;
+ //refresh = 1;
+}
+
+void
+Program::gotoFrame(GraphicDevice *gd, long frame)
+{
+ long f;
+
+ //printf("GotoFrame %d (Current = %d)\n", frame, currentFrame);
+ dl->clearList();
+
+ for(f=0; f <= frame; f++) {
+ runFrame(gd, 0, f, 0);
+ }
+}
+
+long
+Program::runFrame(GraphicDevice *gd, SoundMixer *sm, long f, long action)
+{
+ Control *ctrl;
+ Character *character;
+ Matrix *matrix;
+ Cxform *cxform;
+ long status = NOTHING;
+ long update = 0;
+ char *name;
+
+#if PRINT&1
+ if (action) printf("Prog %x (dl=%x): Frame N° %d/%d\n", this, this->dl, f, nbFrames-1);
+#endif
+ movie->buttons_updated = 0;
+
+ for(ctrl = frames[f].controls; ctrl; ctrl = ctrl->next)
+ {
+ switch (ctrl->type)
+ {
+ case ctrlPlaceObject:
+ case ctrlPlaceObject2:
+ character = 0;
+ matrix = 0;
+ cxform = 0;
+ name = "";
+ if (ctrl->flags & placeHasCharacter) {
+ character = ctrl->character;
+ }
+ if (ctrl->flags & placeHasMatrix) {
+ matrix = &ctrl->matrix;
+ }
+ if (ctrl->flags & placeHasColorXform) {
+ cxform = &ctrl->cxform;
+ }
+ if (ctrl->flags & placeHasName) {
+ name = ctrl->name;
+ }
+ if (!ctrl->clipDepth) { // Ignore
+ dl->placeObject(gd,character, ctrl->depth, matrix, cxform, name);
+ update = 1;
+ }
+ break;
+ case ctrlRemoveObject:
+ character = ctrl->character;
+
+ if (!character) break; // Should not happen
+
+ dl->removeObject(gd, character, ctrl->depth);
+ if (action) {
+ character->reset();
+ update = 1;
+ }
+ break;
+ case ctrlRemoveObject2:
+ character = dl->removeObject(gd,NULL, ctrl->depth);
+ if (character && action) {
+ character->reset();
+ update = 1;
+ }
+ break;
+ // Actions
+ case ctrlDoAction:
+ if (action) {
+ status = doAction(gd, ctrl->actionRecords, sm);
+ }
+ break;
+ case ctrlStartSound:
+ if (action && sm) {
+ sm->startSound( (Sound *)ctrl->character );
+ }
+ break;
+ case ctrlStopSound:
+ if (action && sm) {
+ sm->stopSounds();
+ }
+ break;
+ case ctrlBackgroundColor:
+ if (action) {
+ if (gd->setBackgroundColor(ctrl->color)) {
+ dl->bbox.xmin = -32768;
+ dl->bbox.ymin = -32768;
+ dl->bbox.xmax = 32768;
+ dl->bbox.ymax = 32768;
+ }
+ }
+ break;
+ }
+ }
+ if (movie->buttons_updated) {
+ dl->updateButtons(movie);
+ }
+
+ if (status & GOTO) {
+ if (nextFrame < nbFrames) {
+ gotoFrame(gd,nextFrame);
+ if (nextFrame != f)
+ if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame);
+ update = 1;
+ }
+ }
+
+#if PRINT&1
+ if (action) printf("Frame N° %d ready\n", f);
+#endif
+ return update;
+}
+
+long
+Program::nestedMovie(GraphicDevice *gd, SoundMixer *sm, Matrix *mat, Cxform *cxform)
+{
+ if (movieStatus == MoviePlay) {
+ // Movie Beeing Played
+ advanceFrame();
+ if (currentFrame == 0) {
+ dl->clearList();
+ }
+ runFrame(gd, sm, currentFrame);
+ if (nbFrames == 1) {
+ pauseMovie();
+ }
+ }
+
+ return (movieStatus == MoviePlay);
+}
+
+long
+Program::processMovie(GraphicDevice *gd, SoundMixer *sm)
+{
+ int wakeUp = 0;
+
+#if PRINT&1
+ printf("Prog %x (dl=%x): Current = %d Next = %d Wait = %d Status = %d\n", this, this->dl, currentFrame, nextFrame, movieWait, movieStatus);
+#endif
+
+ if (movieStatus == MoviePlay && movieWait == 0) {
+ // Movie Beeing Played
+ advanceFrame();
+ if (currentFrame == 0) {
+ dl->clearList();
+ }
+ wakeUp |= runFrame(gd, sm, currentFrame);
+ wakeUp |= dl->updateSprites();
+ if (nextFrame == nbFrames) {
+ if (nbFrames != totalFrames) {
+ movieWait = 1;
+ } else if ((settings & PLAYER_LOOP) == 0) {
+ pauseMovie();
+ }
+ }
+ } else {
+ wakeUp |= dl->updateSprites();
+ }
+
+ if (wakeUp) {
+ render = 1;
+ }
+
+ return (wakeUp || movieStatus == MoviePlay);
+}
+
+/* timer (ms) -1 = delete timer */
+void setFlashTimer(struct timeval *tv, int time_ms)
+{
+ if (time_ms == -1) {
+ tv->tv_sec = -1;
+ } else {
+ gettimeofday(tv,0);
+
+ tv->tv_usec += time_ms*1000;
+ while (tv->tv_usec > 1000000) {
+ tv->tv_usec -= 1000000;
+ tv->tv_sec++;
+ }
+ }
+}
+
+int checkFlashTimer(struct timeval *tv)
+{
+ struct timeval now;
+
+ if (tv->tv_sec == -1) return 0;
+
+ gettimeofday(&now,0);
+ return (now.tv_sec > tv->tv_sec ||
+ (now.tv_sec == tv->tv_sec && now.tv_usec >= tv->tv_usec));
+}
+
+/* bbox */
+typedef struct {
+ long x1,y1,x2,y2;
+} ButtonBoundingBox;
+
+
+static void button_bbox_func(void *id, long y, long start, long end)
+{
+ ButtonBoundingBox *h = (ButtonBoundingBox *) id;
+
+ if (y < h->y1) h->y1 = y;
+ if (y > h->y2) h->y2 = y;
+ if (start < h->x1) h->x1 = start;
+ if (end > h->x2) h->x2 = end;
+}
+
+void computeBBox(FlashMovie *movie, Rect *rect, DisplayListEntry *e)
+{
+ ButtonBoundingBox bb;
+
+ bb.x1 = LONG_MAX;
+ bb.y1 = LONG_MAX;
+ bb.x2 = LONG_MIN;
+ bb.y2 = LONG_MIN;
+
+ e->character->getRegion(movie->gd,&e->renderMatrix,&bb,button_bbox_func);
+
+ rect->xmin = bb.x1 / FRAC;
+ rect->xmax = bb.x2 / FRAC;
+ rect->ymin = bb.y1;
+ rect->ymax = bb.y2;
+}
+
+void transform_coords(long *x_ptr,long *y_ptr, long cx, long cy, long dx, long dy)
+{
+ long x,y,x1,y1;
+ x = *x_ptr;
+ y = *y_ptr;
+
+ x -= cx;
+ y -= cy;
+
+ if (dx < 0) {
+ /* left */
+ x1 = - x;
+ y1 = y;
+ } else if (dy < 0) {
+ /* up */
+ y1 = x;
+ x1 = -y;
+ } else if (dy > 0) {
+ /* down */
+ y1 = x;
+ x1 = y;
+ } else {
+ /* right */
+ x1 = x;
+ y1 = y;
+ }
+
+ *x_ptr = x1;
+ *y_ptr = y1;
+}
+
+typedef struct {
+ FlashMovie *movie;
+ DisplayListEntry *emin,*cur_focus;
+ long dmin;
+ long w,cx,cy,dx,dy;
+} ButtonFocus;
+
+static int button_focus(void *opaque, Program *prg, DisplayListEntry *e)
+{
+ ButtonFocus *h=(ButtonFocus *)opaque;
+ Rect rect;
+ long d,x,y;
+
+ if (e != h->cur_focus) {
+ computeBBox(h->movie,&rect,e);
+ x = (rect.xmin + rect.xmax) / 2;
+ y = (rect.ymin + rect.ymax) / 2;
+
+ /* transform the coords so that the angular sector is directed to the right */
+ transform_coords(&x,&y,h->cx,h->cy,h->dx,h->dy);
+
+ /* inside it ? */
+ if ( x >= 0 &&
+ (y - x - h->w) <= 0 &&
+ (y + x + h->w) >= 0) {
+ d = x*x + y*y;
+
+ if (d < h->dmin) {
+ h->dmin = d;
+ h->emin = e;
+ }
+ }
+ }
+ return 0;
+}
+
+DisplayListEntry *moveFocus(FlashMovie *movie, long dx, long dy,
+ DisplayListEntry *cur_focus)
+{
+ Rect cur_rect;
+ ButtonFocus h;
+
+ h.movie = movie;
+ h.dx = dx;
+ h.dy = dy;
+
+ computeBBox(movie,&cur_rect,cur_focus);
+ /* center */
+ h.cx = (cur_rect.xmin + cur_rect.xmax) / 2;
+ h.cy = (cur_rect.ymin + cur_rect.ymax) / 2;
+
+ /* width/2 of the 45 degrees angular sector */
+ if (dy != 0) {
+ /* for vertical displacement, we have a larger width */
+ h.w = (cur_rect.xmax - cur_rect.xmin) / 2;
+ } else {
+ /* zero width for horizontal displacement */
+ h.w = 0;
+ }
+
+ /* now we select the nearest button in the angular sector */
+ h.dmin = LONG_MAX;
+ h.emin = NULL;
+ h.cur_focus = cur_focus;
+
+ exploreButtons(movie, &h, button_focus);
+
+ return h.emin;
+}
+
+static int button_newfocus(void *opaque, Program *prg, DisplayListEntry *e)
+{
+ * (DisplayListEntry **)opaque = e;
+ return 2;
+}
+
+static int button_nextfocus(void *opaque, Program *prg, DisplayListEntry *e)
+{
+ static int found = 0;
+ DisplayListEntry **focus;
+
+ focus = (DisplayListEntry **)opaque;
+ if (found) {
+ *focus = e;
+ found = 0;
+ return 2;
+ }
+ if (e == *focus) {
+ found = 1;
+ }
+ return 0;
+}
+
+
+/* XXX: should not be here (one level upper) */
+long
+Program::handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *fe)
+{
+ ActionRecord *action;
+ Program *prog;
+ long status = 0;
+ DisplayListEntry *cur_focus, *new_focus;
+ long dx,dy;
+ int refresh;
+
+ refresh = 0;
+
+ switch(fe->type) {
+
+ case FeKeyRelease:
+ if (movie->mouse_active == 0) {
+
+ if (movie->cur_focus) {
+ movie->cur_focus->owner->updateBoundingBox(movie->cur_focus);
+ movie->cur_focus->renderState = stateOver;
+ movie->cur_focus->owner->updateBoundingBox(movie->cur_focus);
+ }
+ }
+ break;
+
+ case FeKeyPress:
+
+ movie->mouse_active = 0;
+
+ /* find the button which has the focus */
+ cur_focus = movie->cur_focus;
+
+ if (fe->key == FeKeyEnter) {
+ /* selection */
+ if (cur_focus) {
+ /* select the button */
+ cur_focus->owner->updateBoundingBox(cur_focus);
+ cur_focus->renderState = stateDown;
+ ((Button *)cur_focus->character)->updateButtonState(cur_focus);
+ cur_focus->owner->updateBoundingBox(cur_focus);
+
+ movie->scheduledEvent.type = FeKeyRelease;
+ movie->scheduledEvent.key = FeKeyEnter;
+
+ setFlashTimer(&movie->scheduledTime, 250); /* 250 ms down */
+ }
+ } else {
+ /* displacement */
+
+ if (cur_focus == NULL) {
+ /* no current focus : set one */
+ exploreButtons(movie, &cur_focus, button_newfocus);
+ if (cur_focus) {
+ cur_focus->renderState = stateOver;
+ ((Button *)cur_focus->character)->updateButtonState(cur_focus);
+ cur_focus->owner->updateBoundingBox(cur_focus);
+ }
+ movie->cur_focus = cur_focus;
+ } else {
+ /* move the focus (test) */
+ switch(fe->key) {
+ case FeKeyNext:
+ /* Next available */
+ cur_focus->owner->updateBoundingBox(cur_focus);
+ cur_focus->renderState = stateUp;
+ ((Button *)cur_focus->character)->updateButtonState(cur_focus);
+ cur_focus->owner->updateBoundingBox(cur_focus);
+ exploreButtons(movie, &cur_focus, button_nextfocus);
+ if (cur_focus) {
+ cur_focus->renderState = stateOver;
+ ((Button *)cur_focus->character)->updateButtonState(cur_focus);
+ cur_focus->owner->updateBoundingBox(cur_focus);
+ }
+ movie->cur_focus = cur_focus;
+ dx = 0;
+ dy = 0;
+ break;
+ case FeKeyUp:
+ dx = 0;
+ dy = -1;
+ break;
+ case FeKeyDown:
+ dx = 0;
+ dy = 1;
+ break;
+ case FeKeyLeft:
+ dx = -1;
+ dy = 0;
+ break;
+ case FeKeyRight:
+ dx = 1;
+ dy = 0;
+ break;
+ default:
+ /* should not happen */
+ dx = 0;
+ dy = 0;
+ break;
+ }
+
+ if (dx != 0 || dy != 0) {
+
+ new_focus = moveFocus(movie, dx, dy, cur_focus);
+ if (new_focus) {
+ cur_focus->owner->updateBoundingBox(cur_focus);
+ cur_focus->renderState = stateUp;
+ ((Button *)cur_focus->character)->updateButtonState(cur_focus);
+ cur_focus->owner->updateBoundingBox(cur_focus);
+
+ if (computeActions(movie, &prog, &action)) {
+ status |= prog->doAction(gd, action, sm);
+ }
+
+ new_focus->renderState = stateOver;
+ ((Button *)new_focus->character)->updateButtonState(new_focus);
+ movie->cur_focus = new_focus;
+ new_focus->owner->updateBoundingBox(new_focus);
+ } else {
+ return 0;
+ }
+ }
+ }
+ if (movie->cur_focus == NULL) return 0;
+ }
+ break;
+
+ case FeMouseMove:
+ movie->mouse_active = 1;
+ movie->mouse_x = fe->x * FRAC;
+ movie->mouse_y = fe->y * FRAC;
+ dl->updateButtons(movie);
+ break;
+
+ case FeButtonPress:
+ movie->mouse_active = 1;
+ movie->button_pressed = 1;
+ dl->updateButtons(movie);
+ break;
+
+ case FeButtonRelease:
+ movie->mouse_active = 1;
+ movie->button_pressed = 0;
+ dl->updateButtons(movie);
+ break;
+
+ default:
+ return 0;
+ }
+
+ if (computeActions(movie, &prog, &action)) {
+ status |= prog->doAction(gd, action, sm);
+ }
+
+ if (status & REFRESH) {
+ status |= WAKEUP;
+ refresh = 1;
+ }
+ if (status & GOTO) {
+ if (nextFrame < nbFrames) {
+ gotoFrame(gd, nextFrame);
+ if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame);
+ refresh = 1;
+ }
+ }
+
+ if (refresh) {
+ dl->updateSprites();
+ render = 1;
+ }
+ return (refresh || movieStatus == MoviePlay);
+}
+
+long
+Program::doAction(GraphicDevice *gd, ActionRecord *action, SoundMixer *sm)
+{
+ long status = NOTHING;
+ long f;
+ char *target = "";
+ long skip = 0;
+
+ while(action)
+ {
+ if (skip) skip--;
+ else
+ switch (action->action)
+ {
+ case ActionPlaySound:
+#if PRINT&2
+ printf("Prog %x : PlaySound\n", this);
+#endif
+ if (sm) {
+ sm->startSound(action->sound);
+ }
+ status |= WAKEUP;
+ break;
+ case ActionRefresh:
+#if PRINT&2
+ printf("Prog %x : Refresh\n", this);
+#endif
+ status |= REFRESH;
+ break;
+ case ActionGotoFrame:
+#if PRINT&2
+ printf("Prog %x : GotoFrame %d\n", this, action->frameIndex);
+#endif
+ if (target[0] == 0) {
+ if (action->frameIndex < nbFrames) {
+ currentFrame = action->frameIndex;
+ pauseMovie();
+ status |= WAKEUP|GOTO;
+ }
+ }
+ break;
+ case ActionGetURL:
+#if PRINT&2
+ printf("Prog %x : GetURL %s target = %s\n", this, action->url, action->target);
+#endif
+ {
+ int len,level;
+ len = strlen(action->target);
+
+ if (len > 6 && memcmp(action->target,"_level", 6) == 0) {
+ level = atoi(action->target + 6);
+ loadNewSwf(movie, action->url, level);
+ } else {
+ if (movie->getUrl) {
+ movie->getUrl(action->url, action->target, movie->getUrlClientData);
+ }
+ }
+ }
+ break;
+ case ActionNextFrame:
+ nextFrame = currentFrame+1;
+ movieStatus = MoviePlay;
+ status |= WAKEUP;
+ break;
+ case ActionPrevFrame:
+ nextFrame = currentFrame-1;
+ status |= WAKEUP|GOTO;
+ break;
+ case ActionPlay:
+#if PRINT&2
+ printf("Prog %x : Play\n", this);
+#endif
+ if (target[0] == 0) {
+ movieStatus = MoviePlay;
+ if ((status & GOTO) == 0) {
+ if (currentFrame == nextFrame) advanceFrame();
+ }
+ status |= WAKEUP;
+ }
+ break;
+ case ActionStop:
+#if PRINT&2
+ printf("Prog %x : Stop\n", this);
+#endif
+ if (target[0] == 0) {
+ movieStatus = MoviePaused;
+ nextFrame = currentFrame;
+ }
+ break;
+ case ActionToggleQuality:
+ break;
+ case ActionStopSounds:
+ if (sm) {
+ sm->stopSounds();
+ }
+ break;
+ case ActionWaitForFrame:
+ if (action->frameIndex >= nbFrames) {
+ skip = action->skipCount;
+ }
+ break;
+ case ActionSetTarget:
+#if PRINT&2
+ printf("Prog %x : SetTarget '%s'\n", this, action->target);
+#endif
+ target = action->target;
+ break;
+ case ActionGoToLabel:
+#if PRINT&2
+ printf("Prog %x : GotoFrame '%s'\n", this, action->frameLabel);
+#endif
+ f = searchFrame(gd, action->frameLabel, target);
+ if (f >= 0) {
+ currentFrame = f;
+ pauseMovie();
+ status |= WAKEUP|GOTO;
+ } else {
+ status |= REFRESH;
+ }
+ break;
+ }
+ action = action->next;
+ }
+ return status;
+}
+
+void
+Program::setCurrentFrameLabel(char *label)
+{
+ frames[loadingFrame].label = label;
+}
+
+void
+Program::rewindMovie()
+{
+ currentFrame = 0;
+ nextFrame = 0;
+}
+
+void
+Program::pauseMovie()
+{
+ movieStatus = MoviePaused;
+ nextFrame = currentFrame;
+}
+
+void
+Program::continueMovie()
+{
+ movieStatus = MoviePlay;
+}
+
+void
+Program::nextStepMovie()
+{
+ if (movieStatus == MoviePaused) {
+ advanceFrame();
+ }
+}
+
+void
+Program::advanceFrame()
+{
+ currentFrame = nextFrame;
+ nextFrame = currentFrame+1;
+ if (currentFrame == nbFrames) {
+ currentFrame = 0;
+ nextFrame = 0;
+ movieStatus = MoviePlay;
+ }
+}
+
+void
+Program::addControlInCurrentFrame(Control *ctrl)
+{
+ Control *c;
+
+ ctrl->next = 0;
+ if (frames[loadingFrame].controls == 0) {
+ frames[loadingFrame].controls = ctrl;
+ } else {
+ for(c = frames[loadingFrame].controls; c->next; c = c->next);
+ c->next = ctrl;
+ }
+}
+
+void
+Program::modifySettings(long flags)
+{
+ settings = flags;
+}
+
+long
+Program::searchFrame(GraphicDevice *gd, char *label, char *target)
+{
+ long f;
+ DisplayListEntry *e;
+ Program *prg;
+
+ // Current movie
+ if (target[0] == 0) {
+ for(f=0; f < nbFrames; f++)
+ {
+ if (frames[f].label && !strcmp(label,frames[f].label)) {
+ return f;
+ }
+ }
+ }
+
+ // Kludge !!!
+ for (e = dl->list; e; e = e->next) {
+ if (e->character->isSprite()) {
+ prg = ((Sprite *)e->character)->program;
+ f = prg->searchFrame(gd,label,"");
+ if (f >= 0 && f < prg->nbFrames) {
+ prg->dl->updateBoundingBox(e);
+ prg->gotoFrame(gd, f);
+ prg->nextFrame = f;
+ prg->dl->updateBoundingBox(e);
+ return -1;
+ }
+ }
+ }
+
+ return -1;
+}
+
+void loadNewSwf(FlashMovie *movie, char *url, int level)
+{
+ CInputScript *s,*prev,**l;
+
+ if (movie->getSwf == NULL) return;
+
+ for(s = movie->main, prev = 0; s != NULL; prev = s, s = s->next) {
+ if (s->level == level) {
+ // Mark movie to be deleted
+ s->level = -1;
+ break;
+ }
+ }
+
+ //printf("Unload movie @ %d\n", level);
+
+ if (*url == 0) return; // Just UnloadMovie
+
+ s = new CInputScript(level);
+ if (s == NULL) return;
+
+ /* insert it in the right order */
+ l = &movie->main;
+ while (*l != NULL && (*l)->level < level) l = &(*l)->next;
+ s->next = *l;
+ *l = s;
+
+ // Notify the external loader of a new movie to load
+ movie->getSwf(url, level, movie->getSwfClientData);
+}
diff --git a/core/multimedia/opieplayer/libflash/program.h b/core/multimedia/opieplayer/libflash/program.h
new file mode 100644
index 0000000..7672d88
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/program.h
@@ -0,0 +1,185 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _PROGRAM_H_
+#define _PROGRAM_H_
+
+enum ControlType {
+ ctrlPlaceObject,
+ ctrlPlaceObject2,
+ ctrlRemoveObject,
+ ctrlRemoveObject2,
+ ctrlDoAction,
+ ctrlStartSound,
+ ctrlStopSound,
+ ctrlBackgroundColor
+};
+
+enum PlaceFlags {
+ placeIsMove = 0x01,
+ placeHasCharacter = 0x02,
+ placeHasMatrix = 0x04,
+ placeHasColorXform = 0x08,
+ placeHasRatio = 0x10,
+ placeHasName = 0x20,
+ placeHasClip = 0x40
+};
+
+struct Control {
+ ControlType type;
+
+ // Place, Remove, Sound
+ Character *character;
+ long depth;
+
+ // Place 1&2
+ PlaceFlags flags;
+ Matrix matrix;
+ Cxform cxform;
+ long ratio;
+ long clipDepth;
+ char *name;
+
+ // BackgroundColor
+ Color color;
+
+ // DoAction
+ ActionRecord *actionRecords;
+
+ struct Control *next;
+
+
+ // Methods
+
+ void addActionRecord( ActionRecord *ar)
+ {
+ ar->next = 0;
+
+ if (actionRecords == 0) {
+ actionRecords = ar;
+ } else {
+ ActionRecord *current;
+
+ for(current = actionRecords; current->next; current = current->next);
+
+ current->next = ar;
+ }
+ };
+
+ Control()
+ {
+ actionRecords = 0;
+ cxform.aa = 1.0; cxform.ab = 0;
+ cxform.ra = 1.0; cxform.rb = 0;
+ cxform.ga = 1.0; cxform.gb = 0;
+ cxform.ba = 1.0; cxform.bb = 0;
+ ratio = 0;
+ clipDepth = 0;
+ name = 0;
+ };
+
+ ~Control()
+ {
+ ActionRecord *ar,*del;
+ for(ar = actionRecords; ar;)
+ {
+ del = ar;
+ ar = ar->next;
+ delete del;
+ }
+ if (name) {
+ free(name);
+ }
+ };
+};
+
+struct Frame {
+ char *label;
+ Control *controls; // Controls for this frame
+};
+
+enum MovieStatus {
+ MoviePaused,
+ MoviePlay
+};
+
+struct FlashMovie;
+
+struct Program {
+ DisplayList *dl;
+
+ Frame *frames; // Array
+ long nbFrames; // Number of valid frames
+ long currentFrame;
+ long loadingFrame;
+ long totalFrames; // Total expected number of frames
+ long nextFrame;
+ int movieWait; // If true freeze movie until next loaded frame
+ MovieStatus movieStatus;
+ Sound *currentSound;
+ long settings;
+ FlashMovie *movie;
+ long render; // True if needed to be rendered
+
+ Program(FlashMovie *movie,long n);
+ ~Program();
+
+ void rewindMovie();
+ void pauseMovie();
+ void continueMovie();
+ void nextStepMovie();
+ void gotoFrame(GraphicDevice *gd, long f);
+
+ long processMovie(GraphicDevice *, SoundMixer *);
+ long nestedMovie(GraphicDevice *, SoundMixer *, Matrix *, Cxform *);
+ long runFrame(GraphicDevice *, SoundMixer *, long f, long action=1);
+ long handleEvent(GraphicDevice *, SoundMixer *, FlashEvent *);
+ long doAction(GraphicDevice *gd, ActionRecord *action, SoundMixer *);
+ void setCurrentFrameLabel(char *label);
+ void advanceFrame();
+ void addControlInCurrentFrame(Control *ctrl);
+ void setGetUrlMethod( void (*)(char *, char *, void *), void *);
+ void modifySettings(long flags);
+ long searchFrame(GraphicDevice *gd, char *, char *);
+ void validateLoadingFrame();
+ long getCurrentFrame();
+ void setCurrentFrame(long);
+
+ Frame *getFrames();
+ long getNbFrames();
+
+ DisplayList *getDisplayList();
+
+#ifdef DUMP
+ void dump(BitStream *bs);
+static void dumpActions(BitStream *bs, ActionRecord *actions);
+#endif
+};
+
+DisplayListEntry *findFocus(DisplayList *dl);
+void setFlashTimer(struct timeval *tv, int time_ms);
+int checkFlashTimer(struct timeval *tv);
+
+void loadNewSwf(FlashMovie *movie, char *url, int level);
+
+void computeBBox(FlashMovie *movie, Rect *rect, DisplayListEntry *e);
+
+long processMovie(FlashMovie *movie);
+
+#endif /* _PROGRAM_H_ */
diff --git a/core/multimedia/opieplayer/libflash/rect.h b/core/multimedia/opieplayer/libflash/rect.h
new file mode 100644
index 0000000..cb84eb3
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/rect.h
@@ -0,0 +1,55 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _RECT_H_
+#define _RECT_H_
+
+struct Rect
+{
+ long xmin;
+ long xmax;
+ long ymin;
+ long ymax;
+
+ long getWidth() {
+ return xmax-xmin;
+ };
+
+ long getHeight() {
+ return ymax-ymin;
+ };
+
+ void print() {
+ printf("Xmin = %d Xmax = %d Ymin = %d Ymax = %d\n",
+ (int)xmin,(int)xmax,(int)ymin,(int)ymax);
+ };
+
+ void reset() {
+ xmin = LONG_MAX;
+ ymin = LONG_MAX;
+ xmax = LONG_MIN;
+ ymax = LONG_MIN;
+ };
+
+#ifdef DUMP
+ void dump(BitStream *bs);
+#endif
+};
+
+#endif /* _RECT_H_ */
diff --git a/core/multimedia/opieplayer/libflash/script.cc b/core/multimedia/opieplayer/libflash/script.cc
new file mode 100644
index 0000000..db65819
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/script.cc
@@ -0,0 +1,1988 @@
+#include "swf.h"
+
+////////////////////////////////////////////////////////////
+// This file is derived from the 'buggy' SWF parser provided
+// by Macromedia.
+//
+// Modifications : Olivier Debon <odebon@club-internet.fr>
+//
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+#define printf(fmt,args...)
+
+//////////////////////////////////////////////////////////////////////
+// Inline input script object methods.
+//////////////////////////////////////////////////////////////////////
+
+//
+// Inlines to parse a Flash file.
+//
+inline U8 CInputScript::GetByte(void)
+{
+ return m_fileBuf[m_filePos++];
+}
+
+inline U16 CInputScript::GetWord(void)
+{
+ U8 * s = m_fileBuf + m_filePos;
+ m_filePos += 2;
+ return (U16) s[0] | ((U16) s[1] << 8);
+}
+
+inline U32 CInputScript::GetDWord(void)
+{
+ U8 * s = m_fileBuf + m_filePos;
+ m_filePos += 4;
+ return (U32) s[0] | ((U32) s[1] << 8) | ((U32) s[2] << 16) | ((U32) s [3] << 24);
+}
+
+
+
+
+//////////////////////////////////////////////////////////////////////
+// Input script object methods.
+//////////////////////////////////////////////////////////////////////
+
+CInputScript::CInputScript(int level)
+// Class constructor.
+{
+ this->level = level;
+
+ // Initialize the input pointer.
+ m_fileBuf = NULL;
+
+ // Initialize the file information.
+ m_filePos = 0;
+ m_fileSize = 0;
+ m_fileVersion = 0;
+
+ // Initialize the bit position and buffer.
+ m_bitPos = 0;
+ m_bitBuf = 0;
+
+ // Initialize the output file.
+ m_outputFile = NULL;
+
+ // Set to true if we wish to dump all contents long form
+ m_dumpAll = false;
+
+ // if set to true will dump image guts (i.e. jpeg, zlib, etc. data)
+ m_dumpGuts = false;
+
+ needHeader = 1;
+ program = 0;
+
+ outOfMemory = 0;
+
+ next = NULL;
+
+ return;
+}
+
+
+CInputScript::~CInputScript(void)
+// Class destructor.
+{
+ // Free the buffer if it is there.
+ if (m_fileBuf)
+ {
+ delete program;
+ m_fileBuf = NULL;
+ m_fileSize = 0;
+ }
+}
+
+
+U16 CInputScript::GetTag(void)
+{
+ // Save the start of the tag.
+ m_tagStart = m_filePos;
+
+ if (m_actualSize-m_filePos < 2) return notEnoughData;
+
+ // Get the combined code and length of the tag.
+ U16 code = GetWord();
+
+ // The length is encoded in the tag.
+ U32 len = code & 0x3f;
+
+ // Remove the length from the code.
+ code = code >> 6;
+
+ // Determine if another long word must be read to get the length.
+ if (len == 0x3f) {
+ if (m_actualSize-m_filePos < 4) return notEnoughData;
+ len = (U32) GetDWord();
+ }
+
+ // Determine the end position of the tag.
+ m_tagEnd = m_filePos + (U32) len;
+ m_tagLen = (U32) len;
+
+ return code;
+}
+
+
+void CInputScript::GetRect (Rect * r)
+{
+ InitBits();
+ int nBits = (int) GetBits(5);
+ r->xmin = GetSBits(nBits);
+ r->xmax = GetSBits(nBits);
+ r->ymin = GetSBits(nBits);
+ r->ymax = GetSBits(nBits);
+}
+
+void CInputScript::GetMatrix(Matrix* mat)
+{
+ InitBits();
+
+ // Scale terms
+ if (GetBits(1))
+ {
+ int nBits = (int) GetBits(5);
+ mat->a = (float)(GetSBits(nBits))/(float)0x10000;
+ mat->d = (float)(GetSBits(nBits))/(float)0x10000;
+ }
+ else
+ {
+ mat->a = mat->d = 1.0;
+ }
+
+ // Rotate/skew terms
+ if (GetBits(1))
+ {
+ int nBits = (int)GetBits(5);
+ mat->c = (float)(GetSBits(nBits))/(float)0x10000;
+ mat->b = (float)(GetSBits(nBits))/(float)0x10000;
+ }
+ else
+ {
+ mat->b = mat->c = 0.0;
+ }
+
+ // Translate terms
+ int nBits = (int) GetBits(5);
+ mat->tx = GetSBits(nBits);
+ mat->ty = GetSBits(nBits);
+}
+
+
+void CInputScript::GetCxform(Cxform* cx, BOOL hasAlpha)
+{
+ int flags;
+ int nBits;
+ float aa; long ab;
+ float ra; long rb;
+ float ga; long gb;
+ float ba; long bb;
+
+ InitBits();
+
+ flags = (int) GetBits(2);
+ nBits = (int) GetBits(4);
+ aa = 1.0; ab = 0;
+ if (flags & 1)
+ {
+ ra = (float) GetSBits(nBits)/256.0;
+ ga = (float) GetSBits(nBits)/256.0;
+ ba = (float) GetSBits(nBits)/256.0;
+ if (hasAlpha) aa = (float) GetSBits(nBits)/256.0;
+ }
+ else
+ {
+ ra = ga = ba = 1.0;
+ }
+ if (flags & 2)
+ {
+ rb = (S32) GetSBits(nBits);
+ gb = (S32) GetSBits(nBits);
+ bb = (S32) GetSBits(nBits);
+ if (hasAlpha) ab = (S32) GetSBits(nBits);
+ }
+ else
+ {
+ rb = gb = bb = 0;
+ }
+ if (cx) {
+ cx->aa = aa;
+ cx->ab = ab;
+ cx->ra = ra;
+ cx->rb = rb;
+ cx->ga = ga;
+ cx->gb = gb;
+ cx->ba = ba;
+ cx->bb = bb;
+ }
+}
+
+
+/* XXX: should allocate string */
+char *CInputScript::GetString(void)
+{
+ // Point to the string.
+ char *str = (char *) &m_fileBuf[m_filePos];
+
+ // Skip over the string.
+ while (GetByte());
+
+ return str;
+}
+
+void CInputScript::InitBits(void)
+{
+ // Reset the bit position and buffer.
+ m_bitPos = 0;
+ m_bitBuf = 0;
+}
+
+
+S32 CInputScript::GetSBits (S32 n)
+// Get n bits from the string with sign extension.
+{
+ // Get the number as an unsigned value.
+ S32 v = (S32) GetBits(n);
+
+ // Is the number negative?
+ if (v & (1L << (n - 1)))
+ {
+ // Yes. Extend the sign.
+ v |= -1L << n;
+ }
+
+ return v;
+}
+
+
+U32 CInputScript::GetBits (S32 n)
+// Get n bits from the stream.
+{
+ U32 v = 0;
+
+ for (;;)
+ {
+ S32 s = n - m_bitPos;
+ if (s > 0)
+ {
+ // Consume the entire buffer
+ v |= m_bitBuf << s;
+ n -= m_bitPos;
+
+ // Get the next buffer
+ m_bitBuf = GetByte();
+ m_bitPos = 8;
+ }
+ else
+ {
+ // Consume a portion of the buffer
+ v |= m_bitBuf >> -s;
+ m_bitPos -= n;
+ m_bitBuf &= 0xff >> (8 - m_bitPos); // mask off the consumed bits
+ return v;
+ }
+ }
+}
+
+void CInputScript::ParseFreeCharacter()
+{
+ U32 tagid = (U32) GetWord();
+
+ tagid = tagid;
+
+ printf("tagFreeCharacter \ttagid %-5u\n", tagid);
+}
+
+
+void CInputScript::ParsePlaceObject()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlPlaceObject;
+ ctrl->flags = (PlaceFlags)(placeHasMatrix | placeHasCharacter);
+
+ ctrl->character = getCharacter(GetWord());
+ ctrl->depth = GetWord();
+
+ GetMatrix(&(ctrl->matrix));
+
+ if ( m_filePos < m_tagEnd )
+ {
+ ctrl->flags = (PlaceFlags)(ctrl->flags | placeHasColorXform);
+
+ GetCxform(&ctrl->cxform, false);
+ }
+
+ program->addControlInCurrentFrame(ctrl);
+}
+
+
+void CInputScript::ParsePlaceObject2()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlPlaceObject2;
+
+ ctrl->flags = (PlaceFlags)GetByte();
+ ctrl->depth = GetWord();
+
+ // Get the tag if specified.
+ if (ctrl->flags & placeHasCharacter)
+ {
+ ctrl->character = getCharacter(GetWord());
+ }
+
+ // Get the matrix if specified.
+ if (ctrl->flags & placeHasMatrix)
+ {
+ GetMatrix(&(ctrl->matrix));
+ }
+
+ // Get the color transform if specified.
+ if (ctrl->flags & placeHasColorXform)
+ {
+ GetCxform(&ctrl->cxform, true);
+ }
+
+ // Get the ratio if specified.
+ if (ctrl->flags & placeHasRatio)
+ {
+ ctrl->ratio = GetWord();
+ }
+
+ // Get the ratio if specified.
+ if (ctrl->flags & placeHasName)
+ {
+ ctrl->name = strdup(GetString());
+ }
+
+ // Get the clipdepth if specified.
+ if (ctrl->flags & placeHasClip)
+ {
+ ctrl->clipDepth = GetWord();
+ }
+
+ program->addControlInCurrentFrame(ctrl);
+}
+
+
+void CInputScript::ParseRemoveObject()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlRemoveObject;
+ ctrl->character = getCharacter(GetWord());
+ ctrl->depth = GetWord();
+
+ program->addControlInCurrentFrame(ctrl);
+}
+
+
+void CInputScript::ParseRemoveObject2()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlRemoveObject2;
+ ctrl->depth = GetWord();
+
+ program->addControlInCurrentFrame(ctrl);
+}
+
+
+void CInputScript::ParseSetBackgroundColor()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlBackgroundColor;
+ ctrl->color.red = GetByte();
+ ctrl->color.green = GetByte();
+ ctrl->color.blue = GetByte();
+
+ program->addControlInCurrentFrame(ctrl);
+}
+
+
+void CInputScript::ParseDoAction()
+{
+ Control *ctrl;
+ ActionRecord *ar;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlDoAction;
+
+ do {
+ ar = ParseActionRecord();
+ if (ar) {
+ ctrl->addActionRecord( ar );
+ }
+ if (outOfMemory) {
+ return;
+ }
+ } while (ar);
+
+ program->addControlInCurrentFrame(ctrl);
+
+}
+
+
+void CInputScript::ParseStartSound()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->character = getCharacter(GetWord());
+ ctrl->type = ctrlStartSound;
+
+ program->addControlInCurrentFrame(ctrl);
+
+ if (!m_dumpAll)
+ return;
+
+ U32 code = GetByte();
+
+ printf("code %-3u", code);
+
+ if ( code & soundHasInPoint )
+ printf(" inpoint %u ", GetDWord());
+ if ( code & soundHasOutPoint )
+ printf(" oupoint %u", GetDWord());
+ if ( code & soundHasLoops )
+ printf(" loops %u", GetWord());
+
+ printf("\n");
+ if ( code & soundHasEnvelope )
+ {
+ int points = GetByte();
+
+ for ( int i = 0; i < points; i++ )
+ {
+ printf("\n");
+ printf("mark44 %u", GetDWord());
+ printf(" left chanel %u", GetWord());
+ printf(" right chanel %u", GetWord());
+ printf("\n");
+ }
+ }
+}
+
+
+void CInputScript::ParseStopSound()
+{
+ Control *ctrl;
+
+ ctrl = new Control;
+ if (ctrl == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ ctrl->type = ctrlStopSound;
+
+ program->addControlInCurrentFrame(ctrl);
+}
+
+
+void CInputScript::ParseShapeData(int getAlpha, int getStyles)
+{
+ int shapeRecord = 0;
+
+ if (getStyles) {
+ // ShapeWithStyle
+ ParseFillStyle(getAlpha);
+ ParseLineStyle(getAlpha);
+ }
+
+ InitBits();
+ m_nFillBits = (U16) GetBits(4);
+ m_nLineBits = (U16) GetBits(4);
+
+ do {
+ shapeRecord = ParseShapeRecord(getAlpha);
+ } while (shapeRecord);
+}
+
+int
+CInputScript::ParseShapeRecord(long getAlpha)
+{
+ // Determine if this is an edge.
+ BOOL isEdge = (BOOL) GetBits(1);
+
+ if (!isEdge)
+ {
+ // Handle a state change
+ U16 flags = (U16) GetBits(5);
+
+ // Are we at the end?
+ if (flags == 0)
+ {
+ // End of shape
+ return 0;
+ }
+
+ // Process a move to.
+ if (flags & flagsMoveTo)
+ {
+ U16 nBits = (U16) GetBits(5);
+ GetSBits(nBits);
+ GetSBits(nBits);
+ }
+
+ // Get new fill info.
+ if (flags & flagsFill0)
+ {
+ GetBits(m_nFillBits);
+ }
+ if (flags & flagsFill1)
+ {
+ GetBits(m_nFillBits);
+ }
+
+ // Get new line info
+ if (flags & flagsLine)
+ {
+ GetBits(m_nLineBits);
+ }
+
+ // Check to get a new set of styles for a new shape layer.
+ if (flags & flagsNewStyles)
+ {
+ // Parse the style.
+ ParseFillStyle(getAlpha);
+ ParseLineStyle(getAlpha);
+
+ InitBits(); // Bug !
+
+ // Reset.
+ m_nFillBits = (U16) GetBits(4);
+ m_nLineBits = (U16) GetBits(4);
+ }
+
+ return flags & flagsEndShape ? 0 : 1;
+ }
+ else
+ {
+ if (GetBits(1))
+ {
+ // Handle a line
+ U16 nBits = (U16) GetBits(4) + 2; // nBits is biased by 2
+
+ // Save the deltas
+ if (GetBits(1))
+ {
+ // Handle a general line.
+ GetSBits(nBits);
+ GetSBits(nBits);
+ }
+ else
+ {
+ // Handle a vert or horiz line.
+ GetBits(1);
+ GetSBits(nBits);
+ }
+ }
+ else
+ {
+ // Handle a curve
+ U16 nBits = (U16) GetBits(4) + 2; // nBits is biased by 2
+
+ // Get the control
+ GetSBits(nBits);
+ GetSBits(nBits);
+
+ // Get the anchor
+ GetSBits(nBits);
+ GetSBits(nBits);
+ }
+
+ return 1;
+ }
+}
+
+
+void CInputScript::ParseFillStyle(long getAlpha)
+ //
+{
+ U16 i = 0;
+ FillType type;
+ Matrix matrix;
+
+ // Get the number of fills.
+ U16 nFills = GetByte();
+
+ // Do we have a larger number?
+ if (nFills == 255)
+ {
+ // Get the larger number.
+ nFills = GetWord();
+ }
+
+ // Get each of the fill style.
+ for (i = 0; i < nFills; i++)
+ {
+ U16 fillStyle = GetByte();
+
+ type = (FillType) fillStyle;
+
+ printf("fillstyle: type=%d\n",defs[i].type);
+ if (fillStyle & 0x10)
+ {
+ U16 nbGradients;
+
+ type = (FillType) (fillStyle & 0x12);
+
+ // Get the gradient matrix.
+ GetMatrix(&matrix);
+
+ // Get the number of colors.
+ nbGradients = GetByte();
+
+ // Get each of the colors.
+ for (U16 j = 0; j < nbGradients; j++)
+ {
+ GetByte();
+ GetByte();
+ GetByte();
+ GetByte();
+ if (getAlpha) {
+ GetByte();
+ }
+ }
+ }
+ else if (fillStyle & 0x40)
+ {
+ type = (FillType) (fillStyle & 0x41);
+
+ // Get the bitmapId
+ GetWord();
+
+ // Get the bitmap matrix.
+ GetMatrix(&matrix);
+ }
+ else
+ {
+ type = (FillType) 0;
+
+ // A solid color
+ GetByte();
+ GetByte();
+ GetByte();
+ if (getAlpha) {
+ GetByte();
+ }
+
+ printf("fillstyle: %x %x %x %x\n",
+ defs[i].color.red,
+ defs[i].color.green,
+ defs[i].color.blue,
+ defs[i].color.alpha);
+ }
+ }
+}
+
+void CInputScript::ParseLineStyle(long getAlpha)
+{
+ long i;
+
+ // Get the number of lines.
+ U16 nLines = GetByte();
+
+ // Do we have a larger number?
+ if (nLines == 255)
+ {
+ // Get the larger number.
+ nLines = GetWord();
+ }
+
+ // Get each of the line styles.
+ for (i = 0; i < nLines; i++)
+ {
+ GetWord();
+ GetByte();
+ GetByte();
+ GetByte();
+ if (getAlpha) {
+ GetByte();
+ }
+ }
+}
+
+
+void CInputScript::ParseDefineShape(int level)
+{
+ Shape *shape;
+ Rect rect;
+ U32 tagid;
+
+ tagid = (U32) GetWord();
+ shape = new Shape(tagid,level);
+ if (shape == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ shape->dict = this;
+
+ // Get the frame information.
+ GetRect(&rect);
+
+ shape->setBoundingBox(rect);
+
+ shape->file_ptr = (unsigned char*)malloc(m_tagEnd-m_filePos);
+ if (shape->file_ptr == NULL) {
+ outOfMemory = 1;
+ delete shape;
+ return;
+ }
+ memcpy((void*)shape->file_ptr,(void*)&m_fileBuf[m_filePos], m_tagEnd-m_filePos);
+
+ shape->getStyles = 1;
+ shape->getAlpha = (level == 3);
+
+ ParseShapeData(level == 3, 1);
+
+ addCharacter(shape);
+}
+
+void CInputScript::S_DumpImageGuts()
+{
+#if 0
+ U32 lfCount = 0;
+ printf("----- dumping image details -----");
+ while (m_filePos < m_tagEnd)
+ {
+ if ((lfCount % 16) == 0)
+ {
+ fprintf(stdout, "\n");
+ }
+ lfCount += 1;
+ fprintf(stdout, "%02x ", GetByte());
+ }
+ fprintf(stdout, "\n");
+#endif
+}
+
+void CInputScript::ParseDefineBits()
+{
+ Bitmap *bitmap;
+ U32 tagid = (U32) GetWord();
+ int status;
+
+ bitmap = new Bitmap(tagid,1);
+ if (bitmap == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ status = bitmap->buildFromJpegAbbreviatedData(&m_fileBuf[m_filePos]);
+
+ if (status < 0) {
+ fprintf(stderr,"Unable to read JPEG data\n");
+ delete bitmap;
+ return;
+ }
+
+ addCharacter(bitmap);
+}
+
+
+void CInputScript::ParseDefineBitsJPEG2()
+{
+ Bitmap *bitmap;
+ U32 tagid = (U32) GetWord();
+ int status;
+
+ bitmap = new Bitmap(tagid,2);
+ if (bitmap == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 0, 0);
+
+ if (status < 0) {
+ fprintf(stderr,"Unable to read JPEG data\n");
+ delete bitmap;
+ return;
+ }
+
+ addCharacter(bitmap);
+}
+
+void CInputScript::ParseDefineBitsJPEG3()
+{
+ Bitmap *bitmap;
+ U32 tagid = (U32) GetWord();
+ int status;
+ long offset;
+
+ printf("tagDefineBitsJPEG3 \ttagid %-5u\n", tagid);
+
+ bitmap = new Bitmap(tagid,3);
+ if (bitmap == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ offset = GetDWord(); // Not in the specs !!!!
+
+ status = bitmap->buildFromJpegInterchangeData(&m_fileBuf[m_filePos], 1, offset);
+ if (status < 0) {
+ fprintf(stderr,"Unable to read JPEG data\n");
+ delete bitmap;
+ return;
+ }
+
+ addCharacter(bitmap);
+}
+
+
+void CInputScript::ParseDefineBitsLossless(int level)
+{
+ Bitmap *bitmap;
+ U32 tagid = (U32) GetWord();
+ int status;
+ int tableSize;
+
+ bitmap = new Bitmap(tagid,0);
+ if (bitmap == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ int format = GetByte();
+ int width = GetWord();
+ int height = GetWord();
+
+ tableSize = 0;
+
+ if (format == 3) {
+ tableSize = GetByte();
+ }
+
+ status = bitmap->buildFromZlibData(&m_fileBuf[m_filePos], width, height, format, tableSize, level == 2);
+
+ if (status < 0) {
+ fprintf(stderr,"Unable to read ZLIB data\n");
+ delete bitmap;
+ return;
+ }
+
+ addCharacter(bitmap);
+}
+
+void CInputScript::ParseJPEGTables()
+{
+ Bitmap::readJpegTables(&m_fileBuf[m_filePos]);
+}
+
+
+ButtonRecord * CInputScript::ParseButtonRecord(long getCxform)
+{
+ U16 state;
+ ButtonRecord *br;
+ long tagid;
+ Matrix matrix;
+ long layer;
+ Cxform *cxform;
+
+ state = (U16) GetByte();
+
+ if (state == 0) return 0;
+
+ br = new ButtonRecord;
+ if (br == NULL) {
+ outOfMemory = 1;
+ return 0;
+ }
+
+ tagid = GetWord();
+ layer = GetWord();
+ GetMatrix(&matrix);
+
+ if (br) {
+ br->state = (ButtonState) state;
+ br->character = getCharacter(tagid);
+ br->layer = layer;
+ br->cxform = 0;
+ br->buttonMatrix = matrix;
+ }
+
+ if (getCxform) {
+ cxform = new Cxform;
+ GetCxform(cxform, true);
+ if (br) {
+ br->cxform = cxform;
+ if (cxform == NULL) {
+ outOfMemory = 1;
+ }
+ }
+ }
+
+ return br;
+}
+
+ActionRecord * CInputScript::ParseActionRecord()
+{
+ U8 action;
+ U16 length = 0;
+ char *url, *target, *label;
+ long frameIndex, skipCount;
+ ActionRecord *ar;
+
+ action = GetByte();
+ if (action == 0) return 0;
+
+ ar = new ActionRecord;
+ if (ar == NULL) {
+ outOfMemory = 1;
+ return 0;
+ }
+
+ ar->action = (Action)action;
+
+ if (action & 0x80) {
+ length = GetWord();
+ }
+
+ switch (action) {
+ case ActionGotoFrame:
+ frameIndex = GetWord();
+ if (ar) {
+ ar->frameIndex = frameIndex;
+ }
+ break;
+ case ActionGetURL:
+ url = GetString();
+ target = GetString();
+ if (ar) {
+ ar->url = strdup(url);
+ ar->target = strdup(target);
+ }
+ break;
+ case ActionWaitForFrame:
+ frameIndex = GetWord();
+ skipCount = GetByte();
+ if (ar) {
+ ar->frameIndex = frameIndex;
+ ar->skipCount = skipCount;
+ }
+ break;
+ case ActionSetTarget:
+ target = strdup(GetString());
+ if (ar) {
+ ar->target = target;
+ }
+ break;
+ case ActionGoToLabel:
+ label = GetString();
+ if (ar) {
+ ar->frameLabel = strdup(label);
+ }
+ break;
+ default:
+ while (length--) {
+ GetByte();
+ }
+ break;
+ }
+
+ return ar;
+}
+
+void CInputScript::ParseDefineButton()
+{
+ Button *button;
+ ButtonRecord *buttonRecord;
+ ActionRecord *actionRecord;
+
+ U32 tagid = (U32) GetWord();
+
+ button = new Button(tagid);
+ if (button == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ do {
+ buttonRecord = ParseButtonRecord();
+ if (buttonRecord) {
+ button->addButtonRecord( buttonRecord );
+ }
+ if (outOfMemory) {
+ return;
+ }
+ } while (buttonRecord);
+
+ do {
+ actionRecord = ParseActionRecord();
+ if (actionRecord) {
+ button->addActionRecord( actionRecord );
+ }
+ if (outOfMemory) {
+ return;
+ }
+ } while (actionRecord);
+
+ addCharacter(button);
+}
+
+
+void CInputScript::ParseDefineButton2()
+{
+ Button *button;
+ ButtonRecord *buttonRecord;
+ ActionRecord *actionRecord;
+ U16 transition;
+ U16 offset;
+ U8 menu;
+
+ U32 tagid = (U32) GetWord();
+
+ button = new Button(tagid);
+
+ if (button == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ menu = GetByte();
+
+ offset = GetWord();
+
+ do {
+ buttonRecord = ParseButtonRecord(true);
+ if (buttonRecord) {
+ button->addButtonRecord( buttonRecord );
+ }
+ if (outOfMemory) {
+ return;
+ }
+ } while (buttonRecord);
+
+ while (offset) {
+ offset = GetWord();
+
+ transition = GetWord();
+
+ do {
+ actionRecord = ParseActionRecord();
+ if (actionRecord) {
+ button->addActionRecord( actionRecord );
+ }
+ if (outOfMemory) {
+ return;
+ }
+ } while (actionRecord);
+
+ button->addCondition( transition );
+ }
+
+ addCharacter(button);
+}
+
+
+void CInputScript::ParseDefineFont()
+{
+ SwfFont *font = 0;
+ U32 tagid = (U32) GetWord();
+ long start;
+ long nb,n;
+ long offset;
+ long *offsetTable = 0;
+ Shape *shapes = 0;
+
+ font = new SwfFont(tagid);
+ if (font == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ start = m_filePos;
+
+ offset = GetWord();
+ nb = offset/2;
+ offsetTable = new long[nb];
+ if (offsetTable == NULL) {
+ goto memory_error;
+ }
+ offsetTable[0] = offset;
+
+ for(n=1; n<nb; n++)
+ {
+ offsetTable[n] = GetWord();
+ }
+
+ shapes = new Shape[nb];
+ if (shapes == NULL) {
+ goto memory_error;
+ }
+
+ for(n=0; n<nb; n++)
+ {
+ long here;
+
+ m_filePos = offsetTable[n]+start;
+
+ here = m_filePos;
+ ParseShapeData(0, 0);
+
+ // Keep data for later parsing
+ shapes[n].file_ptr = (unsigned char*)malloc(m_filePos-here);
+ if (shapes[n].file_ptr == NULL) {
+ goto memory_error;
+ }
+ memcpy((void*)shapes[n].file_ptr,(void*)&m_fileBuf[here],m_filePos-here);
+ }
+
+ font->setFontShapeTable(shapes,nb);
+
+ delete[] offsetTable;
+
+ addCharacter(font);
+ return;
+
+memory_error:
+ outOfMemory = 1;
+ if (offsetTable) delete offsetTable;
+ if (font) delete font;
+ if (shapes) delete[] shapes;
+}
+
+
+void CInputScript::ParseDefineMorphShape()
+{
+ U32 tagid = (U32) GetWord();
+
+ tagid = tagid;
+ printf("tagDefineMorphShape \ttagid %-5u\n", tagid);
+}
+
+void CInputScript::ParseDefineFontInfo()
+{
+ SwfFont *font;
+ U32 tagid = (U32) GetWord();
+ long nameLen;
+ char *name;
+ long n,nb;
+ FontFlags flags;
+ long *lut;
+
+ font = (SwfFont *)getCharacter(tagid);
+
+ if (font == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ nameLen = GetByte();
+ name = new char[nameLen+1];
+ if (name == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ for(n=0; n < nameLen; n++)
+ {
+ name[n] = GetByte();
+ }
+ name[n]=0;
+
+ font->setFontName(name);
+
+ delete name;
+
+ flags = (FontFlags)GetByte();
+
+ font->setFontFlags(flags);
+
+ nb = font->getNbGlyphs();
+
+ lut = new long[nb];
+ if (lut == NULL) {
+ outOfMemory = 1;
+ delete font;
+ return;
+ }
+
+ for(n=0; n < nb; n++)
+ {
+ if (flags & fontWideCodes) {
+ lut[n] = GetWord();
+ } else {
+ lut[n] = GetByte();
+ }
+ }
+
+ font->setFontLookUpTable(lut);
+}
+
+
+
+
+
+void CInputScript::ParseDefineFont2()
+{
+ int n;
+ U32 tagid = (U32) GetWord();
+ FontFlags flags;
+ char *name;
+ long nameLen;
+ long fontGlyphCount;
+ long *offsetTable = NULL;
+ Shape *shapes = NULL;
+ long start;
+ SwfFont *font;
+ long *lut = NULL;
+
+ font = new SwfFont(tagid);
+ if (font == NULL) {
+ goto memory_error;
+ }
+
+ flags = (FontFlags)GetWord();
+
+ font->setFontFlags(flags);
+
+ nameLen = GetByte();
+ name = new char[nameLen+1];
+ if (name == NULL) {
+ goto memory_error;
+ }
+ for(n=0; n < nameLen; n++)
+ {
+ name[n] = GetByte();
+ }
+ name[n]=0;
+
+ font->setFontName(name);
+
+ delete name;
+
+ fontGlyphCount = GetWord();
+
+ start = m_filePos;
+
+ offsetTable = new long[fontGlyphCount];
+ if (offsetTable == NULL) {
+ goto memory_error;
+ }
+ for (n=0; n<fontGlyphCount; n++) {
+ if (flags & 8) {
+ offsetTable[n] = GetDWord();
+ } else {
+ offsetTable[n] = GetWord();
+ }
+ }
+
+ shapes = new Shape[fontGlyphCount];
+ if (shapes == NULL) {
+ goto memory_error;
+ }
+
+ for (n=0; n<fontGlyphCount; n++) {
+ long here;
+
+ m_filePos = offsetTable[n]+start;
+
+ here = m_filePos;
+ ParseShapeData(0, 0);
+
+ // Keep data for later parsing
+ shapes[n].file_ptr = (unsigned char*)malloc(m_filePos-here);
+ if (shapes[n].file_ptr == NULL) {
+ goto memory_error;
+ }
+ memcpy((void*)shapes[n].file_ptr,(void*)&m_fileBuf[here],m_filePos-here);
+ }
+
+ font->setFontShapeTable(shapes,fontGlyphCount);
+
+ lut = new long[fontGlyphCount];
+ if (lut == NULL) {
+ goto memory_error;
+ }
+
+ for(n=0; n < fontGlyphCount; n++)
+ {
+ if (flags & 4) {
+ lut[n] = GetWord();
+ } else {
+ lut[n] = GetByte();
+ }
+ }
+
+ font->setFontLookUpTable(lut);
+
+ delete offsetTable;
+
+ addCharacter(font);
+
+ // This is an incomplete parsing
+ return;
+
+memory_error:
+ outOfMemory = 1;
+ if (font) delete font;
+ if (offsetTable) delete offsetTable;
+ if (lut) delete lut;
+ if (shapes) delete[] shapes;
+}
+
+TextRecord * CInputScript::ParseTextRecord(int hasAlpha)
+{
+ TextRecord *tr;
+ TextFlags flags;
+
+ flags = (TextFlags) GetByte();
+ if (flags == 0) return 0;
+
+ tr = new TextRecord;
+ if (tr == NULL) {
+ outOfMemory = 1;
+ return 0;
+ }
+
+ tr->flags = flags;
+
+ if (flags & isTextControl) {
+ if (flags & textHasFont) {
+ long fontId;
+
+ fontId = GetWord();
+ tr->font = (SwfFont *)getCharacter(fontId);
+ }
+ if (flags & textHasColor) {
+ tr->color.red = GetByte();
+ tr->color.green = GetByte();
+ tr->color.blue = GetByte();
+ if (hasAlpha) {
+ tr->color.alpha = GetByte();
+ } else {
+ tr->color.alpha = ALPHA_OPAQUE;
+ }
+ }
+ if (flags & textHasXOffset) {
+ tr->xOffset = GetWord();
+ }
+ if (flags & textHasYOffset) {
+ tr->yOffset = GetWord();
+ }
+ if (flags & textHasFont) {
+ tr->fontHeight = GetWord();
+ }
+ tr->nbGlyphs = GetByte();
+ } else {
+ tr->flags = (TextFlags)0;
+ tr->nbGlyphs = (long)flags;
+ }
+
+ tr->glyphs = new Glyph[ tr->nbGlyphs ];
+ if (tr->glyphs == NULL) {
+ outOfMemory = 1;
+ delete tr;
+ return 0;
+ }
+
+ InitBits();
+ for (int g = 0; g < tr->nbGlyphs; g++)
+ {
+ tr->glyphs[g].index = GetBits(m_nGlyphBits);
+ tr->glyphs[g].xAdvance = GetBits(m_nAdvanceBits);
+ }
+
+ return tr;
+}
+
+void CInputScript::ParseDefineText(int hasAlpha)
+{
+ Text *text;
+ TextRecord *textRecord;
+ Matrix m;
+ Rect rect;
+ U32 tagid = (U32) GetWord();
+
+ text = new Text(tagid);
+ if (text == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+
+ GetRect(&rect);
+ text->setTextBoundary(rect);
+
+ GetMatrix(&m);
+ text->setTextMatrix(m);
+
+ m_nGlyphBits = GetByte();
+ m_nAdvanceBits = GetByte();
+
+ do {
+ textRecord = ParseTextRecord(hasAlpha);
+ if (textRecord) {
+ text->addTextRecord( textRecord );
+ }
+ if (outOfMemory) {
+ delete text;
+ return;
+ }
+ if (m_filePos >= m_tagEnd) break;
+ } while (textRecord);
+
+ addCharacter(text);
+}
+
+
+void CInputScript::ParseDefineSound()
+{
+ Sound *sound;
+ U32 tagid = (U32) GetWord();
+ long nbSamples;
+ long flags;
+ char *buffer;
+
+ sound = new Sound(tagid);
+
+ flags = GetByte();
+ sound->setSoundFlags(flags);
+
+ nbSamples = GetDWord();
+ buffer = sound->setNbSamples(nbSamples);
+ if (buffer == NULL) {
+ outOfMemory = 1;
+ delete sound;
+ return;
+ }
+
+ if (flags & soundIsADPCMCompressed) {
+ Adpcm *adpcm;
+
+ adpcm = new Adpcm( &m_fileBuf[m_filePos] , flags & soundIsStereo );
+
+ adpcm->Decompress((short *)buffer, nbSamples);
+
+ delete adpcm;
+ } else {
+ memcpy(buffer, &m_fileBuf[m_filePos], m_tagLen-5);
+ }
+
+ addCharacter(sound);
+}
+
+
+void CInputScript::ParseDefineButtonSound()
+{
+ U32 tagid = (U32) GetWord();
+ Button *button;
+
+ tagid = tagid;
+
+ printf("tagDefineButtonSound \ttagid %-5u\n", tagid);
+
+ button = (Button *)getCharacter(tagid);
+
+ if (button == 0) {
+ printf(" Couldn't find Button id %d\n", tagid);
+ return;
+ }
+
+ // step through for button states
+ for (int i = 0; i < 4; i++)
+ {
+ Sound *sound;
+ U32 soundTag = GetWord();
+
+ sound = (Sound *)getCharacter(soundTag);
+
+ if (sound) {
+ button->setButtonSound(sound,i);
+ } else if (soundTag) {
+ printf(" Couldn't find Sound id %d\n", soundTag);
+ }
+
+ switch (i)
+ {
+ case 0:
+ printf("upState \ttagid %-5u\n", soundTag);
+ break;
+ case 1:
+ printf("overState \ttagid %-5u\n", soundTag);
+ break;
+ case 2:
+ printf("downState \ttagid %-5u\n", soundTag);
+ break;
+ }
+
+ if (soundTag)
+ {
+ U32 code = GetByte();
+ printf("sound code %u", code);
+
+ if ( code & soundHasInPoint )
+ printf(" inpoint %u", GetDWord());
+ if ( code & soundHasOutPoint )
+ printf(" outpoint %u", GetDWord());
+ if ( code & soundHasLoops )
+ printf(" loops %u", GetWord());
+
+ printf("\n");
+ if ( code & soundHasEnvelope )
+ {
+ int points = GetByte();
+
+ for ( int p = 0; p < points; p++ )
+ {
+ printf("\n");
+ printf("mark44 %u", GetDWord());
+ printf(" left chanel %u", GetWord());
+ printf(" right chanel %u", GetWord());
+ printf("\n");
+ }
+ }
+ }
+ if (m_filePos == m_tagEnd) break;
+ }
+}
+
+void CInputScript::ParseSoundStreamHead()
+{
+ int mixFormat = GetByte();
+
+ // The stream settings
+ int format = GetByte();
+ int nSamples = GetWord();
+
+ mixFormat = mixFormat;
+ format = format;
+ nSamples = nSamples;
+
+ printf("tagSoundStreamHead \tmixFrmt %-3u frmt %-3u nSamples %-5u\n", mixFormat, format, nSamples);
+}
+
+void CInputScript::ParseSoundStreamHead2()
+{
+ int mixFormat = GetByte();
+
+ // The stream settings
+ int format = GetByte();
+ int nSamples = GetWord();
+
+ mixFormat = mixFormat;
+ format = format;
+ nSamples = nSamples;
+
+ //printf("tagSoundStreamHead2 \tmixFormat %-3u format %-3u nSamples %-5u\n", mixFormat, format, nSamples);
+}
+
+void CInputScript::ParseSoundStreamBlock()
+{
+ printf("tagSoundStreamBlock\n");
+}
+
+void CInputScript::ParseDefineButtonCxform()
+{
+ ButtonRecord *br;
+ Button *button;
+ U32 tagid = (U32) GetWord();
+
+ button = (Button *)getCharacter(tagid);
+
+ for (br = button->getButtonRecords(); br; br = br->next)
+ {
+ br->cxform = new Cxform;
+ GetCxform(br->cxform, false);
+ }
+}
+
+void CInputScript::ParseNameCharacter()
+{
+ U32 tagid = (U32) GetWord();
+ char *label = strdup(GetString());
+
+ nameCharacter(tagid, label);
+}
+
+
+void CInputScript::ParseFrameLabel()
+{
+ char *label = strdup(GetString());
+ program->setCurrentFrameLabel(label);
+}
+
+
+void CInputScript::ParseDefineMouseTarget()
+{
+ printf("tagDefineMouseTarget\n");
+}
+
+
+void CInputScript::ParseDefineSprite()
+{
+ Sprite *sprite;
+ Program *prg;
+ int status;
+
+ U32 tagid = (U32) GetWord();
+ U32 frameCount = (U32) GetWord();
+
+ if (frameCount == 0) return;
+
+ printf("tagDefineSprite \ttagid %-5u \tframe count %-5u\n", tagid, frameCount);
+
+ sprite = new Sprite(program->movie, tagid, frameCount);
+ if (sprite == NULL) {
+ outOfMemory = 1;
+ return;
+ }
+ if (sprite->getProgram() == NULL) {
+ delete sprite;
+ outOfMemory = 1;
+ return;
+ }
+
+ prg = sprite->getProgram();
+
+ // Set current program
+ program = prg;
+
+ ParseTags(&status);
+
+ if (outOfMemory) {
+ delete sprite;
+ return;
+ }
+
+ addCharacter(sprite);
+}
+
+
+void CInputScript::ParseUnknown(long code, long len)
+{
+ printf("Unknown Tag : %d - Length = %d\n", code, len);
+}
+
+
+void
+CInputScript::ParseTags(int *status)
+ // Parses the tags within the file.
+{
+
+ // Initialize the end of frame flag.
+ BOOL atEnd = false;
+
+ // Loop through each tag.
+ while (!atEnd)
+ {
+ U32 here;
+
+ // Get the current tag.
+ U16 code = GetTag();
+
+ if (code == notEnoughData) {
+ m_filePos = m_tagStart;
+ *status |= FLASH_PARSE_NEED_DATA;
+ return;
+ }
+
+ //printf("Code %d, tagLen %8u \n", code, m_tagLen);
+
+ here = m_filePos;
+
+ // Get the tag ending position.
+ U32 tagEnd = m_tagEnd;
+
+ if (m_tagEnd > m_actualSize) {
+ m_filePos = m_tagStart;
+ *status |= FLASH_PARSE_NEED_DATA;
+ return;
+ }
+
+ switch (code)
+ {
+ case stagProtect:
+ break;
+
+ case stagEnd:
+
+ // We reached the end of the file.
+ atEnd = true;
+
+ printf("End of Movie\n");
+
+ break;
+
+ case stagShowFrame:
+
+ // Validate frame
+ program->validateLoadingFrame();
+ *status |= FLASH_PARSE_WAKEUP;
+
+ break;
+
+ case stagFreeCharacter:
+ ParseFreeCharacter();
+ break;
+
+ case stagPlaceObject:
+ ParsePlaceObject();
+ break;
+
+ case stagPlaceObject2:
+ ParsePlaceObject2();
+ break;
+
+ case stagRemoveObject:
+ ParseRemoveObject();
+ break;
+
+ case stagRemoveObject2:
+ ParseRemoveObject2();
+ break;
+
+ case stagSetBackgroundColor:
+ ParseSetBackgroundColor();
+ break;
+
+ case stagDoAction:
+ ParseDoAction();
+ break;
+
+ case stagStartSound:
+ ParseStartSound();
+ break;
+
+ case stagStopSound:
+ ParseStopSound();
+ break;
+
+ case stagDefineShape:
+ ParseDefineShape(1);
+ break;
+
+ case stagDefineShape2:
+ ParseDefineShape(2);
+ break;
+
+ case stagDefineShape3:
+ ParseDefineShape(3);
+ break;
+
+ case stagDefineBits:
+ ParseDefineBits();
+ break;
+
+ case stagDefineBitsJPEG2:
+ ParseDefineBitsJPEG2();
+ break;
+
+ case stagDefineBitsJPEG3:
+ ParseDefineBitsJPEG3();
+ break;
+
+ case stagDefineBitsLossless:
+ ParseDefineBitsLossless(1);
+ break;
+
+ case stagDefineBitsLossless2:
+ ParseDefineBitsLossless(2);
+ break;
+
+ case stagJPEGTables:
+ ParseJPEGTables();
+ break;
+
+ case stagDefineButton:
+ ParseDefineButton();
+ break;
+
+ case stagDefineButton2:
+ ParseDefineButton2();
+ break;
+
+ case stagDefineFont:
+ ParseDefineFont();
+ break;
+
+ case stagDefineMorphShape:
+ ParseDefineMorphShape();
+ break;
+
+ case stagDefineFontInfo:
+ ParseDefineFontInfo();
+ break;
+
+ case stagDefineText:
+ ParseDefineText(0);
+ break;
+
+ case stagDefineText2:
+ ParseDefineText(1);
+ break;
+
+ case stagDefineSound:
+ ParseDefineSound();
+ break;
+
+ case stagDefineButtonSound:
+ ParseDefineButtonSound();
+ break;
+
+ case stagSoundStreamHead:
+ ParseSoundStreamHead();
+ break;
+
+ case stagSoundStreamHead2:
+ ParseSoundStreamHead2();
+ break;
+
+ case stagSoundStreamBlock:
+ ParseSoundStreamBlock();
+ break;
+
+ case stagDefineButtonCxform:
+ ParseDefineButtonCxform();
+ break;
+
+ case stagDefineSprite:
+ Program *save;
+
+ save = program;
+ ParseDefineSprite();
+ program->rewindMovie();
+ program = save;
+ break;
+
+ case stagNameCharacter:
+ ParseNameCharacter();
+ break;
+
+ case stagFrameLabel:
+ ParseFrameLabel();
+ break;
+
+ case stagDefineFont2:
+ ParseDefineFont2();
+ break;
+
+ default:
+ ParseUnknown(code, m_tagLen);
+ break;
+ }
+
+ //printf("Bytes read = %d\n", m_filePos-here);
+
+ // Increment the past the tag.
+ m_filePos = tagEnd;
+
+ if (outOfMemory) {
+ fprintf(stderr,"Flash: Out of memory\n");
+ *status |= FLASH_PARSE_OOM;
+ return;
+ }
+ }
+
+ program->validateLoadingFrame();
+ *status |= FLASH_PARSE_EOM;
+}
+
+int
+CInputScript::ParseData(FlashMovie *movie, char * data, long size)
+{
+ int status = FLASH_PARSE_ERROR;
+
+ m_fileBuf = (unsigned char *)data;
+ m_actualSize = size;
+
+ if (needHeader) {
+
+ // Do we have sufficient data to read the header ?
+ if (size < 21) {
+ return FLASH_PARSE_NEED_DATA; // No, need more data
+ }
+
+ needHeader = 0; // Yes
+
+ U8 fileHdr[8];
+
+ memcpy(fileHdr,data,8);
+
+ // Verify the header and get the file size.
+ if (fileHdr[0] != 'F' || fileHdr[1] != 'W' || fileHdr[2] != 'S' )
+ {
+ //fprintf(stderr, "Not a Flash File.\n");
+ return FLASH_PARSE_ERROR; // Error
+ }
+ else
+ {
+ // Get the file version.
+ m_fileVersion = (U16) fileHdr[3];
+ }
+
+ // Get the file size.
+ m_fileSize = (U32) fileHdr[4]
+ | ((U32) fileHdr[5] << 8)
+ | ((U32) fileHdr[6] << 16)
+ | ((U32) fileHdr[7] << 24);
+
+ // Verify the minimum length of a Flash file.
+ if (m_fileSize < 21)
+ {
+ //printf("ERROR: File size is too short\n");
+ return FLASH_PARSE_ERROR; // Error
+ }
+
+ // Set the file position past the header and size information.
+ m_filePos = 8;
+
+ // Get the frame information.
+ GetRect(&frameRect);
+
+ frameRate = GetWord() >> 8;
+
+ frameCount = GetWord();
+
+ program = new Program(movie, frameCount);
+
+ if (program == NULL || program->totalFrames == 0) {
+ return FLASH_PARSE_ERROR;
+ }
+
+ status |= FLASH_PARSE_START;
+ }
+
+ ParseTags(&status);
+
+ return status;
+}
+
+
diff --git a/core/multimedia/opieplayer/libflash/script.h b/core/multimedia/opieplayer/libflash/script.h
new file mode 100644
index 0000000..a41c47e
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/script.h
@@ -0,0 +1,144 @@
+#ifndef _SCRIPT_H_
+#define _SCRIPT_H_
+
+// SWF file parser.
+//
+//////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////
+// Input script object definition.
+//////////////////////////////////////////////////////////////////////
+
+// An input script object. This object represents a script created from
+// an external file that is meant to be inserted into an output script.
+struct CInputScript : public Dict
+{
+ int level;
+ struct CInputScript *next;
+
+ Program *program; // Current parsed program
+
+ // Memory fences
+ int outOfMemory;
+
+ //Flash info
+ long frameRate;
+ long frameCount;
+ Rect frameRect;
+
+ // Pointer to file contents buffer.
+ U8 *m_fileBuf;
+
+ // File state information.
+ U32 m_filePos;
+ U32 m_fileSize;
+ U32 m_actualSize;
+ U32 m_fileStart;
+ U16 m_fileVersion;
+
+ int needHeader;
+
+ // Bit Handling
+ S32 m_bitPos;
+ U32 m_bitBuf;
+
+ // Tag parsing information.
+ U32 m_tagStart;
+ U32 m_tagEnd;
+ U32 m_tagLen;
+
+ // Parsing information.
+ S32 m_nFillBits;
+ S32 m_nLineBits;
+ S32 m_nGlyphBits;
+ S32 m_nAdvanceBits;
+
+ // Set to true if we wish to dump all contents long form
+ U32 m_dumpAll;
+
+ // if set to true will dump image guts (i.e. jpeg, zlib, etc. data)
+ U32 m_dumpGuts;
+
+ // Handle to output file.
+ FILE *m_outputFile;
+
+ // Constructor/destructor.
+ CInputScript(int level = 0);
+ ~CInputScript();
+
+ // Tag scanning methods.
+ U16 GetTag(void);
+ U8 GetByte(void);
+ U16 GetWord(void);
+ U32 GetDWord(void);
+ void GetRect(Rect *r);
+ void GetMatrix(Matrix *matrix);
+
+ void GetCxform(Cxform *cxform, BOOL hasAlpha);
+ char *GetString(void);
+
+ // Routines for reading arbitrary sized bit fields from the stream.
+ // Always call start bits before gettings bits and do not intermix
+ // these calls with GetByte, etc...
+ void InitBits();
+ S32 GetSBits(S32 n);
+ U32 GetBits(S32 n);
+
+ // Tag subcomponent parsing methods
+ void ParseFillStyle(long getAlpha = 0);
+ void ParseLineStyle(long getAlpha = 0);
+ int ParseShapeRecord(long getAlpha = 0);
+ ButtonRecord * ParseButtonRecord(long getCxform = 0);
+ ActionRecord * ParseActionRecord();
+ TextRecord * ParseTextRecord(int hasAlpha = 0);
+ void ParseShapeData(int getAlpha, int getStyles);
+
+ // Parsing methods.
+ void ParseEnd(); // 00: stagEnd
+ void ParseShowFrame(U32 frame, U32 offset); // 01: stagShowFrame
+ void ParseDefineShape(int level); // 02: stagDefineShape
+ void ParseFreeCharacter(); // 03: stagFreeCharacter
+ void ParsePlaceObject(); // 04: stagPlaceObject
+ void ParseRemoveObject(); // 05: stagRemoveObject
+ void ParseDefineBits(); // 06: stagDefineBits
+ void ParseDefineButton(); //x 07: stagDefineButton
+ void ParseJPEGTables(); // 08: stagJPEGTables
+ void ParseSetBackgroundColor(); // 09: stagSetBackgroundColor
+ void ParseDefineFont(); //x 10: stagDefineFont
+ void ParseDefineText(int hasAplha); //x 11: stagDefineText 33: stagDefineText2
+ void ParseDoAction(); // 12: stagDoAction
+ void ParseDefineFontInfo(); //x 13: stagDefineFontInfo
+ void ParseDefineSound(); // 14: stagDefineSound
+ void ParseStartSound(); // 15: stagStartSound
+ void ParseStopSound(); // 16: stagStopSound
+ void ParseDefineButtonSound(); // 17: stagDefineButtonSound
+ void ParseSoundStreamHead(); // 18: stagSoundStreamHead
+ void ParseSoundStreamBlock(); // 19: stagSoundStreamBlock
+ void ParseDefineBitsLossless(int level); // 20: stagDefineBitsLossless 36: stagDefineBitsLossless2
+ void ParseDefineBitsJPEG2(); // 21: stagDefineBitsJPEG2
+ void ParseDefineButtonCxform(); // 23: stagDefineButtonCxform
+ void ParseProtect(); // 24: stagProtect
+ void ParsePlaceObject2(); // 26: stagPlaceObject2
+ void ParseRemoveObject2(); // 28: stagRemoveObject2
+ void ParseDefineButton2(); //x 34: stagDefineButton2
+ void ParseDefineBitsJPEG3(); // 35: stagDefineBitsJPEG3
+ void ParseDefineMouseTarget(); // 38: stagDefineMouseTarget
+ void ParseDefineSprite(); //x 39: stagDefineSprite
+ void ParseNameCharacter(); // 40: stagNameCharacter
+ void ParseFrameLabel(); // 43: stagFrameLabel
+ void ParseSoundStreamHead2(); // 45: stagSoundStreamHead2
+ void ParseDefineMorphShape(); //x 46: stagDefineMorphShape
+ void ParseDefineFont2(); //x 48: stagDefineFont2
+ void ParseUnknown(long,long);
+
+ void ParseTags(int *);
+ int ParseData(FlashMovie *movie, char * data, long size);
+ void S_DumpImageGuts();
+
+#ifdef DUMP
+ long save(char *filenam);
+#endif
+};
+
+
+#endif /* _SCRIPT_H_ */
diff --git a/core/multimedia/opieplayer/libflash/shape.cc b/core/multimedia/opieplayer/libflash/shape.cc
new file mode 100644
index 0000000..0d8df93
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/shape.cc
@@ -0,0 +1,1205 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+#define PRINT 0
+
+#define ABS(v) ((v) < 0 ? -(v) : (v))
+
+static void prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, FillStyleDef *f, long n);
+
+static void clearStyles(GraphicDevice *gd, FillStyleDef *f, long n);
+
+static void drawShape(GraphicDevice *gd, Matrix *matrix1, Cxform *cxform, Shape *shape,
+ ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func);
+
+// Constructor
+
+Shape::Shape(long id, int level) : Character(ShapeType, id)
+{
+ defLevel = level;
+
+ defaultFillStyle.type = f_Solid;
+ defaultFillStyle.color.red = 0;
+ defaultFillStyle.color.green = 0;
+ defaultFillStyle.color.blue = 0;
+ defaultFillStyle.color.alpha = ALPHA_OPAQUE;
+
+ defaultLineStyle.width = 0;
+
+ // This is to force a first update
+ lastMat.a = 0;
+ lastMat.d = 0;
+ shape_size += sizeof(Shape);
+ shape_nb ++;
+
+ file_ptr = NULL;
+ getStyles = 0;
+ getAlpha = 0;
+}
+
+Shape::~Shape()
+{
+ if (file_ptr) {
+ free(file_ptr);
+ }
+}
+
+void
+Shape::setBoundingBox(Rect rect)
+{
+ boundary = rect;
+}
+
+void
+Shape::getBoundingBox(Rect *bb, DisplayListEntry *e)
+{
+ *bb = boundary;
+}
+
+int
+Shape::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
+{
+ //printf("TagId = %d\n", getTagId());
+ //if (getTagId() != 220) return 0;
+
+ if (cxform) {
+ defaultFillStyle.color = cxform->getColor(gd->getForegroundColor());
+ } else {
+ defaultFillStyle.color = gd->getForegroundColor();
+ }
+ defaultFillStyle.color.pixel = gd->allocColor(defaultFillStyle.color);
+
+ drawShape(gd, matrix, cxform, this, ShapeDraw, NULL, 0);
+ return 0;
+}
+
+void
+Shape::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func)
+{
+ gd->setClipping(0);
+ drawShape(gd,matrix,0,this,ShapeGetRegion,id,scan_line_func);
+ gd->setClipping(1);
+}
+
+/************************************************************************/
+
+/* create a new path */
+
+static void newPath(ShapeParser *shape,
+ long x, long y)
+{
+ Path *p;
+ long x1,y1;
+
+ p=&shape->curPath;
+
+ x1 = shape->matrix->getX(x, y);
+ y1 = shape->matrix->getY(x, y);
+
+ p->lastX = x1;
+ p->lastY = y1;
+
+ p->nb_edges = 0;
+ p->nb_segments = 0;
+}
+
+
+static void addSegment1(ShapeParser *shape,
+ long x, long y,
+ FillStyleDef *f0,
+ FillStyleDef *f1,
+ LineStyleDef *l)
+{
+ Path *p;
+ p=&shape->curPath;
+
+ if (l) {
+ /* a line is defined ... it will be drawn later */
+ LineSegment *ls;
+
+ ls = new LineSegment;
+ if (ls != NULL) {
+ ls->l = l;
+ ls->x1 = p->lastX;
+ ls->y1 = p->lastY;
+ ls->x2 = x;
+ ls->y2 = y;
+ ls->first = (p->nb_segments == 0);
+ ls->next = NULL;
+ if (shape->last_line == NULL) {
+ shape->first_line = ls;
+ } else {
+ shape->last_line->next = ls;
+ }
+ shape->last_line = ls;
+ }
+ }
+
+ /* anti antialiasing not needed if line */
+ if (!shape->reverse) {
+ shape->gd->addSegment(p->lastX,p->lastY,x,y,f0,f1,l ? 0 : 1);
+ } else {
+ shape->gd->addSegment(p->lastX,p->lastY,x,y,f1,f0,l ? 0 : 1);
+ }
+
+ p->lastX = x;
+ p->lastY = y;
+
+ p->nb_segments++;
+}
+
+
+static void addLine(ShapeParser *shape, long x, long y,
+ FillStyleDef *f0,
+ FillStyleDef *f1,
+ LineStyleDef *l)
+{
+ long x1,y1;
+ Path *p;
+
+ p=&shape->curPath;
+
+ x1 = shape->matrix->getX(x, y);
+ y1 = shape->matrix->getY(x, y);
+
+ addSegment1(shape,x1,y1,f0,f1,l);
+
+ p->nb_edges++;
+}
+
+
+// This is based on Divide and Conquer algorithm.
+
+#define BFRAC_BITS 0
+#define BFRAC (1 << BFRAC_BITS)
+
+static void
+bezierBuildPoints (ShapeParser *s,
+ int subdivisions,
+ long a1X, long a1Y,
+ long cX, long cY,
+ long a2X, long a2Y)
+{
+ long c1X,c1Y;
+ long c2X,c2Y;
+ long X,Y;
+ long xmin,ymin,xmax,ymax;
+
+ if (subdivisions != 0) {
+
+ /* find the bounding box */
+
+ if (a1X < cX) {
+ xmin = a1X;
+ xmax = cX;
+ } else {
+ xmin = cX;
+ xmax = a1X;
+ }
+ if (a2X < xmin) xmin = a2X;
+ if (a2X > xmax) xmax = a2X;
+
+ if (a1Y < cY) {
+ ymin = a1Y;
+ ymax = cY;
+ } else {
+ ymin = cY;
+ ymax = a1Y;
+ }
+ if (a2Y < ymin) ymin = a2Y;
+ if (a2Y > ymax) ymax = a2Y;
+
+ if (((xmax - xmin) + (ymax - ymin)) >= (BFRAC*FRAC*2)) {
+ // Control point 1
+ c1X = (a1X+cX) >> 1;
+ c1Y = (a1Y+cY) >> 1;
+
+ // Control point 2
+ c2X = (a2X+cX) >> 1;
+ c2Y = (a2Y+cY) >> 1;
+
+ // New point
+ X = (c1X+c2X) >> 1;
+ Y = (c1Y+c2Y) >> 1;
+
+ subdivisions--;
+
+ bezierBuildPoints(s, subdivisions,
+ a1X, a1Y, c1X, c1Y, X, Y);
+ bezierBuildPoints(s, subdivisions,
+ X, Y, c2X, c2Y, a2X, a2Y);
+
+ return;
+ }
+ }
+
+ addSegment1(s, (a2X+(BFRAC/2)) >> BFRAC_BITS,
+ (a2Y+(BFRAC/2)) >> BFRAC_BITS, s->f0, s->f1, s->l);
+}
+
+/* this code is broken, but useful to get something */
+static void flushPaths(ShapeParser *s)
+{
+ LineSegment *ls;
+ LineStyleDef *l;
+ long nx,ny,nn,w;
+ GraphicDevice *gd = s->gd;
+
+ /* draw the filled polygon */
+ gd->drawPolygon();
+
+ /* draw the lines */
+ ls = s->first_line;
+ if (ls != NULL) {
+ do {
+ l = ls->l;
+
+#if 0
+ printf("line %d %d %d %d width=%d\n",
+ ls->x1, ls->y1, ls->x2, ls->y2, l->width);
+#endif
+
+ /* XXX: this width is false, but it is difficult (and expensive)
+ to have the correct one */
+ w = ABS((long)(s->matrix->a * l->width));
+
+ if (w <= ((3*FRAC)/2)) {
+ w = FRAC;
+ }
+#ifdef THIN_LINES
+ if (w <= ((3*FRAC)/2)) {
+ // draw the thin lines only in shapeAction == shapeDraw
+ if (gd->scan_line_func == NULL) {
+ gd->setForegroundColor(l->fillstyle.color);
+ gd->drawLine(ls->x1, ls->y1, ls->x2, ls->y2, w);
+ }
+ } else {
+#else
+ {
+#endif
+ /* compute the normal vector */
+
+ nx = -(ls->y2 - ls->y1);
+ ny = (ls->x2 - ls->x1);
+
+ /* normalize & width */
+ nn = 2 * (long) sqrt(nx * nx + ny * ny);
+
+#define UL ls->x1 + nx -ny, ls->y1 + ny +nx
+#define UR ls->x2 + nx +ny, ls->y2 + ny -nx
+#define LL ls->x1 - nx -ny, ls->y1 - ny +nx
+#define LR ls->x2 - nx +ny, ls->y2 - ny -nx
+
+ if (nn > 0) {
+ nx = (nx * w) / nn;
+ ny = (ny * w) / nn;
+
+ /* top segment */
+ gd->addSegment(UL, UR, NULL, &l->fillstyle, 1);
+
+ /* bottom segment */
+ gd->addSegment(LL, LR, &l->fillstyle, NULL, 1);
+
+ /* right segment */
+ gd->addSegment(UR, LR, &l->fillstyle, NULL, 1);
+
+ /* left segment */
+ gd->addSegment(UL, LL, NULL, &l->fillstyle, 1);
+
+ /* draw the line polygon */
+ gd->drawPolygon();
+ }
+ }
+
+ ls = ls->next;
+ } while (ls != NULL);
+
+ /* delete the line structures */
+
+ ls = s->first_line;
+ while (ls != NULL) {
+ LineSegment *ls1;
+ ls1 = ls->next;
+ delete ls;
+ ls = ls1;
+ }
+
+ /* reset the line pointers */
+ s->first_line = NULL;
+ s->last_line = NULL;
+ }
+}
+
+
+static void addBezier(ShapeParser *shape,
+ long ctrlX1, long ctrlY1,
+ long newX1, long newY1,
+ FillStyleDef *f0,
+ FillStyleDef *f1,
+ LineStyleDef *l)
+{
+ long newX,newY,ctrlX,ctrlY;
+ Path *p;
+
+ p=&shape->curPath;
+
+ /* note: we do the matrix multiplication before calculating the
+ bezier points (faster !) */
+
+ ctrlX = shape->matrix->getX(ctrlX1, ctrlY1);
+ ctrlY = shape->matrix->getY(ctrlX1, ctrlY1);
+ newX = shape->matrix->getX(newX1, newY1);
+ newY = shape->matrix->getY(newX1, newY1);
+
+ shape->f0 = f0;
+ shape->f1 = f1;
+ shape->l = l;
+
+ bezierBuildPoints(shape, 3,
+ p->lastX<<BFRAC_BITS,p->lastY<<BFRAC_BITS,
+ ctrlX<<BFRAC_BITS,ctrlY<<BFRAC_BITS,
+ newX<<BFRAC_BITS,newY<<BFRAC_BITS);
+
+ p->nb_edges++;
+}
+
+/***********************************************************************/
+
+
+/* bit parser */
+
+static void InitBitParser(struct BitParser *b,U8 *buf)
+{
+ b->ptr = buf;
+}
+
+static void InitBits(struct BitParser *b)
+{
+ // Reset the bit position and buffer.
+ b->m_bitPos = 0;
+ b->m_bitBuf = 0;
+}
+
+
+
+static inline U8 GetByte(struct BitParser *b)
+{
+ U8 v;
+ v = *b->ptr++;
+ return v;
+}
+
+static inline U16 GetWord(struct BitParser *b)
+{
+ U8 *s;
+ U16 v;
+ s = b->ptr;
+ v = s[0] | ((U16) s[1] << 8);
+ b->ptr = s + 2;
+ return v;
+}
+
+static inline U32 GetDWord(struct BitParser *b)
+{
+ U32 v;
+ U8 * s = b->ptr;
+ v = (U32) s[0] | ((U32) s[1] << 8) |
+ ((U32) s[2] << 16) | ((U32) s [3] << 24);
+ b->ptr = s + 4;
+ return v;
+}
+
+static inline U32 GetBit (struct BitParser *b)
+{
+ U32 v;
+ S32 m_bitPos = b->m_bitPos;
+ U32 m_bitBuf = b->m_bitBuf;
+
+ if (m_bitPos == 0) {
+ m_bitBuf = (U32)(*b->ptr++) << 24;
+ m_bitPos = 8;
+ }
+
+ v = (m_bitBuf >> 31);
+
+ m_bitPos--;
+ m_bitBuf <<= 1;
+
+ b->m_bitPos = m_bitPos;
+ b->m_bitBuf = m_bitBuf;
+
+ return v;
+}
+
+static inline U32 GetBits (struct BitParser *b, int n)
+{
+ U32 v;
+ S32 m_bitPos = b->m_bitPos;
+ U32 m_bitBuf = b->m_bitBuf;
+
+ if (n == 0)
+ return 0;
+
+ while (m_bitPos < n) {
+ m_bitBuf |= (U32)(*b->ptr++) << (24 - m_bitPos);
+ m_bitPos += 8;
+ }
+
+ v = m_bitBuf >> (32 - n);
+ m_bitBuf <<= n;
+ m_bitPos -= n;
+
+ b->m_bitPos = m_bitPos;
+ b->m_bitBuf = m_bitBuf;
+ return v;
+}
+
+// Get n bits from the string with sign extension.
+static inline S32 GetSBits (struct BitParser *b,S32 n)
+{
+ // Get the number as an unsigned value.
+ S32 v = (S32) GetBits(b,n);
+
+ // Is the number negative?
+ if (v & (1L << (n - 1)))
+ {
+ // Yes. Extend the sign.
+ v |= -1L << n;
+ }
+
+ return v;
+}
+
+
+
+/************************************************************************/
+
+static void GetMatrix(BitParser *b, Matrix* mat)
+{
+ InitBits(b);
+
+ // Scale terms
+ if (GetBit(b))
+ {
+ int nBits = (int) GetBits(b,5);
+ mat->a = (float)(GetSBits(b,nBits))/(float)0x10000;
+ mat->d = (float)(GetSBits(b,nBits))/(float)0x10000;
+ }
+ else
+ {
+ mat->a = mat->d = 1.0;
+ }
+
+ // Rotate/skew terms
+ if (GetBit(b))
+ {
+ int nBits = (int)GetBits(b,5);
+ mat->c = (float)(GetSBits(b,nBits))/(float)0x10000;
+ mat->b = (float)(GetSBits(b,nBits))/(float)0x10000;
+ }
+ else
+ {
+ mat->b = mat->c = 0.0;
+ }
+
+ // Translate terms
+ int nBits = (int) GetBits(b,5);
+ mat->tx = GetSBits(b,nBits);
+ mat->ty = GetSBits(b,nBits);
+}
+
+static FillStyleDef * ParseFillStyle(ShapeParser *shape, long *n, long getAlpha)
+{
+ BitParser *b = &shape->bit_parser;
+ FillStyleDef *defs;
+ U16 i = 0;
+
+ // Get the number of fills.
+ U16 nFills = GetByte(b);
+
+ // Do we have a larger number?
+ if (nFills == 255)
+ {
+ // Get the larger number.
+ nFills = GetWord(b);
+ }
+
+ *n = nFills;
+ defs = new FillStyleDef[ nFills ];
+ if (defs == NULL) return NULL;
+
+ // Get each of the fill style.
+ for (i = 0; i < nFills; i++)
+ {
+ U16 fillStyle = GetByte(b);
+
+ defs[i].type = (FillType) fillStyle;
+
+ if (fillStyle & 0x10)
+ {
+ defs[i].type = (FillType) (fillStyle & 0x12);
+
+ // Get the gradient matrix.
+ GetMatrix(b,&(defs[i].matrix));
+
+ // Get the number of colors.
+ defs[i].gradient.nbGradients = GetByte(b);
+
+ // Get each of the colors.
+ for (U16 j = 0; j < defs[i].gradient.nbGradients; j++)
+ {
+ defs[i].gradient.ratio[j] = GetByte(b);
+ defs[i].gradient.color[j].red = GetByte(b);
+ defs[i].gradient.color[j].green = GetByte(b);
+ defs[i].gradient.color[j].blue = GetByte(b);
+ if (getAlpha) {
+ defs[i].gradient.color[j].alpha = GetByte(b);
+ } else {
+ defs[i].gradient.color[j].alpha = ALPHA_OPAQUE;
+ }
+ }
+ }
+ else if (fillStyle & 0x40)
+ {
+ defs[i].type = (FillType) (fillStyle & 0x41);
+
+ // Get the bitmapId
+ defs[i].bitmap = (Bitmap *)shape->dict->getCharacter(GetWord(b));
+ // Get the bitmap matrix.
+ GetMatrix(b,&(defs[i].matrix));
+ }
+ else
+ {
+ defs[i].type = (FillType) 0;
+
+ // A solid color
+ defs[i].color.red = GetByte(b);
+ defs[i].color.green = GetByte(b);
+ defs[i].color.blue = GetByte(b);
+ if (getAlpha) {
+ defs[i].color.alpha = GetByte(b);
+ } else {
+ defs[i].color.alpha = ALPHA_OPAQUE;
+ }
+ }
+ }
+
+ return defs;
+}
+
+static LineStyleDef * ParseLineStyle(ShapeParser *shape, long *n, long getAlpha)
+{
+ BitParser *b = &shape->bit_parser;
+ LineStyleDef *defs,*def;
+ FillStyleDef *f;
+ long i;
+
+ // Get the number of lines.
+ U16 nLines = GetByte(b);
+
+ // Do we have a larger number?
+ if (nLines == 255)
+ {
+ // Get the larger number.
+ nLines = GetWord(b);
+ }
+
+ *n = nLines;
+ defs = new LineStyleDef[ nLines ];
+ if (defs == NULL) return NULL;
+
+ // Get each of the line styles.
+ for (i = 0; i < nLines; i++)
+ {
+ def=&defs[i];
+ def->width = GetWord(b);
+ def->color.red = GetByte(b);
+ def->color.green = GetByte(b);
+ def->color.blue = GetByte(b);
+ if (getAlpha) {
+ def->color.alpha = GetByte(b);
+ } else {
+ def->color.alpha = ALPHA_OPAQUE;
+ }
+
+ f=&def->fillstyle;
+ f->type = f_Solid;
+ f->color = def->color;
+ if (shape->cxform) {
+ f->color = shape->cxform->getColor(f->color);
+ }
+ f->color.pixel = shape->gd->allocColor(f->color);
+ }
+
+ return defs;
+}
+
+/* 0 = end of shape */
+static int ParseShapeRecord(ShapeParser *shape, ShapeRecord *sr, long getAlpha)
+{
+ BitParser *b = &shape->bit_parser;
+
+ // Determine if this is an edge.
+ BOOL isEdge = (BOOL) GetBit(b);
+
+ if (!isEdge)
+ {
+ // Handle a state change
+ U16 flags = (U16) GetBits(b,5);
+
+ // Are we at the end?
+ if (flags == 0)
+ {
+ // End of shape
+ return 0;
+ }
+
+ sr->type = shapeNonEdge;
+ sr->flags = (ShapeFlags)flags;
+
+ // Process a move to.
+ if (flags & flagsMoveTo)
+ {
+ U16 nBits = (U16) GetBits(b,5);
+ sr->x = GetSBits(b,nBits);
+ sr->y = GetSBits(b,nBits);
+ }
+
+ // Get new fill info.
+ if (flags & flagsFill0)
+ {
+ sr->fillStyle0 = GetBits(b,shape->m_nFillBits);
+ }
+ if (flags & flagsFill1)
+ {
+ sr->fillStyle1 = GetBits(b,shape->m_nFillBits);
+ }
+
+ // Get new line info
+ if (flags & flagsLine)
+ {
+ sr->lineStyle = GetBits(b,shape->m_nLineBits);
+ }
+
+ // Check to get a new set of styles for a new shape layer.
+ if (flags & flagsNewStyles)
+ {
+ FillStyleDef *fillDefs;
+ LineStyleDef *lineDefs;
+ long n;
+
+ // Parse the style.
+ fillDefs = ParseFillStyle(shape, &n, getAlpha);
+ if (fillDefs == NULL) return 0;
+
+ sr->newFillStyles = fillDefs;
+ sr->nbNewFillStyles = n;
+
+ lineDefs = ParseLineStyle(shape, &n, getAlpha);
+ if (lineDefs == NULL) return 0;
+
+ sr->newLineStyles = lineDefs;
+ sr->nbNewLineStyles = n;
+
+ InitBits(b); // Bug !
+
+ // Reset.
+ shape->m_nFillBits = (U16) GetBits(b,4);
+ shape->m_nLineBits = (U16) GetBits(b,4);
+ }
+
+ //if (flags & flagsEndShape)
+ //printf("\tEnd of shape.\n\n");
+
+ return flags & flagsEndShape ? 0 : 1;
+ }
+ else
+ {
+ if (GetBit(b))
+ {
+ sr->type = shapeLine;
+
+ // Handle a line
+ U16 nBits = (U16) GetBits(b,4) + 2; // nBits is biased by 2
+
+ // Save the deltas
+ if (GetBit(b))
+ {
+ // Handle a general line.
+ sr->dX = GetSBits(b,nBits);
+ sr->dY = GetSBits(b,nBits);
+ }
+ else
+ {
+ // Handle a vert or horiz line.
+ if (GetBit(b))
+ {
+ // Vertical line
+ sr->dY = GetSBits(b,nBits);
+ sr->dX = 0;
+ }
+ else
+ {
+ // Horizontal line
+ sr->dX = GetSBits(b,nBits);
+ sr->dY = 0;
+ }
+ }
+ }
+ else
+ {
+ sr->type = shapeCurve;
+
+ // Handle a curve
+ U16 nBits = (U16) GetBits(b,4) + 2; // nBits is biased by 2
+
+ // Get the control
+ sr->ctrlX = GetSBits(b,nBits);
+ sr->ctrlY = GetSBits(b,nBits);
+
+ // Get the anchor
+ sr->anchorX = GetSBits(b,nBits);
+ sr->anchorY = GetSBits(b,nBits);
+ }
+
+ return 1;
+ }
+}
+
+static void drawShape(GraphicDevice *gd, Matrix *matrix1, Cxform *cxform, Shape *shape,
+ ShapeAction shapeAction, void *id,ScanLineFunc scan_line_func)
+{
+ LineStyleDef *l;
+ FillStyleDef *f0;
+ FillStyleDef *f1;
+ ShapeRecord sr1,*sr = &sr1;
+ int firstPoint;
+ long lastX,lastY;
+ LineStyleDef *curLineStyle;
+ long curNbLineStyles;
+ FillStyleDef *curFillStyle;
+ long curNbFillStyles;
+ StyleList *sl;
+ ShapeParser sp1,*sp=&sp1;
+ BitParser *b;
+ Matrix mat,*matrix;
+
+ mat = (*gd->adjust) * (*matrix1);
+ matrix = &mat;
+
+ sp->reverse = (mat.a * mat.d) < 0;
+
+ curLineStyle = NULL;
+ curNbLineStyles = 0;
+ curFillStyle = NULL;
+ curNbFillStyles = 0;
+ sp->style_list = NULL;
+
+ sp->shape = shape;
+ sp->gd = gd;
+ sp->matrix = matrix;
+ sp->cxform = cxform;
+ sp->dict = shape->dict;
+
+ if (shapeAction == ShapeGetRegion) {
+ gd->scan_line_func = scan_line_func;
+ gd->scan_line_func_id = id;
+ } else {
+ gd->scan_line_func = NULL;
+ }
+
+ b = &sp->bit_parser;
+ InitBitParser(b,shape->file_ptr);
+
+ if (shape->getStyles) {
+ // ShapeWithStyle
+ curFillStyle = ParseFillStyle(sp, &curNbFillStyles, shape->getAlpha);
+ if (curFillStyle == NULL) return;
+
+ curLineStyle = ParseLineStyle(sp, &curNbLineStyles, shape->getAlpha);
+ if (curLineStyle == NULL) return;
+
+ sl = new StyleList;
+ if (sl == NULL) return;
+
+ sl->next = NULL;
+ sl->newFillStyles = curFillStyle;
+ sl->nbNewFillStyles = curNbFillStyles;
+ sl->newLineStyles = curLineStyle;
+ sl->nbNewLineStyles = curNbLineStyles;
+
+ sp->style_list = sl;
+
+ if (shapeAction == ShapeDraw) {
+ prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles);
+ }
+ }
+
+ InitBits(b);
+ sp->m_nFillBits = (U16) GetBits(b,4);
+ sp->m_nLineBits = (U16) GetBits(b,4);
+
+ l = 0;
+ f0 = 0;
+ f1 = 0;
+ firstPoint = 1;
+ lastX = 0;
+ lastY = 0;
+ sp->curPath.nb_edges = 0;
+ sp->first_line = NULL;
+ sp->last_line = NULL;
+
+ for(;;) {
+ if (ParseShapeRecord(sp, sr, shape->getAlpha) == 0) break;
+
+ switch (sr->type)
+ {
+ case shapeNonEdge:
+ if (sr->flags & flagsNewStyles) {
+
+ curFillStyle = sr->newFillStyles;
+ curNbFillStyles = sr->nbNewFillStyles;
+ curLineStyle = sr->newLineStyles;
+ curNbLineStyles = sr->nbNewLineStyles;
+
+ sl = new StyleList;
+ sl->next = sp->style_list;
+ sl->newFillStyles = sr->newFillStyles;
+ sl->nbNewFillStyles = sr->nbNewFillStyles;
+ sl->newLineStyles = sr->newLineStyles;
+ sl->nbNewLineStyles = sr->nbNewLineStyles;
+
+ sp->style_list = sl;
+
+ if (shapeAction == ShapeDraw) {
+ prepareStyles(gd, matrix, cxform, curFillStyle, curNbFillStyles);
+ }
+ }
+ if (sr->flags & flagsFill0) {
+ if (sr->fillStyle0) {
+ if (curFillStyle) {
+ f0 = &curFillStyle[sr->fillStyle0-1];
+ } else {
+ f0 = &shape->defaultFillStyle;
+ }
+ } else {
+ f0 = 0;
+ }
+ }
+ if (sr->flags & flagsFill1) {
+ if (sr->fillStyle1) {
+ if (curFillStyle) {
+ f1 = &curFillStyle[sr->fillStyle1-1];
+ } else {
+ f1 = &shape->defaultFillStyle;
+ }
+ } else {
+ f1 = 0;
+ }
+ }
+ if (sr->flags & flagsLine) {
+ if (sr->lineStyle) {
+ l = &curLineStyle[sr->lineStyle-1];
+ } else {
+ l = 0;
+ }
+ }
+ if (sr->flags & flagsMoveTo) {
+ if (sp->curPath.nb_edges == 0) {
+ /* if no edges, draw the polygon, then the lines */
+ flushPaths(sp);
+ }
+
+ newPath(sp, sr->x, sr->y);
+ firstPoint = 0;
+
+ lastX = sr->x;
+ lastY = sr->y;
+
+#if PRINT
+ printf("---------\nX,Y = %4d,%4d\n", sr->x/20, sr->y/20);
+#endif
+ }
+ break;
+ case shapeCurve:
+ // Handle Bezier Curves !!!
+ if (firstPoint) {
+ newPath(sp, 0, 0);
+ firstPoint = 0;
+ }
+ {
+ long newX,newY,ctrlX,ctrlY;
+
+ ctrlX = lastX+sr->ctrlX;
+ ctrlY = lastY+sr->ctrlY;
+ newX = ctrlX+sr->anchorX;
+ newY = ctrlY+sr->anchorY;
+
+#if 1
+ addBezier(sp, ctrlX, ctrlY, newX, newY, f0 , f1, l);
+#else
+ addLine(sp, newX, newY, f0, f1, l);
+#endif
+
+ lastX = newX;
+ lastY = newY;
+ }
+ break;
+ case shapeLine:
+ if (firstPoint) {
+ newPath(sp, 0, 0);
+ firstPoint = 0;
+ }
+
+ lastX += sr->dX;
+ lastY += sr->dY;
+
+ addLine(sp, lastX, lastY, f0, f1, l);
+#if PRINT
+ printf(" X, Y = %4d,%4d\n", lastX/20, lastY/20);
+#endif
+ break;
+ }
+ }
+
+ /* XXX: should test if there is something to draw */
+ flushPaths(sp);
+
+ /* free the styles */
+ while (sp->style_list) {
+ StyleList *sl;
+
+ sl=sp->style_list;
+ sp->style_list = sl->next;
+
+ if (shapeAction == ShapeDraw) {
+ clearStyles(gd, sl->newFillStyles, sl->nbNewFillStyles);
+ }
+
+ delete[] sl->newFillStyles;
+ delete[] sl->newLineStyles;
+
+ delete sl;
+ }
+}
+
+static void
+prepareStyles(GraphicDevice *gd, Matrix *matrix, Cxform *cxform,
+ FillStyleDef *ftab, long n)
+{
+ long fs;
+ FillStyleDef *f;
+
+ for(fs = 0; fs < n; fs++)
+ {
+ f = ftab + fs;
+ switch (f->type)
+ {
+ case f_None:
+ break;
+ case f_Solid:
+ if (cxform) {
+ f->color = cxform->getColor(f->color);
+ }
+ f->color.pixel = gd->allocColor(f->color);
+ break;
+ case f_LinearGradient:
+ case f_RadialGradient:
+ {
+ Matrix mat;
+ int n,r,l;
+ long red, green, blue, alpha;
+ long dRed, dGreen, dBlue, dAlpha;
+ long min,max;
+ Matrix *m;
+
+ mat = *(matrix) * f->matrix;
+ // Compute inverted matrix
+ f->gradient.imat = mat.invert();
+
+ /* renormalize the matrix */
+ m=&f->gradient.imat;
+ if (f->type == f_LinearGradient) {
+ m->a = m->a * FRAC * (1/128.0) * 65536.0;
+ m->b = m->b * FRAC * (1/128.0) * 65536.0;
+ m->tx = (long) ((m->tx + 16384) * (1/128.0) * 65536.0);
+ } else {
+ m->a = m->a * FRAC * (1/64.0) * 65536.0;
+ m->b = m->b * FRAC * (1/64.0) * 65536.0;
+ m->c = m->c * FRAC * (1/64.0) * 65536.0;
+ m->d = m->d * FRAC * (1/64.0) * 65536.0;
+ m->tx = (long) (m->tx * (1/64.0) * 65536.0);
+ m->ty = (long) (m->ty * (1/64.0) * 65536.0);
+ }
+
+ // Reset translation in inverted matrix
+ f->gradient.has_alpha = 0;
+
+ // Build a 256 color ramp
+ f->gradient.ramp = new Color[256];
+ if (f->gradient.ramp == NULL) {
+ // Invalidate fill style
+ f->type = f_None;
+ continue;
+ }
+
+ // Store min and max
+ min = f->gradient.ratio[0];
+ max = f->gradient.ratio[f->gradient.nbGradients-1];
+ for(r=0; r < f->gradient.nbGradients-1; r++)
+ {
+ Color start,end;
+
+ l = f->gradient.ratio[r+1]-f->gradient.ratio[r];
+ if (l == 0) continue;
+
+ if (cxform) {
+ start = cxform->getColor(f->gradient.color[r]);
+ end = cxform->getColor(f->gradient.color[r+1]);
+ } else {
+ start = f->gradient.color[r];
+ end = f->gradient.color[r+1];
+ }
+
+ if (start.alpha != ALPHA_OPAQUE ||
+ end.alpha != ALPHA_OPAQUE) {
+ f->gradient.has_alpha = 1;
+ }
+
+ dRed = end.red - start.red;
+ dGreen = end.green - start.green;
+ dBlue = end.blue - start.blue;
+ dAlpha = end.alpha - start.alpha;
+
+ dRed = (dRed<<16)/l;
+ dGreen = (dGreen<<16)/l;
+ dBlue = (dBlue<<16)/l;
+ dAlpha = (dAlpha<<16)/l;
+
+ red = start.red <<16;
+ green = start.green <<16;
+ blue = start.blue <<16;
+ alpha = start.alpha <<16;
+
+ for (n=f->gradient.ratio[r]; n<=f->gradient.ratio[r+1]; n++) {
+ f->gradient.ramp[n].red = red>>16;
+ f->gradient.ramp[n].green = green>>16;
+ f->gradient.ramp[n].blue = blue>>16;
+ f->gradient.ramp[n].alpha = alpha>>16;
+
+ f->gradient.ramp[n].pixel = gd->allocColor(f->gradient.ramp[n]);
+ red += dRed;
+ green += dGreen;
+ blue += dBlue;
+ alpha += dAlpha;
+ }
+ }
+ for(n=0; n<min; n++) {
+ f->gradient.ramp[n] = f->gradient.ramp[min];
+ }
+ for(n=max; n<256; n++) {
+ f->gradient.ramp[n] = f->gradient.ramp[max];
+ }
+ }
+ break;
+ case f_TiledBitmap:
+ case f_clippedBitmap:
+ if (f->bitmap) {
+ Matrix *m;
+
+ f->cmap = gd->getColormap(f->bitmap->colormap,
+ f->bitmap->nbColors, cxform);
+ if (f->cmap == NULL) {
+ /* Get the normal cmap anyway */
+ f->cmap = f->bitmap->colormap;
+ }
+
+ f->bitmap_matrix = *(matrix) * f->matrix;
+
+ f->bitmap_matrix = f->bitmap_matrix.invert();
+
+ m=&f->bitmap_matrix;
+ m->a = m->a * FRAC * 65536.0;
+ m->b = m->b * FRAC * 65536.0;
+ m->c = m->c * FRAC * 65536.0;
+ m->d = m->d * FRAC * 65536.0;
+ m->tx = (long) (m->tx * 65536.0);
+ m->ty = (long) (m->ty * 65536.0);
+
+ f->alpha_table = NULL;
+
+ if (f->bitmap->alpha_buf && cxform) {
+ unsigned char *alpha_table;
+ int i;
+
+ alpha_table = (unsigned char *)malloc (256);
+ if (alpha_table != NULL) {
+ for(i=0;i<256;i++) {
+ alpha_table[i] = cxform->getAlpha(i);
+ }
+ }
+ f->alpha_table = alpha_table;
+ }
+ }
+ break;
+ }
+ }
+}
+
+static void
+clearStyles(GraphicDevice *gd, FillStyleDef *ftab, long n)
+{
+ long fs;
+ FillStyleDef *f;
+
+ for(fs = 0; fs < n; fs++)
+ {
+ f = ftab + fs;
+ switch (f->type)
+ {
+ case f_Solid:
+ break;
+ case f_LinearGradient:
+ case f_RadialGradient:
+ if (f->gradient.ramp) {
+ delete f->gradient.ramp;
+ }
+ break;
+ case f_TiledBitmap:
+ case f_clippedBitmap:
+ if (f->bitmap) {
+ if (f->cmap && f->cmap != f->bitmap->colormap) delete f->cmap;
+ if (f->alpha_table) free(f->alpha_table);
+ }
+ break;
+ case f_None:
+ break;
+ }
+ }
+}
+
diff --git a/core/multimedia/opieplayer/libflash/shape.h b/core/multimedia/opieplayer/libflash/shape.h
new file mode 100644
index 0000000..120ec94
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/shape.h
@@ -0,0 +1,181 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _SHAPE_H_
+#define _SHAPE_H_
+
+struct LineStyleDef {
+ long width;
+ Color color;
+ FillStyleDef fillstyle;
+};
+
+enum ShapeRecordType {
+ shapeNonEdge,
+ shapeCurve,
+ shapeLine
+};
+
+enum ShapeFlags {
+ flagsMoveTo = 0x01,
+ flagsFill0 = 0x02,
+ flagsFill1 = 0x04,
+ flagsLine = 0x08,
+ flagsNewStyles = 0x10,
+ flagsEndShape = 0x80
+};
+
+struct ShapeRecord {
+ ShapeRecordType type;
+
+ // Non Edge
+ ShapeFlags flags;
+ long x,y; // Moveto
+ long fillStyle0;
+ long fillStyle1;
+ long lineStyle;
+ FillStyleDef *newFillStyles; // Array
+ long nbNewFillStyles;
+ LineStyleDef *newLineStyles; // Array
+ long nbNewLineStyles;
+
+ // Curve Edge
+ long ctrlX, ctrlY;
+ long anchorX, anchorY;
+
+ // Straight Line
+ long dX,dY;
+
+ struct ShapeRecord *next;
+
+ ShapeRecord() {
+ shaperecord_size += sizeof(ShapeRecord);
+ shaperecord_nb++;
+ }
+
+};
+
+enum ShapeAction {
+ ShapeDraw,
+ ShapeGetRegion
+};
+
+struct LineSegment {
+ long x1,y1,x2,y2;
+ char first;
+ LineStyleDef *l;
+ struct LineSegment *next;
+};
+
+struct Path {
+ long lastX,lastY;
+ int nb_edges;
+ int nb_segments;
+};
+
+struct StyleList {
+ FillStyleDef *newFillStyles; // Array
+ long nbNewFillStyles;
+ LineStyleDef *newLineStyles; // Array
+ long nbNewLineStyles;
+
+ StyleList *next;
+};
+
+
+/* fast bit parser */
+struct BitParser {
+ // Bit Handling
+ S32 m_bitPos;
+ U32 m_bitBuf;
+
+ U8 *ptr;
+};
+
+class Shape;
+
+/* state of the shape parser */
+struct ShapeParser {
+ Dict *dict; /* XXX: should be put elsewhere */
+
+ BitParser bit_parser;
+ S32 m_nFillBits;
+ S32 m_nLineBits;
+
+ StyleList *style_list;
+ Matrix *matrix;
+ Path curPath;
+ int reverse;
+
+ /* line rasteriser */
+ LineSegment *first_line,*last_line;
+ GraphicDevice *gd;
+ Cxform *cxform;
+ Shape *shape;
+
+ FillStyleDef *f0;
+ FillStyleDef *f1;
+ LineStyleDef *l;
+};
+
+class Shape : public Character {
+ public:
+ int defLevel; // 1,2 or 3
+
+
+ Rect boundary;
+ FillStyleDef defaultFillStyle;
+ LineStyleDef defaultLineStyle;
+
+ Matrix lastMat;
+ /* parsing for the rendering stage (saves a lot of memory &
+ may not reduce significantly the size). These variables
+ should be in another structure (no state need to be
+ maintained between two renderings) */
+ int getAlpha, getStyles;
+ unsigned char *file_ptr;
+ Dict *dict; /* XXX: should be put elsewhere */
+
+protected:
+ void drawLines(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, long, long);
+ void buildSegmentList(Segment **segs, int height, long &n, Matrix *matrix, int update, int reverse);
+ Segment *progressSegments(Segment *, long);
+ Segment *newSegments(Segment *, Segment *);
+
+public:
+ Shape(long id = 0 , int level = 1);
+ ~Shape();
+
+ void setBoundingBox(Rect rect);
+ int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform);
+ void getRegion(GraphicDevice *gd, Matrix *matrix,
+ void *id, ScanLineFunc scan_line_func);
+
+ void getBoundingBox(Rect *bb, DisplayListEntry *);
+
+#ifdef DUMP
+ void dump(BitStream *bs);
+ void dumpShapeRecords(BitStream *bs, int alpha);
+ void dumpFillStyles(BitStream *bs, FillStyleDef *defs, long n, int alpha);
+ void dumpLineStyles(BitStream *bs, LineStyleDef *defs, long n, int alpha);
+ void checkBitmaps(BitStream *bs);
+#endif
+};
+
+#endif /* _SHAPE_H_ */
diff --git a/core/multimedia/opieplayer/libflash/sound.cc b/core/multimedia/opieplayer/libflash/sound.cc
new file mode 100644
index 0000000..e93f9b5
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/sound.cc
@@ -0,0 +1,439 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#ifndef NOSOUND
+#include <linux/soundcard.h>
+#endif
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+#define PRINT 0
+
+//////////// SOUND
+
+Sound::Sound(long id) : Character(SoundType, id)
+{
+ samples = 0;
+ stereo = 0;
+ soundRate = 0;
+ sampleSize = 1;
+}
+
+Sound::~Sound()
+{
+ if (samples) {
+ delete samples;
+ }
+}
+
+void
+Sound::setSoundFlags(long f) {
+ switch (GET_SOUND_RATE_CODE(f)) {
+ case 0:
+ soundRate = 5500;
+ break;
+ case 1:
+ soundRate = 11000;
+ break;
+ case 2:
+ soundRate = 22000;
+ break;
+ case 3:
+ soundRate = 44000;
+ break;
+ }
+ if (f & soundIs16bit) {
+ sampleSize = 2;
+ }
+ if (f & soundIsStereo) {
+ stereo = 1;
+ }
+
+#if PRINT
+ printf("-----\nFlags = %2x\n", f);
+ printf("Rate = %d kHz ", soundRate);
+ printf("SampleSize = %d byte(s) ", sampleSize);
+ if (f & soundIsStereo) {
+ printf("Stereo ");
+ } else {
+ printf("Mono ");
+ }
+ if (f & soundIsADPCMCompressed) {
+ printf("ADPCM\n");
+ } else {
+ printf("Raw\n");
+ }
+#endif
+}
+
+char *
+Sound::setNbSamples(long n) {
+ long size;
+
+ nbSamples = n;
+
+ size = nbSamples * (stereo ? 2 : 1) * sampleSize;
+
+ samples = new char[ size ];
+
+ memset((char *)samples,0, size);
+
+ return samples;
+}
+
+long
+Sound::getRate() {
+ return soundRate;
+}
+
+long
+Sound::getChannel() {
+ return stereo ? 2 : 1;
+}
+
+long
+Sound::getNbSamples() {
+ return nbSamples;
+}
+
+long
+Sound::getSampleSize() {
+ return sampleSize;
+}
+
+char *
+Sound::getSamples() {
+ return samples;
+}
+
+//////////// SOUND MIXER
+
+long SoundMixer::dsp = -1; // Init of descriptor
+long SoundMixer::blockSize = 0; // Driver sound buffer size
+long SoundMixer::nbInst = 0; // Nb SoundMixer instances
+long SoundMixer::sampleSize = 0;
+long SoundMixer::stereo = 0;
+long SoundMixer::soundRate = 0;
+char *SoundMixer::buffer = 0;
+
+SoundMixer::SoundMixer(char *device)
+{
+#ifndef NOSOUND
+ int status;
+ long fmt;
+
+ list = 0; // No sound to play
+
+ if (nbInst++) {
+ // Device is already open
+ return;
+ }
+
+ dsp = open(device,O_WRONLY);
+ if (dsp < 0) {
+ perror("open dsp");
+ return;
+ }
+
+ // Reset device
+ status = ioctl(dsp, SNDCTL_DSP_RESET);
+ if (status < 0) perror("ioctl SNDCTL_DSP_RESET");
+
+ // Set sample size
+ fmt = AFMT_S16_LE;
+ sampleSize = 2;
+ status = ioctl(dsp, SNDCTL_DSP_SETFMT, &fmt);
+ if (status < 0) perror("ioctl SNDCTL_DSP_SETFMT");
+
+ if (status) {
+ fmt = AFMT_U8;
+ sampleSize = 1;
+ status = ioctl(dsp, SNDCTL_DSP_SETFMT, &fmt);
+ if (status < 0) perror("ioctl SNDCTL_DSP_SETFMT");
+ }
+
+ // Set stereo channel
+ stereo = 1;
+ status = ioctl(dsp, SNDCTL_DSP_STEREO, &stereo);
+
+ if (status) {
+ stereo = 0;
+ }
+
+ // Set sound rate in Hertz
+ soundRate = 11000;
+ status = ioctl(dsp, SNDCTL_DSP_SPEED, &soundRate);
+ if (status < 0) perror("ioctl SNDCTL_DSP_SPEED");
+
+ // Get device buffer size
+ status = ioctl(dsp, SNDCTL_DSP_GETBLKSIZE, &blockSize);
+ if (status < 0) perror("ioctl SNDCTL_DSP_GETBLKSIZE");
+ if (blockSize < 1024) {
+ blockSize = 32768;
+ }
+ blockSize *= 2;
+
+ buffer = (char *)malloc(blockSize);
+ if (buffer == 0) {
+ close(dsp);
+ dsp = -1;
+ }
+
+#if PRINT
+ int caps;
+
+ ioctl(dsp,SNDCTL_DSP_GETCAPS, &caps);
+ printf("Audio capabilities = %x\n", caps);
+ printf("Sound Rate = %d\n", soundRate);
+ printf("Stereo = %d\n", stereo);
+ printf("Sample Size = %d\n", sampleSize);
+ printf("Buffer Size = %d\n", blockSize);
+#endif /* PRINT */
+
+#endif /* NOSOUND */
+}
+
+SoundMixer::~SoundMixer()
+{
+ if (--nbInst == 0) {
+ if (dsp > 0) {
+ close(dsp);
+ free(buffer);
+ }
+ }
+}
+
+void
+SoundMixer::stopSounds()
+{
+#ifndef NOSOUND
+ SoundList *sl,*del;
+
+ for(sl = list; sl; ) {
+ del = sl;
+ sl = sl->next;
+ delete del;
+ }
+ list = 0;
+#endif
+}
+
+void
+SoundMixer::startSound(Sound *sound)
+{
+#ifndef NOSOUND
+ SoundList *sl;
+
+ if (sound) {
+ // Add sound in list
+ sl = new SoundList;
+ sl->rate = sound->getRate();
+ sl->stereo = (sound->getChannel() == 2);
+ sl->sampleSize = sound->getSampleSize();
+ sl->current = sound->getSamples();
+ sl->remaining = sound->getSampleSize()*sound->getNbSamples()*sound->getChannel();
+ sl->next = list;
+ list = sl;
+ }
+#endif
+}
+
+long
+SoundMixer::playSounds()
+{
+#ifndef NOSOUND
+ audio_buf_info bufInfo;
+ long nbBytes, n;
+ SoundList *sl,*prev;
+ int status;
+
+ // Init failed
+ if (dsp < 0) return 0;
+
+ // No sound to play
+ if (list == 0) return 0;
+
+ // Get free DMA buffer space
+ status = ioctl(dsp, SNDCTL_DSP_GETOSPACE, &bufInfo);
+
+ // Free space is not large enough to output data without blocking
+ // But there are still sounds to play. We must wait.
+ if (bufInfo.bytes < blockSize) return 1;
+
+ nbBytes = 0;
+
+ // Fill buffer with silence.
+ memset((void*)buffer, 0, blockSize);
+
+ prev = 0;
+ sl = list;
+ while(sl) {
+
+ // Ask sound to fill the buffer
+ // according to device capabilities
+ n = fillSoundBuffer(sl, buffer, blockSize);
+
+ // Remember the largest written size
+ if (n > nbBytes) {
+ nbBytes = n;
+ }
+
+ // No more samples for this sound
+ if (sl->remaining == 0) {
+ // Remove sound from list
+ if (prev) {
+ prev->next = sl->next;
+ delete sl;
+ sl = prev->next;
+ } else {
+ list = sl->next;
+ delete sl;
+ sl = list;
+ }
+ } else {
+ sl = sl->next;
+ }
+ }
+
+ if (nbBytes) {
+ // At last ! Play It !
+ write(dsp,buffer,nbBytes);
+ status = ioctl(dsp, SNDCTL_DSP_POST);
+ }
+
+ return nbBytes;
+#else
+ return 0;
+#endif
+}
+
+long
+SoundMixer::fillSoundBuffer(SoundList *sl, char *buff, long buffSize)
+{
+ long sampleLeft, sampleRight;
+ long skipOut, skipOutInit;
+ long skipIn, skipInInit;
+ long freqRatio;
+ long totalOut = 0;
+
+ sampleLeft = sampleRight = 0;
+ skipOutInit = skipInInit = 0;
+
+ freqRatio = sl->rate / soundRate;
+ if (freqRatio) {
+ skipOutInit = freqRatio - 1;
+ skipInInit = 0;
+ }
+
+ freqRatio = soundRate / sl->rate;
+ if (freqRatio) {
+ skipInInit = freqRatio - 1;
+ skipOutInit = 0;
+ }
+
+ skipOut = skipOutInit;
+ skipIn = skipInInit;
+ while (buffSize && sl->remaining) {
+ if (skipIn-- == 0) {
+ // Get sampleLeft
+ if (sl->sampleSize == 2) {
+ sampleLeft = (long)(*(short *)(sl->current));
+ if (sampleSize == 1) {
+ sampleLeft = (sampleLeft >> 8) &0xff;
+ }
+ } else {
+ sampleLeft = (long)*(sl->current);
+ if (sampleSize == 2) {
+ sampleLeft <<= 8;
+ }
+ }
+ sl->current += sl->sampleSize;
+ sl->remaining -= sl->sampleSize;
+
+ if (sl->stereo) {
+ // Get sampleRight
+ if (sl->sampleSize == 2) {
+ sampleRight = (long)(*(short *)(sl->current));
+ if (sampleSize == 1) {
+ sampleRight = (sampleRight >> 8) &0xff;
+ }
+ } else {
+ sampleRight = (long)*(sl->current);
+ if (sampleSize == 2) {
+ sampleRight <<= 8;
+ }
+ }
+ sl->current += sl->sampleSize;
+ sl->remaining -= sl->sampleSize;
+
+ } else {
+ sampleRight = sampleLeft;
+ }
+
+ skipIn = skipInInit;
+ }
+
+ if (skipOut-- == 0) {
+ // Output
+ if (stereo) {
+ if (sampleSize == 2) {
+ *((short *)buff) += sampleLeft/2;
+ buffSize -= sampleSize;
+ buff += sampleSize;
+ *((short *)buff) += sampleRight/2;
+ buffSize -= sampleSize;
+ buff += sampleSize;
+ } else {
+ *((char *)buff) += sampleLeft/2;
+ buffSize -= sampleSize;
+ buff += sampleSize;
+ *((char *)buff) += sampleRight/2;
+ buffSize -= sampleSize;
+ buff += sampleSize;
+ }
+ totalOut += 2*sampleSize;
+ } else {
+ if (sampleSize == 2) {
+ *((short *)buff) += (sampleLeft+sampleRight)>>2;
+ buffSize -= sampleSize;
+ buff += sampleSize;
+ } else {
+ *((char *)buff) += (sampleLeft+sampleRight)>>2;
+ buffSize -= sampleSize;
+ buff += sampleSize;
+ }
+ totalOut += sampleSize;
+ }
+
+ skipOut = skipOutInit;
+ }
+ }
+
+ return totalOut;
+}
diff --git a/core/multimedia/opieplayer/libflash/sound.h b/core/multimedia/opieplayer/libflash/sound.h
new file mode 100644
index 0000000..c53773d
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/sound.h
@@ -0,0 +1,83 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _SOUND_H_
+#define _SOUND_H_
+
+#define GET_SOUND_RATE_CODE(f) (((f)&0x0c)>>2)
+
+class Sound : public Character {
+ long soundRate; // In hz
+ long stereo; // True if stereo sound
+ long sampleSize; // 1 or 2 bytes
+
+ char *samples; // Array of samples
+ long nbSamples;
+
+public:
+ Sound(long id);
+ ~Sound();
+ void setSoundFlags(long f);
+ char *setNbSamples(long n);
+
+ long getRate();
+ long getChannel();
+ long getNbSamples();
+ long getSampleSize();
+ char *getSamples();
+};
+
+struct SoundList {
+ long rate;
+ long stereo;
+ long sampleSize;
+ long nbSamples;
+ long remaining;
+ char *current;
+
+ SoundList *next;
+};
+
+class SoundMixer {
+
+ SoundList *list;
+
+// Class variables
+static long dsp; // Descriptor for /dev/dsp
+static char * buffer; // DMA buffer
+static long blockSize;
+static long nbInst; // Number of instances
+
+ // Sound Device Capabilities
+static long soundRate; // In hz
+static long stereo; // True if stereo sound
+static long sampleSize; // 1 or 2 bytes
+
+public:
+ SoundMixer(char*);
+ ~SoundMixer();
+
+ void startSound(Sound *sound); // Register a sound to be played
+ void stopSounds(); // Stop every current sounds in the instance
+
+ long playSounds(); // Actually play sounds of all instances
+ long fillSoundBuffer(SoundList *, char *buffer, long bufferSize); // Fill sound buffer
+};
+
+#endif /* _SOUND_H_ */
diff --git a/core/multimedia/opieplayer/libflash/sprite.cc b/core/multimedia/opieplayer/libflash/sprite.cc
new file mode 100644
index 0000000..de53095
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/sprite.cc
@@ -0,0 +1,91 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+Sprite::Sprite(FlashMovie *movie, long id, long frameCount) : Character(SpriteType, id)
+{
+ program = new Program(movie, frameCount);
+ if (program == NULL) return;
+ if (program->totalFrames == 0) {
+ delete program;
+ program = NULL;
+ return;
+ }
+ program->dl->isSprite = 1;
+}
+
+Sprite::~Sprite()
+{
+ delete program;
+}
+
+void
+Sprite::reset()
+{
+ program->rewindMovie();
+}
+
+int
+Sprite::isSprite(void)
+{
+ return 1;
+}
+
+Program *
+Sprite::getProgram()
+{
+ return program;
+}
+
+int
+Sprite::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
+{
+ return program->dl->render(gd,matrix,cxform);
+}
+
+ActionRecord *
+Sprite::eventHandler(GraphicDevice *gd, FlashEvent *event)
+{
+#if 0
+ DisplayList *dl;
+ ActionRecord *actions;
+
+ dl = program->getDisplayList();
+ actions = dl->processEvent(gd, event);
+ if (actions) {
+ program->doAction(actions,0);
+ }
+ return actions;
+#endif
+ return NULL;
+}
+
+void
+Sprite::getBoundingBox(Rect *bb, DisplayListEntry *e)
+{
+ program->dl->getBoundary(bb);
+}
diff --git a/core/multimedia/opieplayer/libflash/sprite.h b/core/multimedia/opieplayer/libflash/sprite.h
new file mode 100644
index 0000000..2ea64bc
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/sprite.h
@@ -0,0 +1,38 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _SPRITE_H_
+#define _SPRITE_H_
+
+class Sprite : public Character {
+public:
+ Program *program;
+
+ Sprite(FlashMovie *movie, long id, long frameCount);
+ ~Sprite();
+ Program *getProgram();
+ int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform);
+ int hasEventHandler();
+ void reset();
+ ActionRecord *eventHandler(GraphicDevice *, FlashEvent *);
+ int isSprite(void);
+ void getBoundingBox(Rect *bb, DisplayListEntry *de);
+};
+
+#endif /* _SPRITE_H_ */
diff --git a/core/multimedia/opieplayer/libflash/sqrt.cc b/core/multimedia/opieplayer/libflash/sqrt.cc
new file mode 100644
index 0000000..0d8295e
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/sqrt.cc
@@ -0,0 +1,4099 @@
+unsigned char SQRT[] = {
+
+0,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,
+4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,
+5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,
+6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
+8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,
+10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,
+11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
+12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
+12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,
+13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
+13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,
+14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
+14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
+16,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
+17,17,17,17,18,18,18,18,18,18,18,18,18,18,18,18,
+18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,
+18,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,
+19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,
+20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
+20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
+20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
+21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,
+22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
+22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,
+22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
+23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
+23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,
+24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
+24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
+24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,
+24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,
+25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,
+26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,
+26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,
+26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,
+27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,
+27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,
+27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,
+28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
+28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
+28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,
+28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,
+29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
+29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
+29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
+29,29,29,29,30,30,30,30,30,30,30,30,30,30,30,30,
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
+30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,
+30,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
+32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,
+32,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
+33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
+33,33,33,33,34,34,34,34,34,34,34,34,34,34,34,34,
+34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,
+34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,
+34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,34,
+34,34,34,34,34,34,34,34,34,35,35,35,35,35,35,35,
+35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
+35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
+35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
+35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,35,
+36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
+36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
+36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
+36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
+36,36,36,36,36,36,36,36,36,37,37,37,37,37,37,37,
+37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
+37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
+37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
+37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,37,
+37,37,37,37,38,38,38,38,38,38,38,38,38,38,38,38,
+38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,
+38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,
+38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,
+38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,38,
+38,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
+39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
+39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
+39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
+39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
+40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
+40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
+40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
+40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
+40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,
+40,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
+41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
+41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
+41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
+41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,
+41,41,41,41,42,42,42,42,42,42,42,42,42,42,42,42,
+42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
+42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
+42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
+42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,
+42,42,42,42,42,42,42,42,42,43,43,43,43,43,43,43,
+43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,
+43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,
+43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,
+43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,
+43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,43,
+44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
+44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
+44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
+44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,
+44,44,44,44,44,44,44,44,44,44,44,44,44,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,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
+45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
+45,45,45,45,45,45,45,45,45,45,45,45,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,46,46,46,46,
+46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,
+46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,46,
+46,46,46,46,46,46,46,46,46,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,47,47,47,47,47,47,47,
+47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+47,47,47,47,47,47,47,47,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,48,48,48,48,48,48,48,48,
+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
+48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,
+48,48,48,48,48,48,48,48,48,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,49,49,49,49,49,49,49,
+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
+49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,
+49,49,49,49,50,50,50,50,50,50,50,50,50,50,50,50,
+50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,50,
+50,50,50,50,50,50,50,50,50,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,51,
+52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
+52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
+52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
+52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
+52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
+52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,52,
+52,52,52,52,52,52,52,52,52,53,53,53,53,53,53,53,
+53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
+53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
+53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
+53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
+53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
+53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,53,
+53,53,53,53,54,54,54,54,54,54,54,54,54,54,54,54,
+54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
+54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
+54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
+54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
+54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
+54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,54,
+54,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
+55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
+55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
+55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
+55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
+55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
+55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,
+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
+56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,56,
+56,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
+57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,57,
+57,57,57,57,58,58,58,58,58,58,58,58,58,58,58,58,
+58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
+58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
+58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
+58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
+58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
+58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,58,
+58,58,58,58,58,58,58,58,58,59,59,59,59,59,59,59,
+59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
+59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
+59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
+59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
+59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
+59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
+59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,59,
+60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
+60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
+60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
+60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
+60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
+60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
+60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,60,
+60,60,60,60,60,60,60,60,60,61,61,61,61,61,61,61,
+61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
+61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
+61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
+61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
+61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
+61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
+61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,61,
+61,61,61,61,62,62,62,62,62,62,62,62,62,62,62,62,
+62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
+62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
+62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
+62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
+62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
+62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
+62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,62,
+62,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
+63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
+63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
+63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
+63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
+63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
+63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
+63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,
+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,64,
+64,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
+65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,65,
+65,65,65,65,66,66,66,66,66,66,66,66,66,66,66,66,
+66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
+66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
+66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
+66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
+66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
+66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
+66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
+66,66,66,66,66,66,66,66,66,67,67,67,67,67,67,67,
+67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
+67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
+67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
+67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
+67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
+67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
+67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
+67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,67,
+68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
+68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
+68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
+68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
+68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
+68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
+68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
+68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,68,
+68,68,68,68,68,68,68,68,68,69,69,69,69,69,69,69,
+69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
+69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
+69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
+69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
+69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
+69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
+69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
+69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,
+69,69,69,69,70,70,70,70,70,70,70,70,70,70,70,70,
+70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
+70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
+70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
+70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
+70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
+70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
+70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
+70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,70,
+70,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
+71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
+71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
+71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
+71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
+71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
+71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
+71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
+71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,71,
+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
+72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
+72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
+73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,
+73,73,73,73,74,74,74,74,74,74,74,74,74,74,74,74,
+74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
+74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
+74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
+74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
+74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
+74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
+74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
+74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,
+74,74,74,74,74,74,74,74,74,75,75,75,75,75,75,75,
+75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
+75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
+75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
+75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
+75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
+75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
+75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
+75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
+75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,75,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,76,
+76,76,76,76,76,76,76,76,76,77,77,77,77,77,77,77,
+77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
+77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
+77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
+77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
+77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
+77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
+77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
+77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
+77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
+77,77,77,77,78,78,78,78,78,78,78,78,78,78,78,78,
+78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
+78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
+78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
+78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
+78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
+78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
+78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
+78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
+78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,78,
+78,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
+79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
+79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
+79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
+79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
+79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
+79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
+79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
+79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
+79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,79,
+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
+80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,
+80,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
+81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,
+81,81,81,81,82,82,82,82,82,82,82,82,82,82,82,82,
+82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
+82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
+82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
+82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
+82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
+82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
+82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
+82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
+82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,
+82,82,82,82,82,82,82,82,82,83,83,83,83,83,83,83,
+83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
+83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
+83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
+83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
+83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
+83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
+83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
+83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
+83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
+83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,
+84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
+84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
+84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
+84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
+84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
+84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
+84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
+84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
+84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
+84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,
+84,84,84,84,84,84,84,84,84,85,85,85,85,85,85,85,
+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
+85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,
+85,85,85,85,86,86,86,86,86,86,86,86,86,86,86,86,
+86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
+86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
+86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
+86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
+86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
+86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
+86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
+86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
+86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
+86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,
+86,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
+87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
+87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
+87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
+87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
+87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
+87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
+87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
+87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
+87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
+87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,
+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
+88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,
+88,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
+89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,
+89,89,89,89,90,90,90,90,90,90,90,90,90,90,90,90,
+90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
+90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
+90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
+90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
+90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
+90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
+90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
+90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
+90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
+90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,
+90,90,90,90,90,90,90,90,90,91,91,91,91,91,91,91,
+91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
+91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
+91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
+91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
+91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
+91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
+91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
+91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
+91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
+91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
+91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,
+92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
+92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
+92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
+92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
+92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
+92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
+92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
+92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
+92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
+92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
+92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,
+92,92,92,92,92,92,92,92,92,93,93,93,93,93,93,93,
+93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
+93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
+93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
+93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
+93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
+93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
+93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
+93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
+93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
+93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
+93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,93,
+93,93,93,93,94,94,94,94,94,94,94,94,94,94,94,94,
+94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
+94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
+94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
+94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
+94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
+94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
+94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
+94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
+94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
+94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
+94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,
+94,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
+95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
+95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
+95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
+95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
+95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
+95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
+95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
+95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
+95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
+95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
+95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,
+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
+96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,
+96,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
+97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,
+97,97,97,97,98,98,98,98,98,98,98,98,98,98,98,98,
+98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
+98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
+98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
+98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
+98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
+98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
+98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
+98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
+98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
+98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
+98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,
+98,98,98,98,98,98,98,98,98,99,99,99,99,99,99,99,
+99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
+99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
+99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
+99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
+99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
+99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
+99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
+99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
+99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
+99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
+99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
+99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
+100,100,100,100,100,100,100,100,100,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,
+101,101,101,101,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,
+102,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,
+104,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,105,
+105,105,105,105,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,
+106,106,106,106,106,106,106,106,106,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,
+108,108,108,108,108,108,108,108,108,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
+109,109,109,109,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+112,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,114,
+114,114,114,114,114,114,114,114,114,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,115,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,
+116,116,116,116,116,116,116,116,116,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,117,
+117,117,117,117,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,118,
+118,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,121,
+121,121,121,121,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,122,
+122,122,122,122,122,122,122,122,122,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,123,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,
+124,124,124,124,124,124,124,124,124,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,
+125,125,125,125,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,
+126,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,
+128,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,
+129,129,129,129,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,130,
+130,130,130,130,130,130,130,130,130,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,132,
+132,132,132,132,132,132,132,132,132,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,133,
+133,133,133,133,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,134,
+134,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,135,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,136,
+136,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,137,
+137,137,137,137,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,138,
+138,138,138,138,138,138,138,138,138,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,139,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,
+140,140,140,140,140,140,140,140,140,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,
+141,141,141,141,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,
+142,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,143,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,144,
+144,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,145,
+145,145,145,145,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,
+146,146,146,146,146,146,146,146,146,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,147,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,148,
+148,148,148,148,148,148,148,148,148,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,149,
+149,149,149,149,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,150,
+150,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,151,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,152,
+152,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+153,153,153,153,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,154,
+154,154,154,154,154,154,154,154,154,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,155,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,
+156,156,156,156,156,156,156,156,156,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,157,
+157,157,157,157,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,158,
+158,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,159,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,
+160,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,161,
+161,161,161,161,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,162,
+162,162,162,162,162,162,162,162,162,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,163,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,164,
+164,164,164,164,164,164,164,164,164,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,165,
+165,165,165,165,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,166,
+166,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,167,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,168,
+168,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,169,
+169,169,169,169,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,170,
+170,170,170,170,170,170,170,170,170,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,171,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,
+172,172,172,172,172,172,172,172,172,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,173,
+173,173,173,173,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,
+174,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+176,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,
+177,177,177,177,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,178,
+178,178,178,178,178,178,178,178,178,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,179,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,180,
+180,180,180,180,180,180,180,180,180,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,181,
+181,181,181,181,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+182,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,183,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,184,
+184,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,185,
+185,185,185,185,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,186,
+186,186,186,186,186,186,186,186,186,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,188,
+188,188,188,188,188,188,188,188,188,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,189,
+189,189,189,189,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
+190,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,192,
+192,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,
+193,193,193,193,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,194,
+194,194,194,194,194,194,194,194,194,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,195,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,196,
+196,196,196,196,196,196,196,196,196,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,
+197,197,197,197,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,198,
+198,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,199,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,
+200,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,
+201,201,201,201,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
+202,202,202,202,202,202,202,202,202,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,204,
+204,204,204,204,204,204,204,204,204,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,
+205,205,205,205,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+206,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,
+208,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,209,
+209,209,209,209,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,210,
+210,210,210,210,210,210,210,210,210,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,213,
+213,213,213,213,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
+214,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,216,
+216,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,
+217,217,217,217,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,218,
+218,218,218,218,218,218,218,218,218,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,219,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,220,
+220,220,220,220,220,220,220,220,220,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,221,
+221,221,221,221,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+222,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+224,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,226,
+226,226,226,226,226,226,226,226,226,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,228,
+228,228,228,228,228,228,228,228,228,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,229,
+229,229,229,229,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,
+230,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,231,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,232,
+232,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+233,233,233,233,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
+234,234,234,234,234,234,234,234,234,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,
+237,237,237,237,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
+238,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,
+240,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,241,
+241,241,241,241,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,
+242,242,242,242,242,242,242,242,242,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,243,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
+244,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,246,
+246,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
+248,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,
+250,250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,252,252,252,252,252,252,252,252,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+253,253,253,253,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
+};
diff --git a/core/multimedia/opieplayer/libflash/swf.h b/core/multimedia/opieplayer/libflash/swf.h
new file mode 100644
index 0000000..5f5e4f7
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/swf.h
@@ -0,0 +1,229 @@
+#ifndef _SWF_H_
+#define _SWF_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+#include <assert.h>
+#include <limits.h>
+
+#ifdef DUMP
+#include "bitstream.h"
+#endif
+
+#include "flash.h"
+
+extern int debug;
+
+// Global Types
+typedef unsigned long U32, *P_U32, **PP_U32;
+typedef signed long S32, *P_S32, **PP_S32;
+typedef unsigned short U16, *P_U16, **PP_U16;
+typedef signed short S16, *P_S16, **PP_S16;
+typedef unsigned char U8, *P_U8, **PP_U8;
+typedef signed char S8, *P_S8, **PP_S8;
+typedef signed long SFIXED, *P_SFIXED;
+typedef signed long SCOORD, *P_SCOORD;
+typedef unsigned long BOOL;
+
+#define ZOOM(v,f) ((v)/(f))
+
+#include "matrix.h"
+#include "cxform.h"
+#include "rect.h"
+
+#include <sys/time.h>
+#define ST struct timeval t1,t2;
+#define START gettimeofday(&t1,0)
+#define STOP(msg) gettimeofday(&t2,0); printf("%s Delta = %d ms\n", msg, (t2.tv_sec-t1.tv_sec)*1000+(t2.tv_usec-t1.tv_usec)/1000); fflush(stdout);
+
+// Start Sound Flags
+enum {
+ soundHasInPoint = 0x01,
+ soundHasOutPoint = 0x02,
+ soundHasLoops = 0x04,
+ soundHasEnvelope = 0x08
+
+ // the upper 4 bits are reserved for synchronization flags
+};
+
+// Flags for Sound Format
+enum SounfFlags {
+ soundIsStereo = 0x01,
+ soundIs16bit = 0x02,
+ soundIsADPCMCompressed = 0x10
+};
+
+// Flags for defining Button States
+enum ButtonState {
+ stateHitTest = 0x08,
+ stateDown = 0x04,
+ stateOver = 0x02,
+ stateUp = 0x01
+};
+
+// Actions
+enum Action {
+ // Internal actions
+ ActionRefresh = 0x00,
+ ActionPlaySound = 0x01,
+ // Normal actions
+ ActionGotoFrame = 0x81,
+ ActionGetURL = 0x83,
+ ActionNextFrame = 0x04,
+ ActionPrevFrame = 0x05,
+ ActionPlay = 0x06,
+ ActionStop = 0x07,
+ ActionToggleQuality = 0x08,
+ ActionStopSounds = 0x09,
+ ActionWaitForFrame = 0x8a,
+ ActionSetTarget = 0x8b,
+ ActionGoToLabel = 0x8c
+};
+
+class Sound;
+
+struct ActionRecord {
+ Action action;
+
+ // GotoFrame & WaitForFrame
+ long frameIndex;
+
+ // GetURL
+ char *url;
+ char *target;
+
+ // GotoLabel
+ char *frameLabel;
+
+ // WaitForFrame
+ long skipCount;
+
+ // Sound
+ Sound *sound;
+
+ struct ActionRecord *next;
+
+ ActionRecord() {
+ frameLabel = 0;
+ url = 0;
+ target = 0;
+ sound = 0;
+ };
+
+ ~ActionRecord() {
+ if (frameLabel) free(frameLabel);
+ if (url) free(url);
+ if (target) free(target);
+ };
+};
+
+enum FontFlags {
+ fontUnicode = 0x20,
+ fontShiftJIS = 0x10,
+ fontANSI = 0x08,
+ fontItalic = 0x04,
+ fontBold = 0x02,
+ fontWideCodes = 0x01
+};
+
+enum TextFlags {
+ isTextControl = 0x80,
+
+ textIsLarge = 0x70,
+ textHasFont = 0x08,
+ textHasColor = 0x04,
+ textHasYOffset= 0x02,
+ textHasXOffset= 0x01
+};
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+// Tag values that represent actions or data in a Flash script.
+enum
+{
+ stagEnd = 0,
+ stagShowFrame = 1,
+ stagDefineShape = 2,
+ stagFreeCharacter = 3,
+ stagPlaceObject = 4,
+ stagRemoveObject = 5,
+ stagDefineBits = 6,
+ stagDefineButton = 7,
+ stagJPEGTables = 8,
+ stagSetBackgroundColor = 9,
+ stagDefineFont = 10,
+ stagDefineText = 11,
+ stagDoAction = 12,
+ stagDefineFontInfo = 13,
+ stagDefineSound = 14, // Event sound tags.
+ stagStartSound = 15,
+ stagStopSound = 16,
+ stagDefineButtonSound = 17,
+ stagSoundStreamHead = 18,
+ stagSoundStreamBlock = 19,
+ stagDefineBitsLossless = 20, // A bitmap using lossless zlib compression.
+ stagDefineBitsJPEG2 = 21, // A bitmap using an internal JPEG compression table.
+ stagDefineShape2 = 22,
+ stagDefineButtonCxform = 23,
+ stagProtect = 24, // This file should not be importable for editing.
+
+ // These are the new tags for Flash 3.
+ stagPlaceObject2 = 26, // The new style place w/ alpha color transform and name.
+ stagRemoveObject2 = 28, // A more compact remove object that omits the character tag (just depth).
+ stagDefineShape3 = 32, // A shape V3 includes alpha values.
+ stagDefineText2 = 33, // A text V2 includes alpha values.
+ stagDefineButton2 = 34, // A button V2 includes color transform, alpha and multiple actions
+ stagDefineBitsJPEG3 = 35, // A JPEG bitmap with alpha info.
+ stagDefineBitsLossless2 = 36, // A lossless bitmap with alpha info.
+ stagDefineSprite = 39, // Define a sequence of tags that describe the behavior of a sprite.
+ stagNameCharacter = 40, // Name a character definition, character id and a string, (used for buttons, bitmaps, sprites and sounds).
+ stagFrameLabel = 43, // A string label for the current frame.
+ stagSoundStreamHead2 = 45, // For lossless streaming sound, should not have needed this...
+ stagDefineMorphShape = 46, // A morph shape definition
+ stagDefineFont2 = 48,
+
+ notEnoughData = 0xffff, // Special code
+};
+
+#ifndef false
+#define false 0
+#endif
+#ifndef true
+#define true 1
+#endif
+
+extern int shape_size,shape_nb,shaperecord_size,shaperecord_nb,style_size,style_nb;
+
+typedef void (*ScanLineFunc)(void *id, long y, long start, long end);
+
+class Bitmap;
+struct FlashMovie;
+
+extern "C" {
+#include "jpeglib.h"
+};
+extern "C" {
+//#include "zlib.h"
+#include "../src/3rdparty/zlib/zlib.h"
+};
+
+#include "graphic.h"
+#include "character.h"
+#include "bitmap.h"
+#include "shape.h"
+#include "displaylist.h"
+#include "sound.h"
+#include "button.h"
+#include "font.h"
+#include "text.h"
+#include "adpcm.h"
+#include "program.h"
+#include "sprite.h"
+#include "script.h"
+#include "movie.h"
+
+#endif /* _SWF_H_ */
diff --git a/core/multimedia/opieplayer/libflash/text.cc b/core/multimedia/opieplayer/libflash/text.cc
new file mode 100644
index 0000000..1b6cb5e
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/text.cc
@@ -0,0 +1,246 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+// Author : Olivier Debon <odebon@club-internet.fr>
+//
+
+#include "swf.h"
+
+#ifdef RCSID
+static char *rcsid = "$Id$";
+#endif
+
+Text::Text(long id) : Character(TextType, id)
+{
+ textRecords = 0;
+}
+
+Text::~Text()
+{
+ TextRecord *cur,*del;
+
+ for(cur = textRecords; cur;)
+ {
+ del = cur;
+ cur = cur->next;
+ delete del;
+ }
+}
+
+void
+Text::setTextBoundary(Rect rect)
+{
+ boundary = rect;
+}
+
+void
+Text::setTextMatrix(Matrix m)
+{
+ textMatrix = m;
+}
+
+void
+Text::addTextRecord(TextRecord *tr)
+{
+ SwfFont *font = 0;
+ long n;
+
+ tr->next = 0;
+
+ if (textRecords == 0) {
+ textRecords = tr;
+ font = tr->font;
+ } else {
+ TextRecord *current;
+ long fontHeight = 0;
+
+ for(current = textRecords; current->next; current = current->next) {
+ if (current->flags & textHasFont) {
+ font = current->font;
+ fontHeight = current->fontHeight;
+ }
+ }
+
+ current->next = tr;
+ if (current->flags & textHasFont) {
+ font = current->font;
+ fontHeight = current->fontHeight;
+ }
+
+ if (tr->flags & textHasFont) {
+ font = tr->font;
+ } else {
+ tr->font = font;
+ tr->fontHeight = fontHeight;
+ }
+ }
+
+ if (tr->nbGlyphs) {
+ for(n=0; n < tr->nbGlyphs; n++) {
+ tr->glyphs[n].code = font->getGlyphCode(tr->glyphs[n].index);
+ }
+ }
+}
+
+int
+Text::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
+{
+ return doText(gd, matrix, cxform, ShapeDraw, NULL, NULL);
+}
+
+void
+Text::getRegion(GraphicDevice *gd, Matrix *matrix,
+ void *id, ScanLineFunc scan_line_func)
+{
+ doText(gd, matrix, 0, ShapeGetRegion, id, scan_line_func);
+}
+
+void
+Text::getBoundingBox(Rect *bb, DisplayListEntry *e)
+{
+ *bb = boundary;
+}
+
+TextRecord *
+Text::getTextRecords()
+{
+ return textRecords;
+}
+
+int
+Text::doText(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ShapeAction action,
+ void *id, ScanLineFunc scan_line_func)
+{
+ TextRecord *tr;
+ long x,y; // Current position
+ SwfFont *font = 0; // Current font
+ long fontHeight;
+ Matrix tmat,fmat;
+ long g;
+
+ x = y = 0;
+ fontHeight = 0;
+
+ // Compute final text matrix
+ tmat = (*matrix) * textMatrix;
+
+ for(tr = textRecords; tr; tr = tr ->next)
+ {
+ if (tr->flags & isTextControl) {
+ if (tr->flags & textHasXOffset) {
+ x = tr->xOffset;
+ }
+ if (tr->flags & textHasYOffset) {
+ y = tr->yOffset;
+ }
+ if (tr->flags & textHasColor) {
+ if (action == ShapeDraw) {
+ if (cxform) {
+ gd->setForegroundColor(cxform->getColor(tr->color));
+ } else {
+ gd->setForegroundColor(tr->color);
+ }
+ }
+ }
+ }
+
+ font = tr->font;
+ fontHeight = tr->fontHeight;
+ // Update font matrix
+ fmat.a = fontHeight/1000.0;
+ fmat.d = fontHeight/1000.0;
+
+ assert(font != 0);
+ for (g = 0; g < tr->nbGlyphs; g++)
+ {
+ Shape *shape;
+ Matrix cmat;
+
+ shape = font->getGlyph( tr->glyphs[g].index );
+
+#ifdef PRINT
+ printf("%c", font->getGlyphCode(tr->glyphs[g].index));
+#endif
+
+ // Update font matrix
+ fmat.tx = x;
+ fmat.ty = y;
+
+ // Compute Character matrix
+ cmat = tmat * fmat;
+
+ if (action == ShapeDraw) {
+ shape->execute(gd, &cmat, cxform);
+ } else {
+ shape->getRegion(gd, &cmat, id, scan_line_func);
+ }
+
+ // Advance
+ x += tr->glyphs[g].xAdvance;
+ }
+#ifdef PRINT
+ printf("\n");
+#endif
+ }
+
+ if (gd->showMore) {
+ tmat = (*gd->adjust) * (*matrix);
+
+ long x1,x2,y1,y2;
+
+ x1 = boundary.xmin;
+ y1 = boundary.ymin;
+ x2 = boundary.xmax;
+ y2 = boundary.ymax;
+ gd->drawLine(tmat.getX(x1,y1),tmat.getY(x1,y1),tmat.getX(x2,y1),tmat.getY(x2,y1),FRAC);
+ gd->drawLine(tmat.getX(x2,y1),tmat.getY(x2,y1),tmat.getX(x2,y2),tmat.getY(x2,y2),FRAC);
+ gd->drawLine(tmat.getX(x2,y2),tmat.getY(x2,y2),tmat.getX(x1,y2),tmat.getY(x1,y2),FRAC);
+ gd->drawLine(tmat.getX(x1,y2),tmat.getY(x1,y2),tmat.getX(x1,y1),tmat.getY(x1,y1),FRAC);
+ }
+
+ return 0;
+}
+
+////////// TextRecord Methods
+TextRecord::TextRecord() {
+ flags = (TextFlags)0;
+ font = 0;
+ fontHeight = 0;
+ nbGlyphs = 0;
+ glyphs = 0;
+ xOffset = 0;
+ yOffset = 0;
+}
+
+TextRecord::~TextRecord() {
+ if (nbGlyphs) delete glyphs;
+}
+
+char *
+TextRecord::getText() {
+ static char text[256];
+ long g;
+
+ for(g=0; g < nbGlyphs; g++) {
+ text[g] = glyphs[g].code;
+ }
+ text[g] = 0;
+
+ return text;
+}
diff --git a/core/multimedia/opieplayer/libflash/text.h b/core/multimedia/opieplayer/libflash/text.h
new file mode 100644
index 0000000..1ba7b74
--- a/dev/null
+++ b/core/multimedia/opieplayer/libflash/text.h
@@ -0,0 +1,77 @@
+/////////////////////////////////////////////////////////////
+// Flash Plugin and Player
+// Copyright (C) 1998,1999 Olivier Debon
+//
+// 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.
+//
+///////////////////////////////////////////////////////////////
+#ifndef _TEXT_H_
+#define _TEXT_H_
+
+struct Glyph {
+ long index;
+ long xAdvance;
+ long code; // Ascii code
+};
+
+struct TextRecord {
+
+ // Normal text record
+ Glyph *glyphs;
+ long nbGlyphs;
+
+ // Control text record
+ TextFlags flags;
+ SwfFont *font;
+ long fontHeight;
+ Color color;
+ long xOffset;
+ long yOffset;
+
+ TextRecord *next;
+
+ TextRecord();
+ ~TextRecord();
+
+ char *getText();
+};
+
+class Text : public Character {
+
+ Rect boundary;
+ Matrix textMatrix;
+ TextRecord *textRecords; // List
+
+public:
+ Text(long id);
+ ~Text();
+
+ void setTextBoundary(Rect rect);
+ void setTextMatrix(Matrix m);
+ void addTextRecord(TextRecord *tr);
+ int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform);
+ void getRegion(GraphicDevice *gd, Matrix *matrix,
+ void *id, ScanLineFunc scan_line_func);
+ int doText(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ShapeAction action,
+ void *id, ScanLineFunc scan_line_func);
+ void getBoundingBox(Rect *bb, DisplayListEntry *e);
+ TextRecord *getTextRecords();
+
+#ifdef DUMP
+ void dump(BitStream *bs);
+#endif
+};
+
+#endif /* _TEXT_H_ */
diff --git a/core/multimedia/opieplayer/libmad/.cvsignore b/core/multimedia/opieplayer/libmad/.cvsignore
new file mode 100644
index 0000000..6fe2396
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/.cvsignore
@@ -0,0 +1,2 @@
+moc_*
+Makefile
diff --git a/core/multimedia/opieplayer/libmad/D.dat b/core/multimedia/opieplayer/libmad/D.dat
new file mode 100644
index 0000000..f33d30c
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/D.dat
@@ -0,0 +1,607 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+/*
+ * These are the coefficients for the subband synthesis window. This is a
+ * reordered version of Table B.3 from ISO/IEC 11172-3.
+ *
+ * Every value is parameterized so that shift optimizations can be made at
+ * compile-time. For example, every value can be right-shifted 12 bits to
+ * minimize multiply instruction times without any loss of accuracy.
+ */
+
+ { PRESHIFT(0x00000000) /* 0.000000000 */, /* 0 */
+ -PRESHIFT(0x0001d000) /* -0.000442505 */,
+ PRESHIFT(0x000d5000) /* 0.003250122 */,
+ -PRESHIFT(0x001cb000) /* -0.007003784 */,
+ PRESHIFT(0x007f5000) /* 0.031082153 */,
+ -PRESHIFT(0x01421000) /* -0.078628540 */,
+ PRESHIFT(0x019ae000) /* 0.100311279 */,
+ -PRESHIFT(0x09271000) /* -0.572036743 */,
+ PRESHIFT(0x1251e000) /* 1.144989014 */,
+ PRESHIFT(0x09271000) /* 0.572036743 */,
+ PRESHIFT(0x019ae000) /* 0.100311279 */,
+ PRESHIFT(0x01421000) /* 0.078628540 */,
+ PRESHIFT(0x007f5000) /* 0.031082153 */,
+ PRESHIFT(0x001cb000) /* 0.007003784 */,
+ PRESHIFT(0x000d5000) /* 0.003250122 */,
+ PRESHIFT(0x0001d000) /* 0.000442505 */,
+
+ PRESHIFT(0x00000000) /* 0.000000000 */,
+ -PRESHIFT(0x0001d000) /* -0.000442505 */,
+ PRESHIFT(0x000d5000) /* 0.003250122 */,
+ -PRESHIFT(0x001cb000) /* -0.007003784 */,
+ PRESHIFT(0x007f5000) /* 0.031082153 */,
+ -PRESHIFT(0x01421000) /* -0.078628540 */,
+ PRESHIFT(0x019ae000) /* 0.100311279 */,
+ -PRESHIFT(0x09271000) /* -0.572036743 */,
+ PRESHIFT(0x1251e000) /* 1.144989014 */,
+ PRESHIFT(0x09271000) /* 0.572036743 */,
+ PRESHIFT(0x019ae000) /* 0.100311279 */,
+ PRESHIFT(0x01421000) /* 0.078628540 */,
+ PRESHIFT(0x007f5000) /* 0.031082153 */,
+ PRESHIFT(0x001cb000) /* 0.007003784 */,
+ PRESHIFT(0x000d5000) /* 0.003250122 */,
+ PRESHIFT(0x0001d000) /* 0.000442505 */ },
+
+ { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 1 */
+ -PRESHIFT(0x0001f000) /* -0.000473022 */,
+ PRESHIFT(0x000da000) /* 0.003326416 */,
+ -PRESHIFT(0x00207000) /* -0.007919312 */,
+ PRESHIFT(0x007d0000) /* 0.030517578 */,
+ -PRESHIFT(0x0158d000) /* -0.084182739 */,
+ PRESHIFT(0x01747000) /* 0.090927124 */,
+ -PRESHIFT(0x099a8000) /* -0.600219727 */,
+ PRESHIFT(0x124f0000) /* 1.144287109 */,
+ PRESHIFT(0x08b38000) /* 0.543823242 */,
+ PRESHIFT(0x01bde000) /* 0.108856201 */,
+ PRESHIFT(0x012b4000) /* 0.073059082 */,
+ PRESHIFT(0x0080f000) /* 0.031478882 */,
+ PRESHIFT(0x00191000) /* 0.006118774 */,
+ PRESHIFT(0x000d0000) /* 0.003173828 */,
+ PRESHIFT(0x0001a000) /* 0.000396729 */,
+
+ -PRESHIFT(0x00001000) /* -0.000015259 */,
+ -PRESHIFT(0x0001f000) /* -0.000473022 */,
+ PRESHIFT(0x000da000) /* 0.003326416 */,
+ -PRESHIFT(0x00207000) /* -0.007919312 */,
+ PRESHIFT(0x007d0000) /* 0.030517578 */,
+ -PRESHIFT(0x0158d000) /* -0.084182739 */,
+ PRESHIFT(0x01747000) /* 0.090927124 */,
+ -PRESHIFT(0x099a8000) /* -0.600219727 */,
+ PRESHIFT(0x124f0000) /* 1.144287109 */,
+ PRESHIFT(0x08b38000) /* 0.543823242 */,
+ PRESHIFT(0x01bde000) /* 0.108856201 */,
+ PRESHIFT(0x012b4000) /* 0.073059082 */,
+ PRESHIFT(0x0080f000) /* 0.031478882 */,
+ PRESHIFT(0x00191000) /* 0.006118774 */,
+ PRESHIFT(0x000d0000) /* 0.003173828 */,
+ PRESHIFT(0x0001a000) /* 0.000396729 */ },
+
+ { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 2 */
+ -PRESHIFT(0x00023000) /* -0.000534058 */,
+ PRESHIFT(0x000de000) /* 0.003387451 */,
+ -PRESHIFT(0x00245000) /* -0.008865356 */,
+ PRESHIFT(0x007a0000) /* 0.029785156 */,
+ -PRESHIFT(0x016f7000) /* -0.089706421 */,
+ PRESHIFT(0x014a8000) /* 0.080688477 */,
+ -PRESHIFT(0x0a0d8000) /* -0.628295898 */,
+ PRESHIFT(0x12468000) /* 1.142211914 */,
+ PRESHIFT(0x083ff000) /* 0.515609741 */,
+ PRESHIFT(0x01dd8000) /* 0.116577148 */,
+ PRESHIFT(0x01149000) /* 0.067520142 */,
+ PRESHIFT(0x00820000) /* 0.031738281 */,
+ PRESHIFT(0x0015b000) /* 0.005294800 */,
+ PRESHIFT(0x000ca000) /* 0.003082275 */,
+ PRESHIFT(0x00018000) /* 0.000366211 */,
+
+ -PRESHIFT(0x00001000) /* -0.000015259 */,
+ -PRESHIFT(0x00023000) /* -0.000534058 */,
+ PRESHIFT(0x000de000) /* 0.003387451 */,
+ -PRESHIFT(0x00245000) /* -0.008865356 */,
+ PRESHIFT(0x007a0000) /* 0.029785156 */,
+ -PRESHIFT(0x016f7000) /* -0.089706421 */,
+ PRESHIFT(0x014a8000) /* 0.080688477 */,
+ -PRESHIFT(0x0a0d8000) /* -0.628295898 */,
+ PRESHIFT(0x12468000) /* 1.142211914 */,
+ PRESHIFT(0x083ff000) /* 0.515609741 */,
+ PRESHIFT(0x01dd8000) /* 0.116577148 */,
+ PRESHIFT(0x01149000) /* 0.067520142 */,
+ PRESHIFT(0x00820000) /* 0.031738281 */,
+ PRESHIFT(0x0015b000) /* 0.005294800 */,
+ PRESHIFT(0x000ca000) /* 0.003082275 */,
+ PRESHIFT(0x00018000) /* 0.000366211 */ },
+
+ { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 3 */
+ -PRESHIFT(0x00026000) /* -0.000579834 */,
+ PRESHIFT(0x000e1000) /* 0.003433228 */,
+ -PRESHIFT(0x00285000) /* -0.009841919 */,
+ PRESHIFT(0x00765000) /* 0.028884888 */,
+ -PRESHIFT(0x0185d000) /* -0.095169067 */,
+ PRESHIFT(0x011d1000) /* 0.069595337 */,
+ -PRESHIFT(0x0a7fe000) /* -0.656219482 */,
+ PRESHIFT(0x12386000) /* 1.138763428 */,
+ PRESHIFT(0x07ccb000) /* 0.487472534 */,
+ PRESHIFT(0x01f9c000) /* 0.123474121 */,
+ PRESHIFT(0x00fdf000) /* 0.061996460 */,
+ PRESHIFT(0x00827000) /* 0.031845093 */,
+ PRESHIFT(0x00126000) /* 0.004486084 */,
+ PRESHIFT(0x000c4000) /* 0.002990723 */,
+ PRESHIFT(0x00015000) /* 0.000320435 */,
+
+ -PRESHIFT(0x00001000) /* -0.000015259 */,
+ -PRESHIFT(0x00026000) /* -0.000579834 */,
+ PRESHIFT(0x000e1000) /* 0.003433228 */,
+ -PRESHIFT(0x00285000) /* -0.009841919 */,
+ PRESHIFT(0x00765000) /* 0.028884888 */,
+ -PRESHIFT(0x0185d000) /* -0.095169067 */,
+ PRESHIFT(0x011d1000) /* 0.069595337 */,
+ -PRESHIFT(0x0a7fe000) /* -0.656219482 */,
+ PRESHIFT(0x12386000) /* 1.138763428 */,
+ PRESHIFT(0x07ccb000) /* 0.487472534 */,
+ PRESHIFT(0x01f9c000) /* 0.123474121 */,
+ PRESHIFT(0x00fdf000) /* 0.061996460 */,
+ PRESHIFT(0x00827000) /* 0.031845093 */,
+ PRESHIFT(0x00126000) /* 0.004486084 */,
+ PRESHIFT(0x000c4000) /* 0.002990723 */,
+ PRESHIFT(0x00015000) /* 0.000320435 */ },
+
+ { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 4 */
+ -PRESHIFT(0x00029000) /* -0.000625610 */,
+ PRESHIFT(0x000e3000) /* 0.003463745 */,
+ -PRESHIFT(0x002c7000) /* -0.010848999 */,
+ PRESHIFT(0x0071e000) /* 0.027801514 */,
+ -PRESHIFT(0x019bd000) /* -0.100540161 */,
+ PRESHIFT(0x00ec0000) /* 0.057617187 */,
+ -PRESHIFT(0x0af15000) /* -0.683914185 */,
+ PRESHIFT(0x12249000) /* 1.133926392 */,
+ PRESHIFT(0x075a0000) /* 0.459472656 */,
+ PRESHIFT(0x0212c000) /* 0.129577637 */,
+ PRESHIFT(0x00e79000) /* 0.056533813 */,
+ PRESHIFT(0x00825000) /* 0.031814575 */,
+ PRESHIFT(0x000f4000) /* 0.003723145 */,
+ PRESHIFT(0x000be000) /* 0.002899170 */,
+ PRESHIFT(0x00013000) /* 0.000289917 */,
+
+ -PRESHIFT(0x00001000) /* -0.000015259 */,
+ -PRESHIFT(0x00029000) /* -0.000625610 */,
+ PRESHIFT(0x000e3000) /* 0.003463745 */,
+ -PRESHIFT(0x002c7000) /* -0.010848999 */,
+ PRESHIFT(0x0071e000) /* 0.027801514 */,
+ -PRESHIFT(0x019bd000) /* -0.100540161 */,
+ PRESHIFT(0x00ec0000) /* 0.057617187 */,
+ -PRESHIFT(0x0af15000) /* -0.683914185 */,
+ PRESHIFT(0x12249000) /* 1.133926392 */,
+ PRESHIFT(0x075a0000) /* 0.459472656 */,
+ PRESHIFT(0x0212c000) /* 0.129577637 */,
+ PRESHIFT(0x00e79000) /* 0.056533813 */,
+ PRESHIFT(0x00825000) /* 0.031814575 */,
+ PRESHIFT(0x000f4000) /* 0.003723145 */,
+ PRESHIFT(0x000be000) /* 0.002899170 */,
+ PRESHIFT(0x00013000) /* 0.000289917 */ },
+
+ { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 5 */
+ -PRESHIFT(0x0002d000) /* -0.000686646 */,
+ PRESHIFT(0x000e4000) /* 0.003479004 */,
+ -PRESHIFT(0x0030b000) /* -0.011886597 */,
+ PRESHIFT(0x006cb000) /* 0.026535034 */,
+ -PRESHIFT(0x01b17000) /* -0.105819702 */,
+ PRESHIFT(0x00b77000) /* 0.044784546 */,
+ -PRESHIFT(0x0b619000) /* -0.711318970 */,
+ PRESHIFT(0x120b4000) /* 1.127746582 */,
+ PRESHIFT(0x06e81000) /* 0.431655884 */,
+ PRESHIFT(0x02288000) /* 0.134887695 */,
+ PRESHIFT(0x00d17000) /* 0.051132202 */,
+ PRESHIFT(0x0081b000) /* 0.031661987 */,
+ PRESHIFT(0x000c5000) /* 0.003005981 */,
+ PRESHIFT(0x000b7000) /* 0.002792358 */,
+ PRESHIFT(0x00011000) /* 0.000259399 */,
+
+ -PRESHIFT(0x00001000) /* -0.000015259 */,
+ -PRESHIFT(0x0002d000) /* -0.000686646 */,
+ PRESHIFT(0x000e4000) /* 0.003479004 */,
+ -PRESHIFT(0x0030b000) /* -0.011886597 */,
+ PRESHIFT(0x006cb000) /* 0.026535034 */,
+ -PRESHIFT(0x01b17000) /* -0.105819702 */,
+ PRESHIFT(0x00b77000) /* 0.044784546 */,
+ -PRESHIFT(0x0b619000) /* -0.711318970 */,
+ PRESHIFT(0x120b4000) /* 1.127746582 */,
+ PRESHIFT(0x06e81000) /* 0.431655884 */,
+ PRESHIFT(0x02288000) /* 0.134887695 */,
+ PRESHIFT(0x00d17000) /* 0.051132202 */,
+ PRESHIFT(0x0081b000) /* 0.031661987 */,
+ PRESHIFT(0x000c5000) /* 0.003005981 */,
+ PRESHIFT(0x000b7000) /* 0.002792358 */,
+ PRESHIFT(0x00011000) /* 0.000259399 */ },
+
+ { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 6 */
+ -PRESHIFT(0x00031000) /* -0.000747681 */,
+ PRESHIFT(0x000e4000) /* 0.003479004 */,
+ -PRESHIFT(0x00350000) /* -0.012939453 */,
+ PRESHIFT(0x0066c000) /* 0.025085449 */,
+ -PRESHIFT(0x01c67000) /* -0.110946655 */,
+ PRESHIFT(0x007f5000) /* 0.031082153 */,
+ -PRESHIFT(0x0bd06000) /* -0.738372803 */,
+ PRESHIFT(0x11ec7000) /* 1.120223999 */,
+ PRESHIFT(0x06772000) /* 0.404083252 */,
+ PRESHIFT(0x023b3000) /* 0.139450073 */,
+ PRESHIFT(0x00bbc000) /* 0.045837402 */,
+ PRESHIFT(0x00809000) /* 0.031387329 */,
+ PRESHIFT(0x00099000) /* 0.002334595 */,
+ PRESHIFT(0x000b0000) /* 0.002685547 */,
+ PRESHIFT(0x00010000) /* 0.000244141 */,
+
+ -PRESHIFT(0x00001000) /* -0.000015259 */,
+ -PRESHIFT(0x00031000) /* -0.000747681 */,
+ PRESHIFT(0x000e4000) /* 0.003479004 */,
+ -PRESHIFT(0x00350000) /* -0.012939453 */,
+ PRESHIFT(0x0066c000) /* 0.025085449 */,
+ -PRESHIFT(0x01c67000) /* -0.110946655 */,
+ PRESHIFT(0x007f5000) /* 0.031082153 */,
+ -PRESHIFT(0x0bd06000) /* -0.738372803 */,
+ PRESHIFT(0x11ec7000) /* 1.120223999 */,
+ PRESHIFT(0x06772000) /* 0.404083252 */,
+ PRESHIFT(0x023b3000) /* 0.139450073 */,
+ PRESHIFT(0x00bbc000) /* 0.045837402 */,
+ PRESHIFT(0x00809000) /* 0.031387329 */,
+ PRESHIFT(0x00099000) /* 0.002334595 */,
+ PRESHIFT(0x000b0000) /* 0.002685547 */,
+ PRESHIFT(0x00010000) /* 0.000244141 */ },
+
+ { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 7 */
+ -PRESHIFT(0x00035000) /* -0.000808716 */,
+ PRESHIFT(0x000e3000) /* 0.003463745 */,
+ -PRESHIFT(0x00397000) /* -0.014022827 */,
+ PRESHIFT(0x005ff000) /* 0.023422241 */,
+ -PRESHIFT(0x01dad000) /* -0.115921021 */,
+ PRESHIFT(0x0043a000) /* 0.016510010 */,
+ -PRESHIFT(0x0c3d9000) /* -0.765029907 */,
+ PRESHIFT(0x11c83000) /* 1.111373901 */,
+ PRESHIFT(0x06076000) /* 0.376800537 */,
+ PRESHIFT(0x024ad000) /* 0.143264771 */,
+ PRESHIFT(0x00a67000) /* 0.040634155 */,
+ PRESHIFT(0x007f0000) /* 0.031005859 */,
+ PRESHIFT(0x0006f000) /* 0.001693726 */,
+ PRESHIFT(0x000a9000) /* 0.002578735 */,
+ PRESHIFT(0x0000e000) /* 0.000213623 */,
+
+ -PRESHIFT(0x00002000) /* -0.000030518 */,
+ -PRESHIFT(0x00035000) /* -0.000808716 */,
+ PRESHIFT(0x000e3000) /* 0.003463745 */,
+ -PRESHIFT(0x00397000) /* -0.014022827 */,
+ PRESHIFT(0x005ff000) /* 0.023422241 */,
+ -PRESHIFT(0x01dad000) /* -0.115921021 */,
+ PRESHIFT(0x0043a000) /* 0.016510010 */,
+ -PRESHIFT(0x0c3d9000) /* -0.765029907 */,
+ PRESHIFT(0x11c83000) /* 1.111373901 */,
+ PRESHIFT(0x06076000) /* 0.376800537 */,
+ PRESHIFT(0x024ad000) /* 0.143264771 */,
+ PRESHIFT(0x00a67000) /* 0.040634155 */,
+ PRESHIFT(0x007f0000) /* 0.031005859 */,
+ PRESHIFT(0x0006f000) /* 0.001693726 */,
+ PRESHIFT(0x000a9000) /* 0.002578735 */,
+ PRESHIFT(0x0000e000) /* 0.000213623 */ },
+
+ { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 8 */
+ -PRESHIFT(0x0003a000) /* -0.000885010 */,
+ PRESHIFT(0x000e0000) /* 0.003417969 */,
+ -PRESHIFT(0x003df000) /* -0.015121460 */,
+ PRESHIFT(0x00586000) /* 0.021575928 */,
+ -PRESHIFT(0x01ee6000) /* -0.120697021 */,
+ PRESHIFT(0x00046000) /* 0.001068115 */,
+ -PRESHIFT(0x0ca8d000) /* -0.791213989 */,
+ PRESHIFT(0x119e9000) /* 1.101211548 */,
+ PRESHIFT(0x05991000) /* 0.349868774 */,
+ PRESHIFT(0x02578000) /* 0.146362305 */,
+ PRESHIFT(0x0091a000) /* 0.035552979 */,
+ PRESHIFT(0x007d1000) /* 0.030532837 */,
+ PRESHIFT(0x00048000) /* 0.001098633 */,
+ PRESHIFT(0x000a1000) /* 0.002456665 */,
+ PRESHIFT(0x0000d000) /* 0.000198364 */,
+
+ -PRESHIFT(0x00002000) /* -0.000030518 */,
+ -PRESHIFT(0x0003a000) /* -0.000885010 */,
+ PRESHIFT(0x000e0000) /* 0.003417969 */,
+ -PRESHIFT(0x003df000) /* -0.015121460 */,
+ PRESHIFT(0x00586000) /* 0.021575928 */,
+ -PRESHIFT(0x01ee6000) /* -0.120697021 */,
+ PRESHIFT(0x00046000) /* 0.001068115 */,
+ -PRESHIFT(0x0ca8d000) /* -0.791213989 */,
+ PRESHIFT(0x119e9000) /* 1.101211548 */,
+ PRESHIFT(0x05991000) /* 0.349868774 */,
+ PRESHIFT(0x02578000) /* 0.146362305 */,
+ PRESHIFT(0x0091a000) /* 0.035552979 */,
+ PRESHIFT(0x007d1000) /* 0.030532837 */,
+ PRESHIFT(0x00048000) /* 0.001098633 */,
+ PRESHIFT(0x000a1000) /* 0.002456665 */,
+ PRESHIFT(0x0000d000) /* 0.000198364 */ },
+
+ { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 9 */
+ -PRESHIFT(0x0003f000) /* -0.000961304 */,
+ PRESHIFT(0x000dd000) /* 0.003372192 */,
+ -PRESHIFT(0x00428000) /* -0.016235352 */,
+ PRESHIFT(0x00500000) /* 0.019531250 */,
+ -PRESHIFT(0x02011000) /* -0.125259399 */,
+ -PRESHIFT(0x003e6000) /* -0.015228271 */,
+ -PRESHIFT(0x0d11e000) /* -0.816864014 */,
+ PRESHIFT(0x116fc000) /* 1.089782715 */,
+ PRESHIFT(0x052c5000) /* 0.323318481 */,
+ PRESHIFT(0x02616000) /* 0.148773193 */,
+ PRESHIFT(0x007d6000) /* 0.030609131 */,
+ PRESHIFT(0x007aa000) /* 0.029937744 */,
+ PRESHIFT(0x00024000) /* 0.000549316 */,
+ PRESHIFT(0x0009a000) /* 0.002349854 */,
+ PRESHIFT(0x0000b000) /* 0.000167847 */,
+
+ -PRESHIFT(0x00002000) /* -0.000030518 */,
+ -PRESHIFT(0x0003f000) /* -0.000961304 */,
+ PRESHIFT(0x000dd000) /* 0.003372192 */,
+ -PRESHIFT(0x00428000) /* -0.016235352 */,
+ PRESHIFT(0x00500000) /* 0.019531250 */,
+ -PRESHIFT(0x02011000) /* -0.125259399 */,
+ -PRESHIFT(0x003e6000) /* -0.015228271 */,
+ -PRESHIFT(0x0d11e000) /* -0.816864014 */,
+ PRESHIFT(0x116fc000) /* 1.089782715 */,
+ PRESHIFT(0x052c5000) /* 0.323318481 */,
+ PRESHIFT(0x02616000) /* 0.148773193 */,
+ PRESHIFT(0x007d6000) /* 0.030609131 */,
+ PRESHIFT(0x007aa000) /* 0.029937744 */,
+ PRESHIFT(0x00024000) /* 0.000549316 */,
+ PRESHIFT(0x0009a000) /* 0.002349854 */,
+ PRESHIFT(0x0000b000) /* 0.000167847 */ },
+
+ { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 10 */
+ -PRESHIFT(0x00044000) /* -0.001037598 */,
+ PRESHIFT(0x000d7000) /* 0.003280640 */,
+ -PRESHIFT(0x00471000) /* -0.017349243 */,
+ PRESHIFT(0x0046b000) /* 0.017257690 */,
+ -PRESHIFT(0x0212b000) /* -0.129562378 */,
+ -PRESHIFT(0x0084a000) /* -0.032379150 */,
+ -PRESHIFT(0x0d78a000) /* -0.841949463 */,
+ PRESHIFT(0x113be000) /* 1.077117920 */,
+ PRESHIFT(0x04c16000) /* 0.297210693 */,
+ PRESHIFT(0x02687000) /* 0.150497437 */,
+ PRESHIFT(0x0069c000) /* 0.025817871 */,
+ PRESHIFT(0x0077f000) /* 0.029281616 */,
+ PRESHIFT(0x00002000) /* 0.000030518 */,
+ PRESHIFT(0x00093000) /* 0.002243042 */,
+ PRESHIFT(0x0000a000) /* 0.000152588 */,
+
+ -PRESHIFT(0x00002000) /* -0.000030518 */,
+ -PRESHIFT(0x00044000) /* -0.001037598 */,
+ PRESHIFT(0x000d7000) /* 0.003280640 */,
+ -PRESHIFT(0x00471000) /* -0.017349243 */,
+ PRESHIFT(0x0046b000) /* 0.017257690 */,
+ -PRESHIFT(0x0212b000) /* -0.129562378 */,
+ -PRESHIFT(0x0084a000) /* -0.032379150 */,
+ -PRESHIFT(0x0d78a000) /* -0.841949463 */,
+ PRESHIFT(0x113be000) /* 1.077117920 */,
+ PRESHIFT(0x04c16000) /* 0.297210693 */,
+ PRESHIFT(0x02687000) /* 0.150497437 */,
+ PRESHIFT(0x0069c000) /* 0.025817871 */,
+ PRESHIFT(0x0077f000) /* 0.029281616 */,
+ PRESHIFT(0x00002000) /* 0.000030518 */,
+ PRESHIFT(0x00093000) /* 0.002243042 */,
+ PRESHIFT(0x0000a000) /* 0.000152588 */ },
+
+ { -PRESHIFT(0x00003000) /* -0.000045776 */, /* 11 */
+ -PRESHIFT(0x00049000) /* -0.001113892 */,
+ PRESHIFT(0x000d0000) /* 0.003173828 */,
+ -PRESHIFT(0x004ba000) /* -0.018463135 */,
+ PRESHIFT(0x003ca000) /* 0.014801025 */,
+ -PRESHIFT(0x02233000) /* -0.133590698 */,
+ -PRESHIFT(0x00ce4000) /* -0.050354004 */,
+ -PRESHIFT(0x0ddca000) /* -0.866363525 */,
+ PRESHIFT(0x1102f000) /* 1.063217163 */,
+ PRESHIFT(0x04587000) /* 0.271591187 */,
+ PRESHIFT(0x026cf000) /* 0.151596069 */,
+ PRESHIFT(0x0056c000) /* 0.021179199 */,
+ PRESHIFT(0x0074e000) /* 0.028533936 */,
+ -PRESHIFT(0x0001d000) /* -0.000442505 */,
+ PRESHIFT(0x0008b000) /* 0.002120972 */,
+ PRESHIFT(0x00009000) /* 0.000137329 */,
+
+ -PRESHIFT(0x00003000) /* -0.000045776 */,
+ -PRESHIFT(0x00049000) /* -0.001113892 */,
+ PRESHIFT(0x000d0000) /* 0.003173828 */,
+ -PRESHIFT(0x004ba000) /* -0.018463135 */,
+ PRESHIFT(0x003ca000) /* 0.014801025 */,
+ -PRESHIFT(0x02233000) /* -0.133590698 */,
+ -PRESHIFT(0x00ce4000) /* -0.050354004 */,
+ -PRESHIFT(0x0ddca000) /* -0.866363525 */,
+ PRESHIFT(0x1102f000) /* 1.063217163 */,
+ PRESHIFT(0x04587000) /* 0.271591187 */,
+ PRESHIFT(0x026cf000) /* 0.151596069 */,
+ PRESHIFT(0x0056c000) /* 0.021179199 */,
+ PRESHIFT(0x0074e000) /* 0.028533936 */,
+ -PRESHIFT(0x0001d000) /* -0.000442505 */,
+ PRESHIFT(0x0008b000) /* 0.002120972 */,
+ PRESHIFT(0x00009000) /* 0.000137329 */ },
+
+ { -PRESHIFT(0x00003000) /* -0.000045776 */, /* 12 */
+ -PRESHIFT(0x0004f000) /* -0.001205444 */,
+ PRESHIFT(0x000c8000) /* 0.003051758 */,
+ -PRESHIFT(0x00503000) /* -0.019577026 */,
+ PRESHIFT(0x0031a000) /* 0.012115479 */,
+ -PRESHIFT(0x02326000) /* -0.137298584 */,
+ -PRESHIFT(0x011b5000) /* -0.069168091 */,
+ -PRESHIFT(0x0e3dd000) /* -0.890090942 */,
+ PRESHIFT(0x10c54000) /* 1.048156738 */,
+ PRESHIFT(0x03f1b000) /* 0.246505737 */,
+ PRESHIFT(0x026ee000) /* 0.152069092 */,
+ PRESHIFT(0x00447000) /* 0.016708374 */,
+ PRESHIFT(0x00719000) /* 0.027725220 */,
+ -PRESHIFT(0x00039000) /* -0.000869751 */,
+ PRESHIFT(0x00084000) /* 0.002014160 */,
+ PRESHIFT(0x00008000) /* 0.000122070 */,
+
+ -PRESHIFT(0x00003000) /* -0.000045776 */,
+ -PRESHIFT(0x0004f000) /* -0.001205444 */,
+ PRESHIFT(0x000c8000) /* 0.003051758 */,
+ -PRESHIFT(0x00503000) /* -0.019577026 */,
+ PRESHIFT(0x0031a000) /* 0.012115479 */,
+ -PRESHIFT(0x02326000) /* -0.137298584 */,
+ -PRESHIFT(0x011b5000) /* -0.069168091 */,
+ -PRESHIFT(0x0e3dd000) /* -0.890090942 */,
+ PRESHIFT(0x10c54000) /* 1.048156738 */,
+ PRESHIFT(0x03f1b000) /* 0.246505737 */,
+ PRESHIFT(0x026ee000) /* 0.152069092 */,
+ PRESHIFT(0x00447000) /* 0.016708374 */,
+ PRESHIFT(0x00719000) /* 0.027725220 */,
+ -PRESHIFT(0x00039000) /* -0.000869751 */,
+ PRESHIFT(0x00084000) /* 0.002014160 */,
+ PRESHIFT(0x00008000) /* 0.000122070 */ },
+
+ { -PRESHIFT(0x00004000) /* -0.000061035 */, /* 13 */
+ -PRESHIFT(0x00055000) /* -0.001296997 */,
+ PRESHIFT(0x000bd000) /* 0.002883911 */,
+ -PRESHIFT(0x0054c000) /* -0.020690918 */,
+ PRESHIFT(0x0025d000) /* 0.009231567 */,
+ -PRESHIFT(0x02403000) /* -0.140670776 */,
+ -PRESHIFT(0x016ba000) /* -0.088775635 */,
+ -PRESHIFT(0x0e9be000) /* -0.913055420 */,
+ PRESHIFT(0x1082d000) /* 1.031936646 */,
+ PRESHIFT(0x038d4000) /* 0.221984863 */,
+ PRESHIFT(0x026e7000) /* 0.151962280 */,
+ PRESHIFT(0x0032e000) /* 0.012420654 */,
+ PRESHIFT(0x006df000) /* 0.026840210 */,
+ -PRESHIFT(0x00053000) /* -0.001266479 */,
+ PRESHIFT(0x0007d000) /* 0.001907349 */,
+ PRESHIFT(0x00007000) /* 0.000106812 */,
+
+ -PRESHIFT(0x00004000) /* -0.000061035 */,
+ -PRESHIFT(0x00055000) /* -0.001296997 */,
+ PRESHIFT(0x000bd000) /* 0.002883911 */,
+ -PRESHIFT(0x0054c000) /* -0.020690918 */,
+ PRESHIFT(0x0025d000) /* 0.009231567 */,
+ -PRESHIFT(0x02403000) /* -0.140670776 */,
+ -PRESHIFT(0x016ba000) /* -0.088775635 */,
+ -PRESHIFT(0x0e9be000) /* -0.913055420 */,
+ PRESHIFT(0x1082d000) /* 1.031936646 */,
+ PRESHIFT(0x038d4000) /* 0.221984863 */,
+ PRESHIFT(0x026e7000) /* 0.151962280 */,
+ PRESHIFT(0x0032e000) /* 0.012420654 */,
+ PRESHIFT(0x006df000) /* 0.026840210 */,
+ -PRESHIFT(0x00053000) /* -0.001266479 */,
+ PRESHIFT(0x0007d000) /* 0.001907349 */,
+ PRESHIFT(0x00007000) /* 0.000106812 */ },
+
+ { -PRESHIFT(0x00004000) /* -0.000061035 */, /* 14 */
+ -PRESHIFT(0x0005b000) /* -0.001388550 */,
+ PRESHIFT(0x000b1000) /* 0.002700806 */,
+ -PRESHIFT(0x00594000) /* -0.021789551 */,
+ PRESHIFT(0x00192000) /* 0.006134033 */,
+ -PRESHIFT(0x024c8000) /* -0.143676758 */,
+ -PRESHIFT(0x01bf2000) /* -0.109161377 */,
+ -PRESHIFT(0x0ef69000) /* -0.935195923 */,
+ PRESHIFT(0x103be000) /* 1.014617920 */,
+ PRESHIFT(0x032b4000) /* 0.198059082 */,
+ PRESHIFT(0x026bc000) /* 0.151306152 */,
+ PRESHIFT(0x00221000) /* 0.008316040 */,
+ PRESHIFT(0x006a2000) /* 0.025909424 */,
+ -PRESHIFT(0x0006a000) /* -0.001617432 */,
+ PRESHIFT(0x00075000) /* 0.001785278 */,
+ PRESHIFT(0x00007000) /* 0.000106812 */,
+
+ -PRESHIFT(0x00004000) /* -0.000061035 */,
+ -PRESHIFT(0x0005b000) /* -0.001388550 */,
+ PRESHIFT(0x000b1000) /* 0.002700806 */,
+ -PRESHIFT(0x00594000) /* -0.021789551 */,
+ PRESHIFT(0x00192000) /* 0.006134033 */,
+ -PRESHIFT(0x024c8000) /* -0.143676758 */,
+ -PRESHIFT(0x01bf2000) /* -0.109161377 */,
+ -PRESHIFT(0x0ef69000) /* -0.935195923 */,
+ PRESHIFT(0x103be000) /* 1.014617920 */,
+ PRESHIFT(0x032b4000) /* 0.198059082 */,
+ PRESHIFT(0x026bc000) /* 0.151306152 */,
+ PRESHIFT(0x00221000) /* 0.008316040 */,
+ PRESHIFT(0x006a2000) /* 0.025909424 */,
+ -PRESHIFT(0x0006a000) /* -0.001617432 */,
+ PRESHIFT(0x00075000) /* 0.001785278 */,
+ PRESHIFT(0x00007000) /* 0.000106812 */ },
+
+ { -PRESHIFT(0x00005000) /* -0.000076294 */, /* 15 */
+ -PRESHIFT(0x00061000) /* -0.001480103 */,
+ PRESHIFT(0x000a3000) /* 0.002487183 */,
+ -PRESHIFT(0x005da000) /* -0.022857666 */,
+ PRESHIFT(0x000b9000) /* 0.002822876 */,
+ -PRESHIFT(0x02571000) /* -0.146255493 */,
+ -PRESHIFT(0x0215c000) /* -0.130310059 */,
+ -PRESHIFT(0x0f4dc000) /* -0.956481934 */,
+ PRESHIFT(0x0ff0a000) /* 0.996246338 */,
+ PRESHIFT(0x02cbf000) /* 0.174789429 */,
+ PRESHIFT(0x0266e000) /* 0.150115967 */,
+ PRESHIFT(0x00120000) /* 0.004394531 */,
+ PRESHIFT(0x00662000) /* 0.024932861 */,
+ -PRESHIFT(0x0007f000) /* -0.001937866 */,
+ PRESHIFT(0x0006f000) /* 0.001693726 */,
+ PRESHIFT(0x00006000) /* 0.000091553 */,
+
+ -PRESHIFT(0x00005000) /* -0.000076294 */,
+ -PRESHIFT(0x00061000) /* -0.001480103 */,
+ PRESHIFT(0x000a3000) /* 0.002487183 */,
+ -PRESHIFT(0x005da000) /* -0.022857666 */,
+ PRESHIFT(0x000b9000) /* 0.002822876 */,
+ -PRESHIFT(0x02571000) /* -0.146255493 */,
+ -PRESHIFT(0x0215c000) /* -0.130310059 */,
+ -PRESHIFT(0x0f4dc000) /* -0.956481934 */,
+ PRESHIFT(0x0ff0a000) /* 0.996246338 */,
+ PRESHIFT(0x02cbf000) /* 0.174789429 */,
+ PRESHIFT(0x0266e000) /* 0.150115967 */,
+ PRESHIFT(0x00120000) /* 0.004394531 */,
+ PRESHIFT(0x00662000) /* 0.024932861 */,
+ -PRESHIFT(0x0007f000) /* -0.001937866 */,
+ PRESHIFT(0x0006f000) /* 0.001693726 */,
+ PRESHIFT(0x00006000) /* 0.000091553 */ },
+
+ { -PRESHIFT(0x00005000) /* -0.000076294 */, /* 16 */
+ -PRESHIFT(0x00068000) /* -0.001586914 */,
+ PRESHIFT(0x00092000) /* 0.002227783 */,
+ -PRESHIFT(0x0061f000) /* -0.023910522 */,
+ -PRESHIFT(0x0002d000) /* -0.000686646 */,
+ -PRESHIFT(0x025ff000) /* -0.148422241 */,
+ -PRESHIFT(0x026f7000) /* -0.152206421 */,
+ -PRESHIFT(0x0fa13000) /* -0.976852417 */,
+ PRESHIFT(0x0fa13000) /* 0.976852417 */,
+ PRESHIFT(0x026f7000) /* 0.152206421 */,
+ PRESHIFT(0x025ff000) /* 0.148422241 */,
+ PRESHIFT(0x0002d000) /* 0.000686646 */,
+ PRESHIFT(0x0061f000) /* 0.023910522 */,
+ -PRESHIFT(0x00092000) /* -0.002227783 */,
+ PRESHIFT(0x00068000) /* 0.001586914 */,
+ PRESHIFT(0x00005000) /* 0.000076294 */,
+
+ -PRESHIFT(0x00005000) /* -0.000076294 */,
+ -PRESHIFT(0x00068000) /* -0.001586914 */,
+ PRESHIFT(0x00092000) /* 0.002227783 */,
+ -PRESHIFT(0x0061f000) /* -0.023910522 */,
+ -PRESHIFT(0x0002d000) /* -0.000686646 */,
+ -PRESHIFT(0x025ff000) /* -0.148422241 */,
+ -PRESHIFT(0x026f7000) /* -0.152206421 */,
+ -PRESHIFT(0x0fa13000) /* -0.976852417 */,
+ PRESHIFT(0x0fa13000) /* 0.976852417 */,
+ PRESHIFT(0x026f7000) /* 0.152206421 */,
+ PRESHIFT(0x025ff000) /* 0.148422241 */,
+ PRESHIFT(0x0002d000) /* 0.000686646 */,
+ PRESHIFT(0x0061f000) /* 0.023910522 */,
+ -PRESHIFT(0x00092000) /* -0.002227783 */,
+ PRESHIFT(0x00068000) /* 0.001586914 */,
+ PRESHIFT(0x00005000) /* 0.000076294 */ }
diff --git a/core/multimedia/opieplayer/libmad/Makefile.in b/core/multimedia/opieplayer/libmad/Makefile.in
new file mode 100644
index 0000000..9e17769
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/Makefile.in
@@ -0,0 +1,226 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB) -DQCONFIG=\"qpe\"
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB) -DQCONFIG=\"qpe\"
+INCPATH = -I$(QPEDIR)/include -I..
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe -lm $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../../plugins/codecs/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = madplugin
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = libmad_version.h \
+ fixed.h \
+ bit.h \
+ timer.h \
+ stream.h \
+ frame.h \
+ synth.h \
+ decoder.h \
+ layer12.h \
+ layer3.h \
+ huffman.h \
+ libmad_global.h \
+ mad.h \
+ libmadplugin.h \
+ libmadpluginimpl.h
+SOURCES = version.c \
+ fixed.c \
+ bit.c \
+ timer.c \
+ stream.c \
+ frame.c \
+ synth.c \
+ decoder.c \
+ layer12.c \
+ layer3.c \
+ huffman.c \
+ libmadplugin.cpp \
+ libmadpluginimpl.cpp
+OBJECTS = version.o \
+ fixed.o \
+ bit.o \
+ timer.o \
+ stream.o \
+ frame.o \
+ synth.o \
+ decoder.o \
+ layer12.o \
+ layer3.o \
+ huffman.o \
+ libmadplugin.o \
+ libmadpluginimpl.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC =
+OBJMOC =
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
+
+$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK_LIB)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake libmad.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+version.o: version.c \
+ libmad_global.h \
+ libmad_version.h
+
+fixed.o: fixed.c \
+ libmad_global.h \
+ fixed.h
+
+bit.o: bit.c \
+ libmad_global.h \
+ bit.h
+
+timer.o: timer.c \
+ libmad_global.h \
+ timer.h
+
+stream.o: stream.c \
+ libmad_global.h \
+ bit.h \
+ stream.h
+
+frame.o: frame.c \
+ libmad_global.h \
+ bit.h \
+ stream.h \
+ frame.h \
+ fixed.h \
+ timer.h \
+ layer12.h \
+ layer3.h
+
+synth.o: synth.c \
+ libmad_global.h \
+ fixed.h \
+ frame.h \
+ timer.h \
+ stream.h \
+ bit.h \
+ synth.h \
+ D.dat
+
+decoder.o: decoder.c \
+ libmad_global.h \
+ stream.h \
+ bit.h \
+ frame.h \
+ fixed.h \
+ timer.h \
+ synth.h \
+ decoder.h
+
+layer12.o: layer12.c \
+ libmad_global.h \
+ fixed.h \
+ bit.h \
+ stream.h \
+ frame.h \
+ timer.h \
+ layer12.h \
+ sf_table.dat \
+ qc_table.dat
+
+layer3.o: layer3.c \
+ libmad_global.h \
+ fixed.h \
+ bit.h \
+ stream.h \
+ frame.h \
+ timer.h \
+ huffman.h \
+ layer3.h \
+ rq_table.dat \
+ imdct_s.dat
+
+huffman.o: huffman.c \
+ libmad_global.h \
+ huffman.h
+
+libmadplugin.o: libmadplugin.cpp \
+ libmadplugin.h \
+ ../mediaplayerplugininterface.h \
+ mad.h
+
+libmadpluginimpl.o: libmadpluginimpl.cpp \
+ libmadplugin.h \
+ ../mediaplayerplugininterface.h \
+ libmadpluginimpl.h \
+ ../mediaplayerplugininterface.h
+
+
diff --git a/core/multimedia/opieplayer/libmad/bit.c b/core/multimedia/opieplayer/libmad/bit.c
new file mode 100644
index 0000000..2466c5f
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/bit.c
@@ -0,0 +1,220 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifdef HAVE_CONFIG_H
+# include "libmad_config.h"
+# endif
+
+# include "libmad_global.h"
+
+# ifdef HAVE_LIMITS_H
+# include <limits.h>
+# else
+# define CHAR_BIT 8
+# endif
+
+# include "bit.h"
+
+/*
+ * This is the lookup table for computing the CRC-check word.
+ * As described in section 2.4.3.1 and depicted in Figure A.9
+ * of ISO/IEC 11172-3, the generator polynomial is:
+ *
+ * G(X) = X^16 + X^15 + X^2 + 1
+ */
+static
+unsigned short const crc_table[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
+};
+
+# define CRC_POLY 0x8005
+
+/*
+ * NAME: bit->init()
+ * DESCRIPTION: initialize bit pointer struct
+ */
+void mad_bit_init(struct mad_bitptr *bitptr, unsigned char const *byte)
+{
+ bitptr->byte = byte;
+ bitptr->cache = 0;
+ bitptr->left = CHAR_BIT;
+}
+
+/*
+ * NAME: bit->length()
+ * DESCRIPTION: return number of bits between start and end points
+ */
+unsigned int mad_bit_length(struct mad_bitptr const *begin,
+ struct mad_bitptr const *end)
+{
+ return begin->left +
+ CHAR_BIT * (end->byte - (begin->byte + 1)) + (CHAR_BIT - end->left);
+}
+
+/*
+ * NAME: bit->nextbyte()
+ * DESCRIPTION: return pointer to next unprocessed byte
+ */
+unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *bitptr)
+{
+ return bitptr->left == CHAR_BIT ? bitptr->byte : bitptr->byte + 1;
+}
+
+/*
+ * NAME: bit->skip()
+ * DESCRIPTION: advance bit pointer
+ */
+void mad_bit_skip(struct mad_bitptr *bitptr, unsigned int len)
+{
+ bitptr->byte += len / CHAR_BIT;
+ bitptr->left -= len % CHAR_BIT;
+
+ if (bitptr->left > CHAR_BIT) {
+ bitptr->byte++;
+ bitptr->left += CHAR_BIT;
+ }
+
+ if (bitptr->left < CHAR_BIT)
+ bitptr->cache = *bitptr->byte;
+}
+
+/*
+ * NAME: bit->read()
+ * DESCRIPTION: read an arbitrary number of bits and return their UIMSBF value
+ */
+unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len)
+{
+ register unsigned long value;
+
+ if (bitptr->left == CHAR_BIT)
+ bitptr->cache = *bitptr->byte;
+
+ if (len < bitptr->left) {
+ value = (bitptr->cache & ((1 << bitptr->left) - 1)) >>
+ (bitptr->left - len);
+ bitptr->left -= len;
+
+ return value;
+ }
+
+ /* remaining bits in current byte */
+
+ value = bitptr->cache & ((1 << bitptr->left) - 1);
+ len -= bitptr->left;
+
+ bitptr->byte++;
+ bitptr->left = CHAR_BIT;
+
+ /* more bytes */
+
+ while (len >= CHAR_BIT) {
+ value = (value << CHAR_BIT) | *bitptr->byte++;
+ len -= CHAR_BIT;
+ }
+
+ if (len > 0) {
+ bitptr->cache = *bitptr->byte;
+
+ value = (value << len) | (bitptr->cache >> (CHAR_BIT - len));
+ bitptr->left -= len;
+ }
+
+ return value;
+}
+
+# if 0
+/*
+ * NAME: bit->write()
+ * DESCRIPTION: write an arbitrary number of bits
+ */
+void mad_bit_write(struct mad_bitptr *bitptr, unsigned int len,
+ unsigned long value)
+{
+ unsigned char *ptr;
+
+ ptr = (unsigned char *) bitptr->byte;
+
+ /* ... */
+}
+# endif
+
+/*
+ * NAME: bit->crc()
+ * DESCRIPTION: compute CRC-check word
+ */
+unsigned short mad_bit_crc(struct mad_bitptr bitptr, unsigned int len,
+ unsigned short init)
+{
+ register unsigned int crc, data;
+
+# if CHAR_BIT == 8
+ for (crc = init; len >= 8; len -= 8) {
+ crc = (crc << 8) ^
+ crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff];
+ }
+# else
+ crc = init;
+# endif
+
+ while (len--) {
+ data = mad_bit_read(&bitptr, 1) ^ (crc >> 15);
+
+ crc <<= 1;
+ if (data & 1)
+ crc ^= CRC_POLY;
+ }
+
+ return crc & 0xffff;
+}
diff --git a/core/multimedia/opieplayer/libmad/bit.h b/core/multimedia/opieplayer/libmad/bit.h
new file mode 100644
index 0000000..f315bc9
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/bit.h
@@ -0,0 +1,47 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifndef LIBMAD_BIT_H
+# define LIBMAD_BIT_H
+
+struct mad_bitptr {
+ unsigned char const *byte;
+ unsigned short cache;
+ unsigned short left;
+};
+
+void mad_bit_init(struct mad_bitptr *, unsigned char const *);
+
+# define mad_bit_finish(bitptr) /* nothing */
+
+unsigned int mad_bit_length(struct mad_bitptr const *,
+ struct mad_bitptr const *);
+
+# define mad_bit_bitsleft(bitptr) ((bitptr)->left)
+unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *);
+
+void mad_bit_skip(struct mad_bitptr *, unsigned int);
+unsigned long mad_bit_read(struct mad_bitptr *, unsigned int);
+void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long);
+
+unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short);
+
+# endif
diff --git a/core/multimedia/opieplayer/libmad/decoder.c b/core/multimedia/opieplayer/libmad/decoder.c
new file mode 100644
index 0000000..dcf7cf3
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/decoder.c
@@ -0,0 +1,554 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifdef HAVE_CONFIG_H
+# include "libmad_config.h"
+# else
+# ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+# endif
+# ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+# endif
+# endif
+
+# include "libmad_global.h"
+
+# include <sys/types.h>
+
+# ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+# endif
+
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+
+# include <fcntl.h>
+# include <stdlib.h>
+# include <errno.h>
+
+# include "stream.h"
+# include "frame.h"
+# include "synth.h"
+# include "decoder.h"
+
+void mad_decoder_init(struct mad_decoder *decoder, void *data,
+ enum mad_flow (*input_func)(void *, struct mad_stream *),
+ enum mad_flow (*header_func)(void *,
+ struct mad_header const *),
+ enum mad_flow (*filter_func)(void *, struct mad_frame *),
+ enum mad_flow (*output_func)(void *,
+ struct mad_header const *,
+ struct mad_pcm *),
+ enum mad_flow (*error_func)(void *, struct mad_stream *,
+ struct mad_frame *),
+ enum mad_flow (*message_func)(void *,
+ void *, unsigned int *))
+{
+ decoder->mode = -1;
+
+ decoder->options = 0;
+
+ decoder->async.pid = 0;
+ decoder->async.in = -1;
+ decoder->async.out = -1;
+
+ decoder->sync = 0;
+
+ decoder->cb_data = data;
+
+ decoder->input_func = input_func;
+ decoder->header_func = header_func;
+ decoder->filter_func = filter_func;
+ decoder->output_func = output_func;
+ decoder->error_func = error_func;
+ decoder->message_func = message_func;
+}
+
+int mad_decoder_finish(struct mad_decoder *decoder)
+{
+ if (decoder->mode == MAD_DECODER_MODE_ASYNC && decoder->async.pid) {
+ pid_t pid;
+ int status;
+
+ close(decoder->async.in);
+
+ do {
+ pid = waitpid(decoder->async.pid, &status, 0);
+ }
+ while (pid == -1 && errno == EINTR);
+
+ decoder->mode = -1;
+
+ close(decoder->async.out);
+
+ decoder->async.pid = 0;
+ decoder->async.in = -1;
+ decoder->async.out = -1;
+
+ if (pid == -1)
+ return -1;
+
+ return (!WIFEXITED(status) || WEXITSTATUS(status)) ? -1 : 0;
+ }
+
+ return 0;
+}
+
+static
+enum mad_flow send_io(int fd, void const *data, size_t len)
+{
+ char const *ptr = data;
+ ssize_t count;
+
+ while (len) {
+ do {
+ count = write(fd, ptr, len);
+ }
+ while (count == -1 && errno == EINTR);
+
+ if (count == -1)
+ return MAD_FLOW_BREAK;
+
+ len -= count;
+ ptr += count;
+ }
+
+ return MAD_FLOW_CONTINUE;
+}
+
+static
+enum mad_flow receive_io(int fd, void *buffer, size_t len)
+{
+ char *ptr = buffer;
+ ssize_t count;
+
+ while (len) {
+ do {
+ count = read(fd, ptr, len);
+ }
+ while (count == -1 && errno == EINTR);
+
+ if (count == -1)
+ return (errno == EAGAIN) ? MAD_FLOW_IGNORE : MAD_FLOW_BREAK;
+ else if (count == 0)
+ return MAD_FLOW_STOP;
+
+ len -= count;
+ ptr += count;
+ }
+
+ return MAD_FLOW_CONTINUE;
+}
+
+static
+enum mad_flow receive_io_blocking(int fd, void *buffer, size_t len)
+{
+ int flags, blocking;
+ enum mad_flow result;
+
+ flags = fcntl(fd, F_GETFL);
+ if (flags == -1)
+ return MAD_FLOW_BREAK;
+
+ blocking = flags & ~O_NONBLOCK;
+
+ if (blocking != flags &&
+ fcntl(fd, F_SETFL, blocking) == -1)
+ return MAD_FLOW_BREAK;
+
+ result = receive_io(fd, buffer, len);
+
+ if (flags != blocking &&
+ fcntl(fd, F_SETFL, flags) == -1)
+ return MAD_FLOW_BREAK;
+
+ return result;
+}
+
+static
+enum mad_flow send(int fd, void const *message, unsigned int size)
+{
+ enum mad_flow result;
+
+ /* send size */
+
+ result = send_io(fd, &size, sizeof(size));
+
+ /* send message */
+
+ if (result == MAD_FLOW_CONTINUE)
+ result = send_io(fd, message, size);
+
+ return result;
+}
+
+static
+enum mad_flow receive(int fd, void **message, unsigned int *size)
+{
+ enum mad_flow result;
+ unsigned int actual;
+
+ if (*message == 0)
+ *size = 0;
+
+ /* receive size */
+
+ result = receive_io(fd, &actual, sizeof(actual));
+
+ /* receive message */
+
+ if (result == MAD_FLOW_CONTINUE) {
+ if (actual > *size)
+ actual -= *size;
+ else {
+ *size = actual;
+ actual = 0;
+ }
+
+ if (*size > 0) {
+ if (*message == 0) {
+ *message = malloc(*size);
+ if (*message == 0)
+ return MAD_FLOW_BREAK;
+ }
+
+ result = receive_io_blocking(fd, *message, *size);
+ }
+
+ /* throw away remainder of message */
+
+ while (actual && result == MAD_FLOW_CONTINUE) {
+ char sink[256];
+ unsigned int len;
+
+ len = actual > sizeof(sink) ? sizeof(sink) : actual;
+
+ result = receive_io_blocking(fd, sink, len);
+
+ actual -= len;
+ }
+ }
+
+ return result;
+}
+
+static
+enum mad_flow check_message(struct mad_decoder *decoder)
+{
+ enum mad_flow result;
+ void *message = 0;
+ unsigned int size;
+
+ result = receive(decoder->async.in, &message, &size);
+
+ if (result == MAD_FLOW_CONTINUE) {
+ if (decoder->message_func == 0)
+ size = 0;
+ else {
+ result = decoder->message_func(decoder->cb_data, message, &size);
+
+ if (result == MAD_FLOW_IGNORE ||
+ result == MAD_FLOW_BREAK)
+ size = 0;
+ }
+
+ if (send(decoder->async.out, message, size) != MAD_FLOW_CONTINUE)
+ result = MAD_FLOW_BREAK;
+ }
+
+ if (message)
+ free(message);
+
+ return result;
+}
+
+static
+enum mad_flow error_default(void *data, struct mad_stream *stream,
+ struct mad_frame *frame)
+{
+ int *bad_last_frame = data;
+
+ switch (stream->error) {
+ case MAD_ERROR_BADCRC:
+ if (*bad_last_frame)
+ mad_frame_mute(frame);
+ else
+ *bad_last_frame = 1;
+
+ return MAD_FLOW_IGNORE;
+
+ default:
+ return MAD_FLOW_CONTINUE;
+ }
+}
+
+static
+int run_sync(struct mad_decoder *decoder)
+{
+ enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
+ void *error_data;
+ int bad_last_frame = 0;
+ struct mad_stream *stream;
+ struct mad_frame *frame;
+ struct mad_synth *synth;
+ int result = 0;
+
+ if (decoder->input_func == 0)
+ return 0;
+
+ if (decoder->error_func) {
+ error_func = decoder->error_func;
+ error_data = decoder->cb_data;
+ }
+ else {
+ error_func = error_default;
+ error_data = &bad_last_frame;
+ }
+
+ stream = &decoder->sync->stream;
+ frame = &decoder->sync->frame;
+ synth = &decoder->sync->synth;
+
+ mad_stream_init(stream);
+ mad_frame_init(frame);
+ mad_synth_init(synth);
+
+ mad_stream_options(stream, decoder->options);
+
+ do {
+ switch (decoder->input_func(decoder->cb_data, stream)) {
+ case MAD_FLOW_STOP:
+ goto done;
+ case MAD_FLOW_BREAK:
+ goto fail;
+ case MAD_FLOW_IGNORE:
+ continue;
+ case MAD_FLOW_CONTINUE:
+ break;
+ }
+
+ while (1) {
+ if (decoder->mode == MAD_DECODER_MODE_ASYNC) {
+ switch (check_message(decoder)) {
+ case MAD_FLOW_IGNORE:
+ case MAD_FLOW_CONTINUE:
+ break;
+ case MAD_FLOW_BREAK:
+ goto fail;
+ case MAD_FLOW_STOP:
+ goto done;
+ }
+ }
+
+ if (decoder->header_func) {
+ if (mad_header_decode(&frame->header, stream) == -1) {
+ if (!MAD_RECOVERABLE(stream->error))
+ break;
+
+ switch (error_func(error_data, stream, frame)) {
+ case MAD_FLOW_STOP:
+ goto done;
+ case MAD_FLOW_BREAK:
+ goto fail;
+ case MAD_FLOW_IGNORE:
+ case MAD_FLOW_CONTINUE:
+ default:
+ continue;
+ }
+ }
+
+ switch (decoder->header_func(decoder->cb_data, &frame->header)) {
+ case MAD_FLOW_STOP:
+ goto done;
+ case MAD_FLOW_BREAK:
+ goto fail;
+ case MAD_FLOW_IGNORE:
+ continue;
+ case MAD_FLOW_CONTINUE:
+ break;
+ }
+ }
+
+ if (mad_frame_decode(frame, stream) == -1) {
+ if (!MAD_RECOVERABLE(stream->error))
+ break;
+
+ switch (error_func(error_data, stream, frame)) {
+ case MAD_FLOW_STOP:
+ goto done;
+ case MAD_FLOW_BREAK:
+ goto fail;
+ case MAD_FLOW_IGNORE:
+ break;
+ case MAD_FLOW_CONTINUE:
+ default:
+ continue;
+ }
+ }
+ else
+ bad_last_frame = 0;
+
+ if (decoder->filter_func) {
+ switch (decoder->filter_func(decoder->cb_data, frame)) {
+ case MAD_FLOW_STOP:
+ goto done;
+ case MAD_FLOW_BREAK:
+ goto fail;
+ case MAD_FLOW_IGNORE:
+ continue;
+ case MAD_FLOW_CONTINUE:
+ break;
+ }
+ }
+
+ mad_synth_frame(synth, frame);
+
+ if (decoder->output_func) {
+ switch (decoder->output_func(decoder->cb_data,
+ &frame->header, &synth->pcm)) {
+ case MAD_FLOW_STOP:
+ goto done;
+ case MAD_FLOW_BREAK:
+ goto fail;
+ case MAD_FLOW_IGNORE:
+ case MAD_FLOW_CONTINUE:
+ break;
+ }
+ }
+ }
+ }
+ while (stream->error == MAD_ERROR_BUFLEN);
+
+ fail:
+ result = -1;
+
+ done:
+ mad_synth_finish(synth);
+ mad_frame_finish(frame);
+ mad_stream_finish(stream);
+
+ return result;
+}
+
+static
+int run_async(struct mad_decoder *decoder)
+{
+ pid_t pid;
+ int ptoc[2], ctop[2], flags;
+
+ if (pipe(ptoc) == -1)
+ return -1;
+
+ if (pipe(ctop) == -1) {
+ close(ptoc[0]);
+ close(ptoc[1]);
+ return -1;
+ }
+
+ flags = fcntl(ptoc[0], F_GETFL);
+ if (flags == -1 ||
+ fcntl(ptoc[0], F_SETFL, flags | O_NONBLOCK) == -1) {
+ close(ctop[0]);
+ close(ctop[1]);
+ close(ptoc[0]);
+ close(ptoc[1]);
+ return -1;
+ }
+
+ pid = fork();
+ if (pid == -1) {
+ close(ctop[0]);
+ close(ctop[1]);
+ close(ptoc[0]);
+ close(ptoc[1]);
+ return -1;
+ }
+
+ decoder->async.pid = pid;
+
+ if (pid) {
+ /* parent */
+
+ close(ptoc[0]);
+ close(ctop[1]);
+
+ decoder->async.in = ctop[0];
+ decoder->async.out = ptoc[1];
+
+ return 0;
+ }
+
+ /* child */
+
+ close(ptoc[1]);
+ close(ctop[0]);
+
+ decoder->async.in = ptoc[0];
+ decoder->async.out = ctop[1];
+
+ _exit(run_sync(decoder));
+
+ /* not reached */
+ return -1;
+}
+
+int mad_decoder_run(struct mad_decoder *decoder, enum mad_decoder_mode mode)
+{
+ int result;
+ int (*run)(struct mad_decoder *) = 0;
+
+ switch (decoder->mode = mode) {
+ case MAD_DECODER_MODE_SYNC:
+ run = run_sync;
+ break;
+
+ case MAD_DECODER_MODE_ASYNC:
+ run = run_async;
+ break;
+ }
+
+ if (run == 0)
+ return -1;
+
+ decoder->sync = malloc(sizeof(*decoder->sync));
+ if (decoder->sync == 0)
+ return -1;
+
+ result = run(decoder);
+
+ free(decoder->sync);
+ decoder->sync = 0;
+
+ return result;
+}
+
+int mad_decoder_message(struct mad_decoder *decoder,
+ void *message, unsigned int *len)
+{
+ if (decoder->mode != MAD_DECODER_MODE_ASYNC ||
+ send(decoder->async.out, message, *len) != MAD_FLOW_CONTINUE ||
+ receive(decoder->async.in, &message, len) != MAD_FLOW_CONTINUE)
+ return -1;
+
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmad/decoder.h b/core/multimedia/opieplayer/libmad/decoder.h
new file mode 100644
index 0000000..dbacc1a
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/decoder.h
@@ -0,0 +1,87 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifndef LIBMAD_DECODER_H
+# define LIBMAD_DECODER_H
+
+# include "stream.h"
+# include "frame.h"
+# include "synth.h"
+
+enum mad_decoder_mode {
+ MAD_DECODER_MODE_SYNC = 0,
+ MAD_DECODER_MODE_ASYNC
+};
+
+enum mad_flow {
+ MAD_FLOW_CONTINUE = 0x0000,
+ MAD_FLOW_STOP = 0x0010,
+ MAD_FLOW_BREAK = 0x0011,
+ MAD_FLOW_IGNORE = 0x0020
+};
+
+struct mad_decoder {
+ enum mad_decoder_mode mode;
+
+ int options;
+
+ struct {
+ long pid;
+ int in;
+ int out;
+ } async;
+
+ struct {
+ struct mad_stream stream;
+ struct mad_frame frame;
+ struct mad_synth synth;
+ } *sync;
+
+ void *cb_data;
+
+ enum mad_flow (*input_func)(void *, struct mad_stream *);
+ enum mad_flow (*header_func)(void *, struct mad_header const *);
+ enum mad_flow (*filter_func)(void *, struct mad_frame *);
+ enum mad_flow (*output_func)(void *,
+ struct mad_header const *, struct mad_pcm *);
+ enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
+ enum mad_flow (*message_func)(void *, void *, unsigned int *);
+};
+
+void mad_decoder_init(struct mad_decoder *, void *,
+ enum mad_flow (*)(void *, struct mad_stream *),
+ enum mad_flow (*)(void *, struct mad_header const *),
+ enum mad_flow (*)(void *, struct mad_frame *),
+ enum mad_flow (*)(void *,
+ struct mad_header const *,
+ struct mad_pcm *),
+ enum mad_flow (*)(void *,
+ struct mad_stream *,
+ struct mad_frame *),
+ enum mad_flow (*)(void *, void *, unsigned int *));
+int mad_decoder_finish(struct mad_decoder *);
+
+# define mad_decoder_options(decoder, opts) ((decoder)->options = (opts))
+
+int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode);
+int mad_decoder_message(struct mad_decoder *, void *, unsigned int *);
+
+# endif
diff --git a/core/multimedia/opieplayer/libmad/fix_headers_problem b/core/multimedia/opieplayer/libmad/fix_headers_problem
new file mode 100755
index 0000000..6a5595c
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/fix_headers_problem
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+#
+# This is needed to ensure the single build will work
+# The names of the header files clash with names of other headers in Qt/Palmtop
+#
+
+
+for file in *.c
+do
+
+ echo "fixing $file"
+ sed "s/global.h/libmad_global.h/" $file > $file.tmp
+ sed "s/version.h/libmad_version.h/" $file.tmp > $file
+ sed "s/config.h/libmad_config.h/" $file > $file.tmp
+ mv $file.tmp $file
+
+done
+
+
+mv global.h libmad_global.h
+mv version.h libmad_version.h
+mv config.h libmad_config.h
+
+
diff --git a/core/multimedia/opieplayer/libmad/fixed.c b/core/multimedia/opieplayer/libmad/fixed.c
new file mode 100644
index 0000000..be5c94e
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/fixed.c
@@ -0,0 +1,37 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifdef HAVE_CONFIG_H
+# include "libmad_config.h"
+# endif
+
+# include "libmad_global.h"
+
+# include "fixed.h"
+
+/*
+ * NAME: fixed->abs()
+ * DESCRIPTION: return absolute value of a fixed-point number
+ */
+mad_fixed_t mad_f_abs(mad_fixed_t x)
+{
+ return x < 0 ? -x : x;
+}
diff --git a/core/multimedia/opieplayer/libmad/fixed.h b/core/multimedia/opieplayer/libmad/fixed.h
new file mode 100644
index 0000000..00ade62
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/fixed.h
@@ -0,0 +1,413 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifndef LIBMAD_FIXED_H
+# define LIBMAD_FIXED_H
+
+# if SIZEOF_INT >= 4
+typedef signed int mad_fixed_t;
+
+typedef signed int mad_fixed64hi_t;
+typedef unsigned int mad_fixed64lo_t;
+# else
+typedef signed long mad_fixed_t;
+
+typedef signed long mad_fixed64hi_t;
+typedef unsigned long mad_fixed64lo_t;
+# endif
+
+/*
+ * Fixed-point format: 0xABBBBBBB
+ * A == whole part (sign + 3 bits)
+ * B == fractional part (28 bits)
+ *
+ * Values are signed two's complement, so the effective range is:
+ * 0x80000000 to 0x7fffffff
+ * -8.0 to +7.9999999962747097015380859375
+ *
+ * The smallest representable value is:
+ * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9)
+ *
+ * 28 bits of fractional accuracy represent about
+ * 8.6 digits of decimal accuracy.
+ *
+ * Fixed-point numbers can be added or subtracted as normal
+ * integers, but multiplication requires shifting the 64-bit result
+ * from 56 fractional bits back to 28 (and rounding.)
+ *
+ * Changing the definition of MAD_F_FRACBITS is only partially
+ * supported, and must be done with care.
+ */
+
+# define MAD_F_FRACBITS 28
+
+# if MAD_F_FRACBITS == 28
+# define MAD_F(x) ((mad_fixed_t) (x##L))
+# else
+# if MAD_F_FRACBITS < 28
+# warning "MAD_F_FRACBITS < 28"
+# define MAD_F(x) ((mad_fixed_t) \
+ (((x##L) + \
+ (1L << (28 - MAD_F_FRACBITS - 1))) >> \
+ (28 - MAD_F_FRACBITS)))
+# elif MAD_F_FRACBITS > 28
+# error "MAD_F_FRACBITS > 28 not currently supported"
+# define MAD_F(x) ((mad_fixed_t) \
+ ((x##L) << (MAD_F_FRACBITS - 28)))
+# endif
+# endif
+
+# define MAD_F_MIN ((mad_fixed_t) -0x80000000L)
+# define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL)
+
+# define MAD_F_ONE MAD_F(0x10000000)
+
+# define mad_f_tofixed(x) ((mad_fixed_t) \
+ ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5))
+# define mad_f_todouble(x) ((double) \
+ ((x) / (double) (1L << MAD_F_FRACBITS)))
+
+# define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS)
+# define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1))
+ /* (x should be positive) */
+
+# define mad_f_fromint(x) ((x) << MAD_F_FRACBITS)
+
+# define mad_f_add(x, y) ((x) + (y))
+# define mad_f_sub(x, y) ((x) - (y))
+
+# if defined(FPM_64BIT)
+
+/*
+ * This version should be the most accurate if 64-bit (long long) types are
+ * supported by the compiler, although it may not be the most efficient.
+ */
+# if defined(OPT_ACCURACY)
+# define mad_f_mul(x, y) \
+ ((mad_fixed_t) \
+ ((((signed long long) (x) * (y)) + \
+ (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS))
+# else
+# define mad_f_mul(x, y) \
+ ((mad_fixed_t) (((signed long long) (x) * (y)) >> MAD_F_SCALEBITS))
+# endif
+
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+
+/* --- Intel --------------------------------------------------------------- */
+
+# elif defined(FPM_INTEL)
+
+/*
+ * This Intel version is fast and accurate; the disposition of the least
+ * significant bit depends on OPT_ACCURACY via mad_f_scale64().
+ */
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("imull %3" \
+ : "=a" (lo), "=d" (hi) \
+ : "%a" (x), "rm" (y) \
+ : "cc")
+
+# if defined(OPT_ACCURACY)
+/*
+ * This gives best accuracy but is not very fast.
+ */
+# define MAD_F_MLA(hi, lo, x, y) \
+ ({ mad_fixed64hi_t __hi; \
+ mad_fixed64lo_t __lo; \
+ MAD_F_MLX(__hi, __lo, (x), (y)); \
+ asm ("addl %2,%0\n\t" \
+ "adcl %3,%1" \
+ : "=rm" (lo), "=rm" (hi) \
+ : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \
+ : "cc"); \
+ })
+# endif /* OPT_ACCURACY */
+
+# if defined(OPT_ACCURACY)
+/*
+ * Surprisingly, this is faster than SHRD followed by ADC.
+ */
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed64hi_t __hi_; \
+ mad_fixed64lo_t __lo_; \
+ mad_fixed_t __result; \
+ asm ("addl %4,%2\n\t" \
+ "adcl %5,%3" \
+ : "=rm" (__lo_), "=rm" (__hi_) \
+ : "0" (lo), "1" (hi), \
+ "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \
+ : "cc"); \
+ asm ("shrdl %3,%2,%1" \
+ : "=rm" (__result) \
+ : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \
+ : "cc"); \
+ __result; \
+ })
+# else
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed_t __result; \
+ asm ("shrdl %3,%2,%1" \
+ : "=rm" (__result) \
+ : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \
+ : "cc"); \
+ __result; \
+ })
+# endif /* OPT_ACCURACY */
+
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+
+/* --- ARM ----------------------------------------------------------------- */
+
+# elif defined(FPM_ARM)
+
+/*
+ * This ARM V4 version is as accurate as FPM_64BIT but much faster. The
+ * least significant bit is properly rounded at no CPU cycle cost!
+ */
+# if 1
+/*
+ * There's a bug somewhere, possibly in the compiler, that sometimes makes
+ * this necessary instead of the default implementation via MAD_F_MLX and
+ * mad_f_scale64. It may be related to the use (or lack) of
+ * -finline-functions and/or -fstrength-reduce.
+ *
+ * This is also apparently faster than MAD_F_MLX/mad_f_scale64.
+ */
+# define mad_f_mul(x, y) \
+ ({ mad_fixed64hi_t __hi; \
+ mad_fixed64lo_t __lo; \
+ mad_fixed_t __result; \
+ asm ("smull %0, %1, %3, %4\n\t" \
+ "movs %0, %0, lsr %5\n\t" \
+ "adc %2, %0, %1, lsl %6" \
+ : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
+ : "%r" (x), "r" (y), \
+ "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
+ : "cc"); \
+ __result; \
+ })
+# endif
+
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("smull %0, %1, %2, %3" \
+ : "=&r" (lo), "=&r" (hi) \
+ : "%r" (x), "r" (y))
+
+# define MAD_F_MLA(hi, lo, x, y) \
+ asm ("smlal %0, %1, %2, %3" \
+ : "+r" (lo), "+r" (hi) \
+ : "%r" (x), "r" (y))
+
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed_t __result; \
+ asm ("movs %0, %1, lsr %3\n\t" \
+ "adc %0, %0, %2, lsl %4" \
+ : "=r" (__result) \
+ : "r" (lo), "r" (hi), \
+ "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
+ : "cc"); \
+ __result; \
+ })
+
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+
+/* --- MIPS ---------------------------------------------------------------- */
+
+# elif defined(FPM_MIPS)
+
+/*
+ * This MIPS version is fast and accurate; the disposition of the least
+ * significant bit depends on OPT_ACCURACY via mad_f_scale64().
+ */
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("mult %2,%3" \
+ : "=l" (lo), "=h" (hi) \
+ : "%r" (x), "r" (y))
+
+# if defined(HAVE_MADD_ASM)
+# define MAD_F_MLA(hi, lo, x, y) \
+ asm ("madd %2,%3" \
+ : "+l" (lo), "+h" (hi) \
+ : "%r" (x), "r" (y))
+# elif defined(HAVE_MADD16_ASM)
+/*
+ * This loses significant accuracy due to the 16-bit integer limit in the
+ * multiply/accumulate instruction.
+ */
+# define MAD_F_ML0(hi, lo, x, y) \
+ asm ("mult %2,%3" \
+ : "=l" (lo), "=h" (hi) \
+ : "%r" ((x) >> 12), "r" ((y) >> 16))
+# define MAD_F_MLA(hi, lo, x, y) \
+ asm ("madd16 %2,%3" \
+ : "+l" (lo), "+h" (hi) \
+ : "%r" ((x) >> 12), "r" ((y) >> 16))
+# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo))
+# endif
+
+# if defined(OPT_SPEED)
+# define mad_f_scale64(hi, lo) \
+ ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS)))
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+# endif
+
+/* --- SPARC --------------------------------------------------------------- */
+
+# elif defined(FPM_SPARC)
+
+/*
+ * This SPARC V8 version is fast and accurate; the disposition of the least
+ * significant bit depends on OPT_ACCURACY via mad_f_scale64().
+ */
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("smul %2, %3, %0\n\t" \
+ "rd %%y, %1" \
+ : "=r" (lo), "=r" (hi) \
+ : "%r" (x), "rI" (y))
+
+/* --- PowerPC ------------------------------------------------------------- */
+
+# elif defined(FPM_PPC)
+
+/*
+ * This PowerPC version is tuned for the 4xx embedded processors. It is
+ * effectively a tuned version of FPM_64BIT. It is a little faster and just
+ * as accurate. The disposition of the least significant bit depends on
+ * OPT_ACCURACY via mad_f_scale64().
+ */
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("mulhw %1, %2, %3\n\t" \
+ "mullw %0, %2, %3" \
+ : "=&r" (lo), "=&r" (hi) \
+ : "%r" (x), "r" (y))
+
+# define MAD_F_MLA(hi, lo, x, y) \
+ ({ mad_fixed64hi_t __hi; \
+ mad_fixed64lo_t __lo; \
+ MAD_F_MLX(__hi, __lo, (x), (y)); \
+ asm ("addc %0, %2, %3\n\t" \
+ "adde %1, %4, %5" \
+ : "=r" (lo), "=r" (hi) \
+ : "%r" (__lo), "0" (lo), "%r" (__hi), "1" (hi)); \
+ })
+
+# if defined(OPT_ACCURACY)
+/*
+ * This is accurate and ~2 - 2.5 times slower than the unrounded version.
+ *
+ * The __volatile__ improves the generated code by another 5% (fewer spills
+ * to memory); eventually they should be removed.
+ */
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed_t __result; \
+ mad_fixed64hi_t __hi_; \
+ mad_fixed64lo_t __lo_; \
+ asm __volatile__ ("addc %0, %2, %4\n\t" \
+ "addze %1, %3" \
+ : "=r" (__lo_), "=r" (__hi_) \
+ : "r" (lo), "r" (hi), "r" (1 << (MAD_F_SCALEBITS - 1))); \
+ asm __volatile__ ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \
+ "rlwimi %0, %1,32-%3,%3,31" \
+ : "=&r" (__result) \
+ : "r" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS)); \
+ __result; \
+ })
+# else
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed_t __result; \
+ asm ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \
+ "rlwimi %0, %1,32-%3,%3,31" \
+ : "=r" (__result) \
+ : "r" (lo), "r" (hi), "I" (MAD_F_SCALEBITS)); \
+ __result; \
+ })
+# endif /* OPT_ACCURACY */
+
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+
+/* --- Default ------------------------------------------------------------- */
+
+# elif defined(FPM_DEFAULT)
+
+/*
+ * This version is the most portable but it loses significant accuracy.
+ * Furthermore, accuracy is biased against the second argument, so care
+ * should be taken when ordering operands.
+ *
+ * The scale factors are constant as this is not used with SSO.
+ *
+ * Pre-rounding is required to stay within the limits of compliance.
+ */
+# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \
+ (((y) + (1L << 15)) >> 16))
+
+/* ------------------------------------------------------------------------- */
+
+# else
+# error "no FPM selected"
+# endif
+
+/* default implementations */
+
+# if !defined(mad_f_mul)
+# define mad_f_mul(x, y) \
+ ({ mad_fixed64hi_t __hi; \
+ mad_fixed64lo_t __lo; \
+ MAD_F_MLX(__hi, __lo, (x), (y)); \
+ mad_f_scale64(__hi, __lo); \
+ })
+# endif
+
+# if !defined(MAD_F_MLA)
+# define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y)))
+# define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y)))
+# define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
+# endif
+
+# if !defined(MAD_F_ML0)
+# define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y))
+# endif
+
+# if !defined(MAD_F_MLZ)
+# define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo))
+# endif
+
+# if !defined(mad_f_scale64)
+# if defined(OPT_ACCURACY)
+# define mad_f_scale64(hi, lo) \
+ ((((mad_fixed_t) \
+ (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \
+ ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1)
+# else
+# define mad_f_scale64(hi, lo) \
+ ((mad_fixed_t) \
+ (((hi) << (32 - MAD_F_SCALEBITS)) | \
+ ((lo) >> MAD_F_SCALEBITS)))
+# endif
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+# endif
+
+/* miscellaneous C routines */
+
+mad_fixed_t mad_f_abs(mad_fixed_t);
+
+# endif
diff --git a/core/multimedia/opieplayer/libmad/frame.c b/core/multimedia/opieplayer/libmad/frame.c
new file mode 100644
index 0000000..4ebb80c
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/frame.c
@@ -0,0 +1,499 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifdef HAVE_CONFIG_H
+# include "libmad_config.h"
+# endif
+
+# include "libmad_global.h"
+
+# include <stdlib.h>
+
+# include "bit.h"
+# include "stream.h"
+# include "frame.h"
+# include "timer.h"
+# include "layer12.h"
+# include "layer3.h"
+
+static
+unsigned long const bitrate_table[5][15] = {
+ /* MPEG-1 */
+ { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */
+ 256000, 288000, 320000, 352000, 384000, 416000, 448000 },
+ { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */
+ 128000, 160000, 192000, 224000, 256000, 320000, 384000 },
+ { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */
+ 112000, 128000, 160000, 192000, 224000, 256000, 320000 },
+
+ /* MPEG-2 LSF */
+ { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */
+ 128000, 144000, 160000, 176000, 192000, 224000, 256000 },
+ { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */
+ 64000, 80000, 96000, 112000, 128000, 144000, 160000 } /* II & III */
+};
+
+static
+unsigned int const samplerate_table[3] = { 44100, 48000, 32000 };
+
+static
+int (*const decoder_table[3])(struct mad_stream *, struct mad_frame *) = {
+ mad_layer_I,
+ mad_layer_II,
+ mad_layer_III
+};
+
+/*
+ * NAME: header->init()
+ * DESCRIPTION: initialize header struct
+ */
+void mad_header_init(struct mad_header *header)
+{
+ header->layer = 0;
+ header->mode = 0;
+ header->mode_extension = 0;
+ header->emphasis = 0;
+
+ header->bitrate = 0;
+ header->samplerate = 0;
+
+ header->crc_check = 0;
+ header->crc_target = 0;
+
+ header->flags = 0;
+ header->private_bits = 0;
+
+ header->duration = mad_timer_zero;
+}
+
+/*
+ * NAME: frame->init()
+ * DESCRIPTION: initialize frame struct
+ */
+void mad_frame_init(struct mad_frame *frame)
+{
+ mad_header_init(&frame->header);
+
+ frame->options = 0;
+
+ frame->overlap = 0;
+ mad_frame_mute(frame);
+}
+
+/*
+ * NAME: frame->finish()
+ * DESCRIPTION: deallocate any dynamic memory associated with frame
+ */
+void mad_frame_finish(struct mad_frame *frame)
+{
+ mad_header_finish(&frame->header);
+
+ if (frame->overlap) {
+ free(frame->overlap);
+ frame->overlap = 0;
+ }
+}
+
+/*
+ * NAME: decode_header()
+ * DESCRIPTION: read header data and following CRC word
+ */
+static
+int decode_header(struct mad_header *header, struct mad_stream *stream)
+{
+ unsigned int index;
+
+ header->flags = 0;
+ header->private_bits = 0;
+
+ /* header() */
+
+ /* syncword */
+ mad_bit_skip(&stream->ptr, 11);
+
+ /* MPEG 2.5 indicator (really part of syncword) */
+ if (mad_bit_read(&stream->ptr, 1) == 0)
+ header->flags |= MAD_FLAG_MPEG_2_5_EXT;
+
+ /* ID */
+ if (mad_bit_read(&stream->ptr, 1) == 0)
+ header->flags |= MAD_FLAG_LSF_EXT;
+ else if (header->flags & MAD_FLAG_MPEG_2_5_EXT) {
+ stream->error = MAD_ERROR_LOSTSYNC;
+ return -1;
+ }
+
+ /* layer */
+ header->layer = 4 - mad_bit_read(&stream->ptr, 2);
+
+ if (header->layer == 4) {
+ stream->error = MAD_ERROR_BADLAYER;
+ return -1;
+ }
+
+ /* protection_bit */
+ if (mad_bit_read(&stream->ptr, 1) == 0) {
+ header->flags |= MAD_FLAG_PROTECTION;
+ header->crc_check = mad_bit_crc(stream->ptr, 16, 0xffff);
+ }
+
+ /* bitrate_index */
+ index = mad_bit_read(&stream->ptr, 4);
+
+ if (index == 15) {
+ stream->error = MAD_ERROR_BADBITRATE;
+ return -1;
+ }
+
+ if (header->flags & MAD_FLAG_LSF_EXT)
+ header->bitrate = bitrate_table[3 + (header->layer >> 1)][index];
+ else
+ header->bitrate = bitrate_table[header->layer - 1][index];
+
+ /* sampling_frequency */
+ index = mad_bit_read(&stream->ptr, 2);
+
+ if (index == 3) {
+ stream->error = MAD_ERROR_BADSAMPLERATE;
+ return -1;
+ }
+
+ header->samplerate = samplerate_table[index];
+
+ if (header->flags & MAD_FLAG_LSF_EXT) {
+ header->samplerate /= 2;
+
+ if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
+ header->samplerate /= 2;
+ }
+
+ /* padding_bit */
+ if (mad_bit_read(&stream->ptr, 1))
+ header->flags |= MAD_FLAG_PADDING;
+
+ /* private_bit */
+ if (mad_bit_read(&stream->ptr, 1))
+ header->private_bits |= MAD_PRIVATE_HEADER;
+
+ /* mode */
+ header->mode = 3 - mad_bit_read(&stream->ptr, 2);
+
+ /* mode_extension */
+ header->mode_extension = mad_bit_read(&stream->ptr, 2);
+
+ /* copyright */
+ if (mad_bit_read(&stream->ptr, 1))
+ header->flags |= MAD_FLAG_COPYRIGHT;
+
+ /* original/copy */
+ if (mad_bit_read(&stream->ptr, 1))
+ header->flags |= MAD_FLAG_ORIGINAL;
+
+ /* emphasis */
+ header->emphasis = mad_bit_read(&stream->ptr, 2);
+
+ if (header->emphasis == 2) {
+ stream->error = MAD_ERROR_BADEMPHASIS;
+ return -1;
+ }
+
+ /* error_check() */
+
+ /* crc_check */
+ if (header->flags & MAD_FLAG_PROTECTION)
+ header->crc_target = mad_bit_read(&stream->ptr, 16);
+
+ return 0;
+}
+
+/*
+ * NAME: free_bitrate()
+ * DESCRIPTION: attempt to discover the bitstream's free bitrate
+ */
+static
+int free_bitrate(struct mad_stream *stream, struct mad_header const *header)
+{
+ struct mad_bitptr keep_ptr;
+ unsigned long rate = 0;
+ unsigned int pad_slot, slots_per_frame;
+ unsigned char const *ptr = 0;
+
+ keep_ptr = stream->ptr;
+
+ pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0;
+ slots_per_frame = (header->layer == MAD_LAYER_III &&
+ (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144;
+
+ while (mad_stream_sync(stream) == 0) {
+ struct mad_stream peek_stream;
+ struct mad_header peek_header;
+
+ peek_stream = *stream;
+ peek_header = *header;
+
+ if (decode_header(&peek_header, &peek_stream) == 0 &&
+ peek_header.layer == header->layer &&
+ peek_header.samplerate == header->samplerate) {
+ unsigned int N;
+
+ ptr = mad_bit_nextbyte(&stream->ptr);
+
+ N = ptr - stream->this_frame;
+
+ if (header->layer == MAD_LAYER_I) {
+ rate = (unsigned long) header->samplerate *
+ (N - 4 * pad_slot + 4) / 48 / 1000;
+ }
+ else {
+ rate = (unsigned long) header->samplerate *
+ (N - pad_slot + 1) / slots_per_frame / 1000;
+ }
+
+ if (rate >= 8)
+ break;
+ }
+
+ mad_bit_skip(&stream->ptr, 8);
+ }
+
+ stream->ptr = keep_ptr;
+
+ if (rate < 8 || (header->layer == MAD_LAYER_III && rate > 640)) {
+ stream->error = MAD_ERROR_LOSTSYNC;
+ return -1;
+ }
+
+ stream->freerate = rate * 1000;
+
+# if 0 && defined(DEBUG)
+ fprintf(stderr, "free bitrate == %lu\n", stream->freerate);
+# endif
+
+ return 0;
+}
+
+/*
+ * NAME: header->decode()
+ * DESCRIPTION: read the next frame header from the stream
+ */
+int mad_header_decode(struct mad_header *header, struct mad_stream *stream)
+{
+ register unsigned char const *ptr, *end;
+ unsigned int pad_slot, N;
+
+ ptr = stream->next_frame;
+ end = stream->bufend;
+
+ if (ptr == 0) {
+ stream->error = MAD_ERROR_BUFPTR;
+ goto fail;
+ }
+
+ /* stream skip */
+ if (stream->skiplen) {
+ if (!stream->sync)
+ ptr = stream->this_frame;
+
+ if (end - ptr < stream->skiplen) {
+ stream->skiplen -= end - ptr;
+ stream->next_frame = end;
+
+ stream->error = MAD_ERROR_BUFLEN;
+ goto fail;
+ }
+
+ ptr += stream->skiplen;
+ stream->skiplen = 0;
+
+ stream->sync = 1;
+ }
+
+ sync:
+ /* synchronize */
+ if (stream->sync) {
+ if (end - ptr < MAD_BUFFER_GUARD) {
+ stream->next_frame = ptr;
+
+ stream->error = MAD_ERROR_BUFLEN;
+ goto fail;
+ }
+ else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
+ /* mark point where frame sync word was expected */
+ stream->this_frame = ptr;
+ stream->next_frame = ptr + 1;
+
+ stream->error = MAD_ERROR_LOSTSYNC;
+ goto fail;
+ }
+ }
+ else {
+ mad_bit_init(&stream->ptr, ptr);
+
+ if (mad_stream_sync(stream) == -1) {
+ if (end - stream->next_frame >= MAD_BUFFER_GUARD)
+ stream->next_frame = end - MAD_BUFFER_GUARD;
+
+ stream->error = MAD_ERROR_BUFLEN;
+ goto fail;
+ }
+
+ ptr = mad_bit_nextbyte(&stream->ptr);
+ }
+
+ /* begin processing */
+ stream->this_frame = ptr;
+ stream->next_frame = ptr + 1; /* possibly bogus sync word */
+
+ mad_bit_init(&stream->ptr, stream->this_frame);
+
+ if (decode_header(header, stream) == -1)
+ goto fail;
+
+ /* calculate frame duration */
+ mad_timer_set(&header->duration, 0,
+ 32 * MAD_NSBSAMPLES(header), header->samplerate);
+
+ /* calculate free bit rate */
+ if (header->bitrate == 0) {
+ if ((!stream->sync || !stream->freerate) &&
+ free_bitrate(stream, header) == -1)
+ goto fail;
+
+ header->bitrate = stream->freerate;
+ header->flags |= MAD_FLAG_FREEFORMAT;
+ }
+
+ /* calculate beginning of next frame */
+ pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0;
+
+ if (header->layer == MAD_LAYER_I)
+ N = ((12 * header->bitrate / header->samplerate) + pad_slot) * 4;
+ else {
+ unsigned int slots_per_frame;
+
+ slots_per_frame = (header->layer == MAD_LAYER_III &&
+ (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144;
+
+ N = (slots_per_frame * header->bitrate / header->samplerate) + pad_slot;
+ }
+
+ /* verify there is enough data left in buffer to decode this frame */
+ if (N + MAD_BUFFER_GUARD > end - stream->this_frame) {
+ stream->next_frame = stream->this_frame;
+
+ stream->error = MAD_ERROR_BUFLEN;
+ goto fail;
+ }
+
+ stream->next_frame = stream->this_frame + N;
+
+ if (!stream->sync) {
+ /* check that a valid frame header follows this frame */
+
+ ptr = stream->next_frame;
+ if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) {
+ ptr = stream->next_frame = stream->this_frame + 1;
+ goto sync;
+ }
+
+ stream->sync = 1;
+ }
+
+ header->flags |= MAD_FLAG_INCOMPLETE;
+
+ return 0;
+
+ fail:
+ stream->sync = 0;
+
+ return -1;
+}
+
+/*
+ * NAME: frame->decode()
+ * DESCRIPTION: decode a single frame from a bitstream
+ */
+int mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream)
+{
+ frame->options = stream->options;
+
+ /* header() */
+ /* error_check() */
+
+ if (!(frame->header.flags & MAD_FLAG_INCOMPLETE) &&
+ mad_header_decode(&frame->header, stream) == -1)
+ goto fail;
+
+ /* audio_data() */
+
+ frame->header.flags &= ~MAD_FLAG_INCOMPLETE;
+
+ if (decoder_table[frame->header.layer - 1](stream, frame) == -1) {
+ if (!MAD_RECOVERABLE(stream->error))
+ stream->next_frame = stream->this_frame;
+
+ goto fail;
+ }
+
+ /* ancillary_data() */
+
+ if (frame->header.layer != MAD_LAYER_III) {
+ struct mad_bitptr next_frame;
+
+ mad_bit_init(&next_frame, stream->next_frame);
+
+ stream->anc_ptr = stream->ptr;
+ stream->anc_bitlen = mad_bit_length(&stream->ptr, &next_frame);
+
+ mad_bit_finish(&next_frame);
+ }
+
+ return 0;
+
+ fail:
+ stream->anc_bitlen = 0;
+ return -1;
+}
+
+/*
+ * NAME: frame->mute()
+ * DESCRIPTION: zero all subband values so the frame becomes silent
+ */
+void mad_frame_mute(struct mad_frame *frame)
+{
+ unsigned int s, sb;
+
+ for (s = 0; s < 36; ++s) {
+ for (sb = 0; sb < 32; ++sb) {
+ frame->sbsample[0][s][sb] =
+ frame->sbsample[1][s][sb] = 0;
+ }
+ }
+
+ if (frame->overlap) {
+ for (s = 0; s < 18; ++s) {
+ for (sb = 0; sb < 32; ++sb) {
+ (*frame->overlap)[0][sb][s] =
+ (*frame->overlap)[1][sb][s] = 0;
+ }
+ }
+ }
+}
diff --git a/core/multimedia/opieplayer/libmad/frame.h b/core/multimedia/opieplayer/libmad/frame.h
new file mode 100644
index 0000000..e88d0c8
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/frame.h
@@ -0,0 +1,115 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifndef LIBMAD_FRAME_H
+# define LIBMAD_FRAME_H
+
+# include "fixed.h"
+# include "timer.h"
+# include "stream.h"
+
+enum mad_layer {
+ MAD_LAYER_I = 1, /* Layer I */
+ MAD_LAYER_II = 2, /* Layer II */
+ MAD_LAYER_III = 3 /* Layer III */
+};
+
+enum mad_mode {
+ MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */
+ MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */
+ MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */
+ MAD_MODE_STEREO = 3 /* normal LR stereo */
+};
+
+enum mad_emphasis {
+ MAD_EMPHASIS_NONE = 0, /* no emphasis */
+ MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */
+ MAD_EMPHASIS_CCITT_J_17 = 3 /* CCITT J.17 emphasis */
+};
+
+struct mad_frame {
+ struct mad_header {
+ enum mad_layer layer; /* audio layer (1, 2, or 3) */
+ enum mad_mode mode; /* channel mode (see above) */
+ int mode_extension; /* additional mode info */
+ enum mad_emphasis emphasis; /* de-emphasis to use (see above) */
+
+ unsigned long bitrate; /* stream bitrate (bps) */
+ unsigned int samplerate; /* sampling frequency (Hz) */
+
+ unsigned short crc_check; /* frame CRC accumulator */
+ unsigned short crc_target; /* final target CRC checksum */
+
+ int flags; /* flags (see below) */
+ int private_bits; /* private bits (see below) */
+
+ mad_timer_t duration; /* audio playing time of frame */
+ } header;
+
+ int options; /* decoding options (from stream) */
+
+ mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */
+ mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */
+};
+
+# define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1)
+# define MAD_NSBSAMPLES(header) \
+ ((header)->layer == MAD_LAYER_I ? 12 : \
+ (((header)->layer == MAD_LAYER_III && \
+ ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36))
+
+enum {
+ MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */
+ MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */
+
+ MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */
+ MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */
+ MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */
+ MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */
+
+ MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */
+ MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */
+ MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */
+
+ MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */
+ MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */
+ MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */
+};
+
+enum {
+ MAD_PRIVATE_HEADER = 0x0100, /* header private bit */
+ MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */
+};
+
+void mad_header_init(struct mad_header *);
+
+# define mad_header_finish(header) /* nothing */
+
+int mad_header_decode(struct mad_header *, struct mad_stream *);
+
+void mad_frame_init(struct mad_frame *);
+void mad_frame_finish(struct mad_frame *);
+
+int mad_frame_decode(struct mad_frame *, struct mad_stream *);
+
+void mad_frame_mute(struct mad_frame *);
+
+# endif
diff --git a/core/multimedia/opieplayer/libmad/huffman.c b/core/multimedia/opieplayer/libmad/huffman.c
new file mode 100644
index 0000000..8ec9499
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/huffman.c
@@ -0,0 +1,3087 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifdef HAVE_CONFIG_H
+# include "libmad_config.h"
+# endif
+
+# include "libmad_global.h"
+
+# include "huffman.h"
+
+/*
+ * These are the Huffman code words for Layer III.
+ * The data for these tables are derived from Table B.7 of ISO/IEC 11172-3.
+ *
+ * These tables support decoding up to 4 Huffman code bits at a time.
+ */
+
+# define V(v, w, x, y, hlen) { { 1, hlen, v, w, x, y } }
+# define PTR(offs, bits) { ptr: { 0, bits, offs } }
+
+static
+union huffquad const hufftabA[] = {
+ /* 0000 */ PTR(16, 2),
+ /* 0001 */ PTR(20, 2),
+ /* 0010 */ PTR(24, 1),
+ /* 0011 */ PTR(26, 1),
+ /* 0100 */ V(0, 0, 1, 0, 4),
+ /* 0101 */ V(0, 0, 0, 1, 4),
+ /* 0110 */ V(0, 1, 0, 0, 4),
+ /* 0111 */ V(1, 0, 0, 0, 4),
+ /* 1000 */ V(0, 0, 0, 0, 1),
+ /* 1001 */ V(0, 0, 0, 0, 1),
+ /* 1010 */ V(0, 0, 0, 0, 1),
+ /* 1011 */ V(0, 0, 0, 0, 1),
+ /* 1100 */ V(0, 0, 0, 0, 1),
+ /* 1101 */ V(0, 0, 0, 0, 1),
+ /* 1110 */ V(0, 0, 0, 0, 1),
+ /* 1111 */ V(0, 0, 0, 0, 1),
+
+ /* 0000 ... */
+ /* 00 */ V(1, 0, 1, 1, 2), /* 16 */
+ /* 01 */ V(1, 1, 1, 1, 2),
+ /* 10 */ V(1, 1, 0, 1, 2),
+ /* 11 */ V(1, 1, 1, 0, 2),
+
+ /* 0001 ... */
+ /* 00 */ V(0, 1, 1, 1, 2), /* 20 */
+ /* 01 */ V(0, 1, 0, 1, 2),
+ /* 10 */ V(1, 0, 0, 1, 1),
+ /* 11 */ V(1, 0, 0, 1, 1),
+
+ /* 0010 ... */
+ /* 0 */ V(0, 1, 1, 0, 1), /* 24 */
+ /* 1 */ V(0, 0, 1, 1, 1),
+
+ /* 0011 ... */
+ /* 0 */ V(1, 0, 1, 0, 1), /* 26 */
+ /* 1 */ V(1, 1, 0, 0, 1)
+};
+
+static
+union huffquad const hufftabB[] = {
+ /* 0000 */ V(1, 1, 1, 1, 4),
+ /* 0001 */ V(1, 1, 1, 0, 4),
+ /* 0010 */ V(1, 1, 0, 1, 4),
+ /* 0011 */ V(1, 1, 0, 0, 4),
+ /* 0100 */ V(1, 0, 1, 1, 4),
+ /* 0101 */ V(1, 0, 1, 0, 4),
+ /* 0110 */ V(1, 0, 0, 1, 4),
+ /* 0111 */ V(1, 0, 0, 0, 4),
+ /* 1000 */ V(0, 1, 1, 1, 4),
+ /* 1001 */ V(0, 1, 1, 0, 4),
+ /* 1010 */ V(0, 1, 0, 1, 4),
+ /* 1011 */ V(0, 1, 0, 0, 4),
+ /* 1100 */ V(0, 0, 1, 1, 4),
+ /* 1101 */ V(0, 0, 1, 0, 4),
+ /* 1110 */ V(0, 0, 0, 1, 4),
+ /* 1111 */ V(0, 0, 0, 0, 4)
+};
+
+# undef V
+# undef PTR
+
+# define V(x, y, hlen) { { 1, hlen, x, y } }
+# define PTR(offs, bits) { ptr: { 0, bits, offs } }
+
+static
+union huffpair const hufftab0[] = {
+ /* */ V(0, 0, 0)
+};
+
+static
+union huffpair const hufftab1[] = {
+ /* 000 */ V(1, 1, 3),
+ /* 001 */ V(0, 1, 3),
+ /* 010 */ V(1, 0, 2),
+ /* 011 */ V(1, 0, 2),
+ /* 100 */ V(0, 0, 1),
+ /* 101 */ V(0, 0, 1),
+ /* 110 */ V(0, 0, 1),
+ /* 111 */ V(0, 0, 1)
+};
+
+static
+union huffpair const hufftab2[] = {
+ /* 000 */ PTR(8, 3),
+ /* 001 */ V(1, 1, 3),
+ /* 010 */ V(0, 1, 3),
+ /* 011 */ V(1, 0, 3),
+ /* 100 */ V(0, 0, 1),
+ /* 101 */ V(0, 0, 1),
+ /* 110 */ V(0, 0, 1),
+ /* 111 */ V(0, 0, 1),
+
+ /* 000 ... */
+ /* 000 */ V(2, 2, 3), /* 8 */
+ /* 001 */ V(0, 2, 3),
+ /* 010 */ V(1, 2, 2),
+ /* 011 */ V(1, 2, 2),
+ /* 100 */ V(2, 1, 2),
+ /* 101 */ V(2, 1, 2),
+ /* 110 */ V(2, 0, 2),
+ /* 111 */ V(2, 0, 2)
+};
+
+static
+union huffpair const hufftab3[] = {
+ /* 000 */ PTR(8, 3),
+ /* 001 */ V(1, 0, 3),
+ /* 010 */ V(1, 1, 2),
+ /* 011 */ V(1, 1, 2),
+ /* 100 */ V(0, 1, 2),
+ /* 101 */ V(0, 1, 2),
+ /* 110 */ V(0, 0, 2),
+ /* 111 */ V(0, 0, 2),
+
+ /* 000 ... */
+ /* 000 */ V(2, 2, 3), /* 8 */
+ /* 001 */ V(0, 2, 3),
+ /* 010 */ V(1, 2, 2),
+ /* 011 */ V(1, 2, 2),
+ /* 100 */ V(2, 1, 2),
+ /* 101 */ V(2, 1, 2),
+ /* 110 */ V(2, 0, 2),
+ /* 111 */ V(2, 0, 2)
+};
+
+static
+union huffpair const hufftab5[] = {
+ /* 000 */ PTR(8, 4),
+ /* 001 */ V(1, 1, 3),
+ /* 010 */ V(0, 1, 3),
+ /* 011 */ V(1, 0, 3),
+ /* 100 */ V(0, 0, 1),
+ /* 101 */ V(0, 0, 1),
+ /* 110 */ V(0, 0, 1),
+ /* 111 */ V(0, 0, 1),
+
+ /* 000 ... */
+ /* 0000 */ PTR(24, 1), /* 8 */
+ /* 0001 */ V(3, 2, 4),
+ /* 0010 */ V(3, 1, 3),
+ /* 0011 */ V(3, 1, 3),
+ /* 0100 */ V(1, 3, 4),
+ /* 0101 */ V(0, 3, 4),
+ /* 0110 */ V(3, 0, 4),
+ /* 0111 */ V(2, 2, 4),
+ /* 1000 */ V(1, 2, 3),
+ /* 1001 */ V(1, 2, 3),
+ /* 1010 */ V(2, 1, 3),
+ /* 1011 */ V(2, 1, 3),
+ /* 1100 */ V(0, 2, 3),
+ /* 1101 */ V(0, 2, 3),
+ /* 1110 */ V(2, 0, 3),
+ /* 1111 */ V(2, 0, 3),
+
+ /* 000 0000 ... */
+ /* 0 */ V(3, 3, 1), /* 24 */
+ /* 1 */ V(2, 3, 1)
+};
+
+static
+union huffpair const hufftab6[] = {
+ /* 0000 */ PTR(16, 3),
+ /* 0001 */ PTR(24, 1),
+ /* 0010 */ PTR(26, 1),
+ /* 0011 */ V(1, 2, 4),
+ /* 0100 */ V(2, 1, 4),
+ /* 0101 */ V(2, 0, 4),
+ /* 0110 */ V(0, 1, 3),
+ /* 0111 */ V(0, 1, 3),
+ /* 1000 */ V(1, 1, 2),
+ /* 1001 */ V(1, 1, 2),
+ /* 1010 */ V(1, 1, 2),
+ /* 1011 */ V(1, 1, 2),
+ /* 1100 */ V(1, 0, 3),
+ /* 1101 */ V(1, 0, 3),
+ /* 1110 */ V(0, 0, 3),
+ /* 1111 */ V(0, 0, 3),
+
+ /* 0000 ... */
+ /* 000 */ V(3, 3, 3), /* 16 */
+ /* 001 */ V(0, 3, 3),
+ /* 010 */ V(2, 3, 2),
+ /* 011 */ V(2, 3, 2),
+ /* 100 */ V(3, 2, 2),
+ /* 101 */ V(3, 2, 2),
+ /* 110 */ V(3, 0, 2),
+ /* 111 */ V(3, 0, 2),
+
+ /* 0001 ... */
+ /* 0 */ V(1, 3, 1), /* 24 */
+ /* 1 */ V(3, 1, 1),
+
+ /* 0010 ... */
+ /* 0 */ V(2, 2, 1), /* 26 */
+ /* 1 */ V(0, 2, 1)
+};
+
+static
+union huffpair const hufftab7[] = {
+ /* 0000 */ PTR(16, 4),
+ /* 0001 */ PTR(32, 4),
+ /* 0010 */ PTR(48, 2),
+ /* 0011 */ V(1, 1, 4),
+ /* 0100 */ V(0, 1, 3),
+ /* 0101 */ V(0, 1, 3),
+ /* 0110 */ V(1, 0, 3),
+ /* 0111 */ V(1, 0, 3),
+ /* 1000 */ V(0, 0, 1),
+ /* 1001 */ V(0, 0, 1),
+ /* 1010 */ V(0, 0, 1),
+ /* 1011 */ V(0, 0, 1),
+ /* 1100 */ V(0, 0, 1),
+ /* 1101 */ V(0, 0, 1),
+ /* 1110 */ V(0, 0, 1),
+ /* 1111 */ V(0, 0, 1),
+
+ /* 0000 ... */
+ /* 0000 */ PTR(52, 2), /* 16 */
+ /* 0001 */ PTR(56, 1),
+ /* 0010 */ PTR(58, 1),
+ /* 0011 */ V(1, 5, 4),
+ /* 0100 */ V(5, 1, 4),
+ /* 0101 */ PTR(60, 1),
+ /* 0110 */ V(5, 0, 4),
+ /* 0111 */ PTR(62, 1),
+ /* 1000 */ V(2, 4, 4),
+ /* 1001 */ V(4, 2, 4),
+ /* 1010 */ V(1, 4, 3),
+ /* 1011 */ V(1, 4, 3),
+ /* 1100 */ V(4, 1, 3),
+ /* 1101 */ V(4, 1, 3),
+ /* 1110 */ V(4, 0, 3),
+ /* 1111 */ V(4, 0, 3),
+
+ /* 0001 ... */
+ /* 0000 */ V(0, 4, 4), /* 32 */
+ /* 0001 */ V(2, 3, 4),
+ /* 0010 */ V(3, 2, 4),
+ /* 0011 */ V(0, 3, 4),
+ /* 0100 */ V(1, 3, 3),
+ /* 0101 */ V(1, 3, 3),
+ /* 0110 */ V(3, 1, 3),
+ /* 0111 */ V(3, 1, 3),
+ /* 1000 */ V(3, 0, 3),
+ /* 1001 */ V(3, 0, 3),
+ /* 1010 */ V(2, 2, 3),
+ /* 1011 */ V(2, 2, 3),
+ /* 1100 */ V(1, 2, 2),
+ /* 1101 */ V(1, 2, 2),
+ /* 1110 */ V(1, 2, 2),
+ /* 1111 */ V(1, 2, 2),
+
+ /* 0010 ... */
+ /* 00 */ V(2, 1, 1), /* 48 */
+ /* 01 */ V(2, 1, 1),
+ /* 10 */ V(0, 2, 2),
+ /* 11 */ V(2, 0, 2),
+
+ /* 0000 0000 ... */
+ /* 00 */ V(5, 5, 2), /* 52 */
+ /* 01 */ V(4, 5, 2),
+ /* 10 */ V(5, 4, 2),
+ /* 11 */ V(5, 3, 2),
+
+ /* 0000 0001 ... */
+ /* 0 */ V(3, 5, 1), /* 56 */
+ /* 1 */ V(4, 4, 1),
+
+ /* 0000 0010 ... */
+ /* 0 */ V(2, 5, 1), /* 58 */
+ /* 1 */ V(5, 2, 1),
+
+ /* 0000 0101 ... */
+ /* 0 */ V(0, 5, 1), /* 60 */
+ /* 1 */ V(3, 4, 1),
+
+ /* 0000 0111 ... */
+ /* 0 */ V(4, 3, 1), /* 62 */
+ /* 1 */ V(3, 3, 1)
+};
+
+# if 0
+/* this version saves 8 entries (16 bytes) at the expense of
+ an extra lookup in 4 out of 36 cases */
+static
+union huffpair const hufftab8[] = {
+ /* 0000 */ PTR(16, 4),
+ /* 0001 */ PTR(32, 2),
+ /* 0010 */ V(1, 2, 4),
+ /* 0011 */ V(2, 1, 4),
+ /* 0100 */ V(1, 1, 2),
+ /* 0101 */ V(1, 1, 2),
+ /* 0110 */ V(1, 1, 2),
+ /* 0111 */ V(1, 1, 2),
+ /* 1000 */ V(0, 1, 3),
+ /* 1001 */ V(0, 1, 3),
+ /* 1010 */ V(1, 0, 3),
+ /* 1011 */ V(1, 0, 3),
+ /* 1100 */ V(0, 0, 2),
+ /* 1101 */ V(0, 0, 2),
+ /* 1110 */ V(0, 0, 2),
+ /* 1111 */ V(0, 0, 2),
+
+ /* 0000 ... */
+ /* 0000 */ PTR(36, 3), /* 16 */
+ /* 0001 */ PTR(44, 2),
+ /* 0010 */ PTR(48, 1),
+ /* 0011 */ V(1, 5, 4),
+ /* 0100 */ V(5, 1, 4),
+ /* 0101 */ PTR(50, 1),
+ /* 0110 */ PTR(52, 1),
+ /* 0111 */ V(2, 4, 4),
+ /* 1000 */ V(4, 2, 4),
+ /* 1001 */ V(1, 4, 4),
+ /* 1010 */ V(4, 1, 3),
+ /* 1011 */ V(4, 1, 3),
+ /* 1100 */ V(0, 4, 4),
+ /* 1101 */ V(4, 0, 4),
+ /* 1110 */ V(2, 3, 4),
+ /* 1111 */ V(3, 2, 4),
+
+ /* 0001 ... */
+ /* 00 */ PTR(54, 2), /* 32 */
+ /* 01 */ V(2, 2, 2),
+ /* 10 */ V(0, 2, 2),
+ /* 11 */ V(2, 0, 2),
+
+ /* 0000 0000 ... */
+ /* 000 */ V(5, 5, 3), /* 36 */
+ /* 001 */ V(5, 4, 3),
+ /* 010 */ V(4, 5, 2),
+ /* 011 */ V(4, 5, 2),
+ /* 100 */ V(5, 3, 1),
+ /* 101 */ V(5, 3, 1),
+ /* 110 */ V(5, 3, 1),
+ /* 111 */ V(5, 3, 1),
+
+ /* 0000 0001 ... */
+ /* 00 */ V(3, 5, 2), /* 44 */
+ /* 01 */ V(4, 4, 2),
+ /* 10 */ V(2, 5, 1),
+ /* 11 */ V(2, 5, 1),
+
+ /* 0000 0010 ... */
+ /* 0 */ V(5, 2, 1), /* 48 */
+ /* 1 */ V(0, 5, 1),
+
+ /* 0000 0101 ... */
+ /* 0 */ V(3, 4, 1), /* 50 */
+ /* 1 */ V(4, 3, 1),
+
+ /* 0000 0110 ... */
+ /* 0 */ V(5, 0, 1), /* 52 */
+ /* 1 */ V(3, 3, 1),
+
+ /* 0001 00 ... */
+ /* 00 */ V(1, 3, 2), /* 54 */
+ /* 01 */ V(3, 1, 2),
+ /* 10 */ V(0, 3, 2),
+ /* 11 */ V(3, 0, 2),
+};
+# else
+static
+union huffpair const hufftab8[] = {
+ /* 0000 */ PTR(16, 4),
+ /* 0001 */ PTR(32, 4),
+ /* 0010 */ V(1, 2, 4),
+ /* 0011 */ V(2, 1, 4),
+ /* 0100 */ V(1, 1, 2),
+ /* 0101 */ V(1, 1, 2),
+ /* 0110 */ V(1, 1, 2),
+ /* 0111 */ V(1, 1, 2),
+ /* 1000 */ V(0, 1, 3),
+ /* 1001 */ V(0, 1, 3),
+ /* 1010 */ V(1, 0, 3),
+ /* 1011 */ V(1, 0, 3),
+ /* 1100 */ V(0, 0, 2),
+ /* 1101 */ V(0, 0, 2),
+ /* 1110 */ V(0, 0, 2),
+ /* 1111 */ V(0, 0, 2),
+
+ /* 0000 ... */
+ /* 0000 */ PTR(48, 3), /* 16 */
+ /* 0001 */ PTR(56, 2),
+ /* 0010 */ PTR(60, 1),
+ /* 0011 */ V(1, 5, 4),
+ /* 0100 */ V(5, 1, 4),
+ /* 0101 */ PTR(62, 1),
+ /* 0110 */ PTR(64, 1),
+ /* 0111 */ V(2, 4, 4),
+ /* 1000 */ V(4, 2, 4),
+ /* 1001 */ V(1, 4, 4),
+ /* 1010 */ V(4, 1, 3),
+ /* 1011 */ V(4, 1, 3),
+ /* 1100 */ V(0, 4, 4),
+ /* 1101 */ V(4, 0, 4),
+ /* 1110 */ V(2, 3, 4),
+ /* 1111 */ V(3, 2, 4),
+
+ /* 0001 ... */
+ /* 0000 */ V(1, 3, 4), /* 32 */
+ /* 0001 */ V(3, 1, 4),
+ /* 0010 */ V(0, 3, 4),
+ /* 0011 */ V(3, 0, 4),
+ /* 0100 */ V(2, 2, 2),
+ /* 0101 */ V(2, 2, 2),
+ /* 0110 */ V(2, 2, 2),
+ /* 0111 */ V(2, 2, 2),
+ /* 1000 */ V(0, 2, 2),
+ /* 1001 */ V(0, 2, 2),
+ /* 1010 */ V(0, 2, 2),
+ /* 1011 */ V(0, 2, 2),
+ /* 1100 */ V(2, 0, 2),
+ /* 1101 */ V(2, 0, 2),
+ /* 1110 */ V(2, 0, 2),
+ /* 1111 */ V(2, 0, 2),
+
+ /* 0000 0000 ... */
+ /* 000 */ V(5, 5, 3), /* 48 */
+ /* 001 */ V(5, 4, 3),
+ /* 010 */ V(4, 5, 2),
+ /* 011 */ V(4, 5, 2),
+ /* 100 */ V(5, 3, 1),
+ /* 101 */ V(5, 3, 1),
+ /* 110 */ V(5, 3, 1),
+ /* 111 */ V(5, 3, 1),
+
+ /* 0000 0001 ... */
+ /* 00 */ V(3, 5, 2), /* 56 */
+ /* 01 */ V(4, 4, 2),
+ /* 10 */ V(2, 5, 1),
+ /* 11 */ V(2, 5, 1),
+
+ /* 0000 0010 ... */
+ /* 0 */ V(5, 2, 1), /* 60 */
+ /* 1 */ V(0, 5, 1),
+
+ /* 0000 0101 ... */
+ /* 0 */ V(3, 4, 1), /* 62 */
+ /* 1 */ V(4, 3, 1),
+
+ /* 0000 0110 ... */
+ /* 0 */ V(5, 0, 1), /* 64 */
+ /* 1 */ V(3, 3, 1)
+};
+# endif
+
+static
+union huffpair const hufftab9[] = {
+ /* 0000 */ PTR(16, 4),
+ /* 0001 */ PTR(32, 3),
+ /* 0010 */ PTR(40, 2),
+ /* 0011 */ PTR(44, 2),
+ /* 0100 */ PTR(48, 1),
+ /* 0101 */ V(1, 2, 4),
+ /* 0110 */ V(2, 1, 4),
+ /* 0111 */ V(2, 0, 4),
+ /* 1000 */ V(1, 1, 3),
+ /* 1001 */ V(1, 1, 3),
+ /* 1010 */ V(0, 1, 3),
+ /* 1011 */ V(0, 1, 3),
+ /* 1100 */ V(1, 0, 3),
+ /* 1101 */ V(1, 0, 3),
+ /* 1110 */ V(0, 0, 3),
+ /* 1111 */ V(0, 0, 3),
+
+ /* 0000 ... */
+ /* 0000 */ PTR(50, 1), /* 16 */
+ /* 0001 */ V(3, 5, 4),
+ /* 0010 */ V(5, 3, 4),
+ /* 0011 */ PTR(52, 1),
+ /* 0100 */ V(4, 4, 4),
+ /* 0101 */ V(2, 5, 4),
+ /* 0110 */ V(5, 2, 4),
+ /* 0111 */ V(1, 5, 4),
+ /* 1000 */ V(5, 1, 3),
+ /* 1001 */ V(5, 1, 3),
+ /* 1010 */ V(3, 4, 3),
+ /* 1011 */ V(3, 4, 3),
+ /* 1100 */ V(4, 3, 3),
+ /* 1101 */ V(4, 3, 3),
+ /* 1110 */ V(5, 0, 4),
+ /* 1111 */ V(0, 4, 4),
+
+ /* 0001 ... */
+ /* 000 */ V(2, 4, 3), /* 32 */
+ /* 001 */ V(4, 2, 3),
+ /* 010 */ V(3, 3, 3),
+ /* 011 */ V(4, 0, 3),
+ /* 100 */ V(1, 4, 2),
+ /* 101 */ V(1, 4, 2),
+ /* 110 */ V(4, 1, 2),
+ /* 111 */ V(4, 1, 2),
+
+ /* 0010 ... */
+ /* 00 */ V(2, 3, 2), /* 40 */
+ /* 01 */ V(3, 2, 2),
+ /* 10 */ V(1, 3, 1),
+ /* 11 */ V(1, 3, 1),
+
+ /* 0011 ... */
+ /* 00 */ V(3, 1, 1), /* 44 */
+ /* 01 */ V(3, 1, 1),
+ /* 10 */ V(0, 3, 2),
+ /* 11 */ V(3, 0, 2),
+
+ /* 0100 ... */
+ /* 0 */ V(2, 2, 1), /* 48 */
+ /* 1 */ V(0, 2, 1),
+
+ /* 0000 0000 ... */
+ /* 0 */ V(5, 5, 1), /* 50 */
+ /* 1 */ V(4, 5, 1),
+
+ /* 0000 0011 ... */
+ /* 0 */ V(5, 4, 1), /* 52 */
+ /* 1 */ V(0, 5, 1)
+};
+
+static
+union huffpair const hufftab10[] = {
+ /* 0000 */ PTR(16, 4),
+ /* 0001 */ PTR(32, 4),
+ /* 0010 */ PTR(48, 2),
+ /* 0011 */ V(1, 1, 4),
+ /* 0100 */ V(0, 1, 3),
+ /* 0101 */ V(0, 1, 3),
+ /* 0110 */ V(1, 0, 3),
+ /* 0111 */ V(1, 0, 3),
+ /* 1000 */ V(0, 0, 1),
+ /* 1001 */ V(0, 0, 1),
+ /* 1010 */ V(0, 0, 1),
+ /* 1011 */ V(0, 0, 1),
+ /* 1100 */ V(0, 0, 1),
+ /* 1101 */ V(0, 0, 1),
+ /* 1110 */ V(0, 0, 1),
+ /* 1111 */ V(0, 0, 1),
+
+ /* 0000 ... */
+ /* 0000 */ PTR(52, 3), /* 16 */
+ /* 0001 */ PTR(60, 2),
+ /* 0010 */ PTR(64, 3),
+ /* 0011 */ PTR(72, 1),
+ /* 0100 */ PTR(74, 2),
+ /* 0101 */ PTR(78, 2),
+ /* 0110 */ PTR(82, 2),
+ /* 0111 */ V(1, 7, 4),
+ /* 1000 */ V(7, 1, 4),
+ /* 1001 */ PTR(86, 1),
+ /* 1010 */ PTR(88, 2),
+ /* 1011 */ PTR(92, 2),
+ /* 1100 */ V(1, 6, 4),
+ /* 1101 */ V(6, 1, 4),
+ /* 1110 */ V(6, 0, 4),
+ /* 1111 */ PTR(96, 1),
+
+ /* 0001 ... */
+ /* 0000 */ PTR(98, 1), /* 32 */
+ /* 0001 */ PTR(100, 1),
+ /* 0010 */ V(1, 4, 4),
+ /* 0011 */ V(4, 1, 4),
+ /* 0100 */ V(4, 0, 4),
+ /* 0101 */ V(2, 3, 4),
+ /* 0110 */ V(3, 2, 4),
+ /* 0111 */ V(0, 3, 4),
+ /* 1000 */ V(1, 3, 3),
+ /* 1001 */ V(1, 3, 3),
+ /* 1010 */ V(3, 1, 3),
+ /* 1011 */ V(3, 1, 3),
+ /* 1100 */ V(3, 0, 3),
+ /* 1101 */ V(3, 0, 3),
+ /* 1110 */ V(2, 2, 3),
+ /* 1111 */ V(2, 2, 3),
+
+ /* 0010 ... */
+ /* 00 */ V(1, 2, 2), /* 48 */
+ /* 01 */ V(2, 1, 2),
+ /* 10 */ V(0, 2, 2),
+ /* 11 */ V(2, 0, 2),
+
+ /* 0000 0000 ... */
+ /* 000 */ V(7, 7, 3), /* 52 */
+ /* 001 */ V(6, 7, 3),
+ /* 010 */ V(7, 6, 3),
+ /* 011 */ V(5, 7, 3),
+ /* 100 */ V(7, 5, 3),
+ /* 101 */ V(6, 6, 3),
+ /* 110 */ V(4, 7, 2),
+ /* 111 */ V(4, 7, 2),
+
+ /* 0000 0001 ... */
+ /* 00 */ V(7, 4, 2), /* 60 */
+ /* 01 */ V(5, 6, 2),
+ /* 10 */ V(6, 5, 2),
+ /* 11 */ V(3, 7, 2),
+
+ /* 0000 0010 ... */
+ /* 000 */ V(7, 3, 2), /* 64 */
+ /* 001 */ V(7, 3, 2),
+ /* 010 */ V(4, 6, 2),
+ /* 011 */ V(4, 6, 2),
+ /* 100 */ V(5, 5, 3),
+ /* 101 */ V(5, 4, 3),
+ /* 110 */ V(6, 3, 2),
+ /* 111 */ V(6, 3, 2),
+
+ /* 0000 0011 ... */
+ /* 0 */ V(2, 7, 1), /* 72 */
+ /* 1 */ V(7, 2, 1),
+
+ /* 0000 0100 ... */
+ /* 00 */ V(6, 4, 2), /* 74 */
+ /* 01 */ V(0, 7, 2),
+ /* 10 */ V(7, 0, 1),
+ /* 11 */ V(7, 0, 1),
+
+ /* 0000 0101 ... */
+ /* 00 */ V(6, 2, 1), /* 78 */
+ /* 01 */ V(6, 2, 1),
+ /* 10 */ V(4, 5, 2),
+ /* 11 */ V(3, 5, 2),
+
+ /* 0000 0110 ... */
+ /* 00 */ V(0, 6, 1), /* 82 */
+ /* 01 */ V(0, 6, 1),
+ /* 10 */ V(5, 3, 2),
+ /* 11 */ V(4, 4, 2),
+
+ /* 0000 1001 ... */
+ /* 0 */ V(3, 6, 1), /* 86 */
+ /* 1 */ V(2, 6, 1),
+
+ /* 0000 1010 ... */
+ /* 00 */ V(2, 5, 2), /* 88 */
+ /* 01 */ V(5, 2, 2),
+ /* 10 */ V(1, 5, 1),
+ /* 11 */ V(1, 5, 1),
+
+ /* 0000 1011 ... */
+ /* 00 */ V(5, 1, 1), /* 92 */
+ /* 01 */ V(5, 1, 1),
+ /* 10 */ V(3, 4, 2),
+ /* 11 */ V(4, 3, 2),
+
+ /* 0000 1111 ... */
+ /* 0 */ V(0, 5, 1), /* 96 */
+ /* 1 */ V(5, 0, 1),
+
+ /* 0001 0000 ... */
+ /* 0 */ V(2, 4, 1), /* 98 */
+ /* 1 */ V(4, 2, 1),
+
+ /* 0001 0001 ... */
+ /* 0 */ V(3, 3, 1), /* 100 */
+ /* 1 */ V(0, 4, 1)
+};
+
+static
+union huffpair const hufftab11[] = {
+ /* 0000 */ PTR(16, 4),
+ /* 0001 */ PTR(32, 4),
+ /* 0010 */ PTR(48, 4),
+ /* 0011 */ PTR(64, 3),
+ /* 0100 */ V(1, 2, 4),
+ /* 0101 */ PTR(72, 1),
+ /* 0110 */ V(1, 1, 3),
+ /* 0111 */ V(1, 1, 3),
+ /* 1000 */ V(0, 1, 3),
+ /* 1001 */ V(0, 1, 3),
+ /* 1010 */ V(1, 0, 3),
+ /* 1011 */ V(1, 0, 3),
+ /* 1100 */ V(0, 0, 2),
+ /* 1101 */ V(0, 0, 2),
+ /* 1110 */ V(0, 0, 2),
+ /* 1111 */ V(0, 0, 2),
+
+ /* 0000 ... */
+ /* 0000 */ PTR(74, 2), /* 16 */
+ /* 0001 */ PTR(78, 3),
+ /* 0010 */ PTR(86, 2),
+ /* 0011 */ PTR(90, 1),
+ /* 0100 */ PTR(92, 2),
+ /* 0101 */ V(2, 7, 4),
+ /* 0110 */ V(7, 2, 4),
+ /* 0111 */ PTR(96, 1),
+ /* 1000 */ V(7, 1, 3),
+ /* 1001 */ V(7, 1, 3),
+ /* 1010 */ V(1, 7, 4),
+ /* 1011 */ V(7, 0, 4),
+ /* 1100 */ V(3, 6, 4),
+ /* 1101 */ V(6, 3, 4),
+ /* 1110 */ V(6, 0, 4),
+ /* 1111 */ PTR(98, 1),
+
+ /* 0001 ... */
+ /* 0000 */ PTR(100, 1), /* 32 */
+ /* 0001 */ V(1, 5, 4),
+ /* 0010 */ V(6, 2, 3),
+ /* 0011 */ V(6, 2, 3),
+ /* 0100 */ V(2, 6, 4),
+ /* 0101 */ V(0, 6, 4),
+ /* 0110 */ V(1, 6, 3),
+ /* 0111 */ V(1, 6, 3),
+ /* 1000 */ V(6, 1, 3),
+ /* 1001 */ V(6, 1, 3),
+ /* 1010 */ V(5, 1, 4),
+ /* 1011 */ V(3, 4, 4),
+ /* 1100 */ V(5, 0, 4),
+ /* 1101 */ PTR(102, 1),
+ /* 1110 */ V(2, 4, 4),
+ /* 1111 */ V(4, 2, 4),
+
+ /* 0010 ... */
+ /* 0000 */ V(1, 4, 4), /* 48 */
+ /* 0001 */ V(4, 1, 4),
+ /* 0010 */ V(0, 4, 4),
+ /* 0011 */ V(4, 0, 4),
+ /* 0100 */ V(2, 3, 3),
+ /* 0101 */ V(2, 3, 3),
+ /* 0110 */ V(3, 2, 3),
+ /* 0111 */ V(3, 2, 3),
+ /* 1000 */ V(1, 3, 2),
+ /* 1001 */ V(1, 3, 2),
+ /* 1010 */ V(1, 3, 2),
+ /* 1011 */ V(1, 3, 2),
+ /* 1100 */ V(3, 1, 2),
+ /* 1101 */ V(3, 1, 2),
+ /* 1110 */ V(3, 1, 2),
+ /* 1111 */ V(3, 1, 2),
+
+ /* 0011 ... */
+ /* 000 */ V(0, 3, 3), /* 64 */
+ /* 001 */ V(3, 0, 3),
+ /* 010 */ V(2, 2, 2),
+ /* 011 */ V(2, 2, 2),
+ /* 100 */ V(2, 1, 1),
+ /* 101 */ V(2, 1, 1),
+ /* 110 */ V(2, 1, 1),
+ /* 111 */ V(2, 1, 1),
+
+ /* 0101 ... */
+ /* 0 */ V(0, 2, 1), /* 72 */
+ /* 1 */ V(2, 0, 1),
+
+ /* 0000 0000 ... */
+ /* 00 */ V(7, 7, 2), /* 74 */
+ /* 01 */ V(6, 7, 2),
+ /* 10 */ V(7, 6, 2),
+ /* 11 */ V(7, 5, 2),
+
+ /* 0000 0001 ... */
+ /* 000 */ V(6, 6, 2), /* 78 */
+ /* 001 */ V(6, 6, 2),
+ /* 010 */ V(4, 7, 2),
+ /* 011 */ V(4, 7, 2),
+ /* 100 */ V(7, 4, 2),
+ /* 101 */ V(7, 4, 2),
+ /* 110 */ V(5, 7, 3),
+ /* 111 */ V(5, 5, 3),
+
+ /* 0000 0010 ... */
+ /* 00 */ V(5, 6, 2), /* 86 */
+ /* 01 */ V(6, 5, 2),
+ /* 10 */ V(3, 7, 1),
+ /* 11 */ V(3, 7, 1),
+
+ /* 0000 0011 ... */
+ /* 0 */ V(7, 3, 1), /* 90 */
+ /* 1 */ V(4, 6, 1),
+
+ /* 0000 0100 ... */
+ /* 00 */ V(4, 5, 2), /* 92 */
+ /* 01 */ V(5, 4, 2),
+ /* 10 */ V(3, 5, 2),
+ /* 11 */ V(5, 3, 2),
+
+ /* 0000 0111 ... */
+ /* 0 */ V(6, 4, 1), /* 96 */
+ /* 1 */ V(0, 7, 1),
+
+ /* 0000 1111 ... */
+ /* 0 */ V(4, 4, 1), /* 98 */
+ /* 1 */ V(2, 5, 1),
+
+ /* 0001 0000 ... */
+ /* 0 */ V(5, 2, 1), /* 100 */
+ /* 1 */ V(0, 5, 1),
+
+ /* 0001 1101 ... */
+ /* 0 */ V(4, 3, 1), /* 102 */
+ /* 1 */ V(3, 3, 1)
+};
+
+static
+union huffpair const hufftab12[] = {
+ /* 0000 */ PTR(16, 4),
+ /* 0001 */ PTR(32, 4),
+ /* 0010 */ PTR(48, 4),
+ /* 0011 */ PTR(64, 2),
+ /* 0100 */ PTR(68, 3),
+ /* 0101 */ PTR(76, 1),
+ /* 0110 */ V(1, 2, 4),
+ /* 0111 */ V(2, 1, 4),
+ /* 1000 */ PTR(78, 1),
+ /* 1001 */ V(0, 0, 4),
+ /* 1010 */ V(1, 1, 3),
+ /* 1011 */ V(1, 1, 3),
+ /* 1100 */ V(0, 1, 3),
+ /* 1101 */ V(0, 1, 3),
+ /* 1110 */ V(1, 0, 3),
+ /* 1111 */ V(1, 0, 3),
+
+ /* 0000 ... */
+ /* 0000 */ PTR(80, 2), /* 16 */
+ /* 0001 */ PTR(84, 1),
+ /* 0010 */ PTR(86, 1),
+ /* 0011 */ PTR(88, 1),
+ /* 0100 */ V(5, 6, 4),
+ /* 0101 */ V(3, 7, 4),
+ /* 0110 */ PTR(90, 1),
+ /* 0111 */ V(2, 7, 4),
+ /* 1000 */ V(7, 2, 4),
+ /* 1001 */ V(4, 6, 4),
+ /* 1010 */ V(6, 4, 4),
+ /* 1011 */ V(1, 7, 4),
+ /* 1100 */ V(7, 1, 4),
+ /* 1101 */ PTR(92, 1),
+ /* 1110 */ V(3, 6, 4),
+ /* 1111 */ V(6, 3, 4),
+
+ /* 0001 ... */
+ /* 0000 */ V(4, 5, 4), /* 32 */
+ /* 0001 */ V(5, 4, 4),
+ /* 0010 */ V(4, 4, 4),
+ /* 0011 */ PTR(94, 1),
+ /* 0100 */ V(2, 6, 3),
+ /* 0101 */ V(2, 6, 3),
+ /* 0110 */ V(6, 2, 3),
+ /* 0111 */ V(6, 2, 3),
+ /* 1000 */ V(6, 1, 3),
+ /* 1001 */ V(6, 1, 3),
+ /* 1010 */ V(1, 6, 4),
+ /* 1011 */ V(6, 0, 4),
+ /* 1100 */ V(3, 5, 4),
+ /* 1101 */ V(5, 3, 4),
+ /* 1110 */ V(2, 5, 4),
+ /* 1111 */ V(5, 2, 4),
+
+ /* 0010 ... */
+ /* 0000 */ V(1, 5, 3), /* 48 */
+ /* 0001 */ V(1, 5, 3),
+ /* 0010 */ V(5, 1, 3),
+ /* 0011 */ V(5, 1, 3),
+ /* 0100 */ V(3, 4, 3),
+ /* 0101 */ V(3, 4, 3),
+ /* 0110 */ V(4, 3, 3),
+ /* 0111 */ V(4, 3, 3),
+ /* 1000 */ V(5, 0, 4),
+ /* 1001 */ V(0, 4, 4),
+ /* 1010 */ V(2, 4, 3),
+ /* 1011 */ V(2, 4, 3),
+ /* 1100 */ V(4, 2, 3),
+ /* 1101 */ V(4, 2, 3),
+ /* 1110 */ V(1, 4, 3),
+ /* 1111 */ V(1, 4, 3),
+
+ /* 0011 ... */
+ /* 00 */ V(3, 3, 2), /* 64 */
+ /* 01 */ V(4, 1, 2),
+ /* 10 */ V(2, 3, 2),
+ /* 11 */ V(3, 2, 2),
+
+ /* 0100 ... */
+ /* 000 */ V(4, 0, 3), /* 68 */
+ /* 001 */ V(0, 3, 3),
+ /* 010 */ V(3, 0, 2),
+ /* 011 */ V(3, 0, 2),
+ /* 100 */ V(1, 3, 1),
+ /* 101 */ V(1, 3, 1),
+ /* 110 */ V(1, 3, 1),
+ /* 111 */ V(1, 3, 1),
+
+ /* 0101 ... */
+ /* 0 */ V(3, 1, 1), /* 76 */
+ /* 1 */ V(2, 2, 1),
+
+ /* 1000 ... */
+ /* 0 */ V(0, 2, 1), /* 78 */
+ /* 1 */ V(2, 0, 1),
+
+ /* 0000 0000 ... */
+ /* 00 */ V(7, 7, 2), /* 80 */
+ /* 01 */ V(6, 7, 2),
+ /* 10 */ V(7, 6, 1),
+ /* 11 */ V(7, 6, 1),
+
+ /* 0000 0001 ... */
+ /* 0 */ V(5, 7, 1), /* 84 */
+ /* 1 */ V(7, 5, 1),
+
+ /* 0000 0010 ... */
+ /* 0 */ V(6, 6, 1), /* 86 */
+ /* 1 */ V(4, 7, 1),
+
+ /* 0000 0011 ... */
+ /* 0 */ V(7, 4, 1), /* 88 */
+ /* 1 */ V(6, 5, 1),
+
+ /* 0000 0110 ... */
+ /* 0 */ V(7, 3, 1), /* 90 */
+ /* 1 */ V(5, 5, 1),
+
+ /* 0000 1101 ... */
+ /* 0 */ V(0, 7, 1), /* 92 */
+ /* 1 */ V(7, 0, 1),
+
+ /* 0001 0011 ... */
+ /* 0 */ V(0, 6, 1), /* 94 */
+ /* 1 */ V(0, 5, 1)
+};
+
+static
+union huffpair const hufftab13[] = {
+ /* 0000 */ PTR(16, 4),
+ /* 0001 */ PTR(32, 4),
+ /* 0010 */ PTR(48, 4),
+ /* 0011 */ PTR(64, 2),
+ /* 0100 */ V(1, 1, 4),
+ /* 0101 */ V(0, 1, 4),
+ /* 0110 */ V(1, 0, 3),
+ /* 0111 */ V(1, 0, 3),
+ /* 1000 */ V(0, 0, 1),
+ /* 1001 */ V(0, 0, 1),
+ /* 1010 */ V(0, 0, 1),
+ /* 1011 */ V(0, 0, 1),
+ /* 1100 */ V(0, 0, 1),
+ /* 1101 */ V(0, 0, 1),
+ /* 1110 */ V(0, 0, 1),
+ /* 1111 */ V(0, 0, 1),
+
+ /* 0000 ... */
+ /* 0000 */ PTR(68, 4), /* 16 */
+ /* 0001 */ PTR(84, 4),
+ /* 0010 */ PTR(100, 4),
+ /* 0011 */ PTR(116, 4),
+ /* 0100 */ PTR(132, 4),
+ /* 0101 */ PTR(148, 4),
+ /* 0110 */ PTR(164, 3),
+ /* 0111 */ PTR(172, 3),
+ /* 1000 */ PTR(180, 3),
+ /* 1001 */ PTR(188, 3),
+ /* 1010 */ PTR(196, 3),
+ /* 1011 */ PTR(204, 3),
+ /* 1100 */ PTR(212, 1),
+ /* 1101 */ PTR(214, 2),
+ /* 1110 */ PTR(218, 3),
+ /* 1111 */ PTR(226, 1),
+
+ /* 0001 ... */
+ /* 0000 */ PTR(228, 2), /* 32 */
+ /* 0001 */ PTR(232, 2),
+ /* 0010 */ PTR(236, 2),
+ /* 0011 */ PTR(240, 2),
+ /* 0100 */ V(8, 1, 4),
+ /* 0101 */ PTR(244, 1),
+ /* 0110 */ PTR(246, 1),
+ /* 0111 */ PTR(248, 1),
+ /* 1000 */ PTR(250, 2),
+ /* 1001 */ PTR(254, 1),
+ /* 1010 */ V(1, 5, 4),
+ /* 1011 */ V(5, 1, 4),
+ /* 1100 */ PTR(256, 1),
+ /* 1101 */ PTR(258, 1),
+ /* 1110 */ PTR(260, 1),
+ /* 1111 */ V(1, 4, 4),
+
+ /* 0010 ... */
+ /* 0000 */ V(4, 1, 3), /* 48 */
+ /* 0001 */ V(4, 1, 3),
+ /* 0010 */ V(0, 4, 4),
+ /* 0011 */ V(4, 0, 4),
+ /* 0100 */ V(2, 3, 4),
+ /* 0101 */ V(3, 2, 4),
+ /* 0110 */ V(1, 3, 3),
+ /* 0111 */ V(1, 3, 3),
+ /* 1000 */ V(3, 1, 3),
+ /* 1001 */ V(3, 1, 3),
+ /* 1010 */ V(0, 3, 3),
+ /* 1011 */ V(0, 3, 3),
+ /* 1100 */ V(3, 0, 3),
+ /* 1101 */ V(3, 0, 3),
+ /* 1110 */ V(2, 2, 3),
+ /* 1111 */ V(2, 2, 3),
+
+ /* 0011 ... */
+ /* 00 */ V(1, 2, 2), /* 64 */
+ /* 01 */ V(2, 1, 2),
+ /* 10 */ V(0, 2, 2),
+ /* 11 */ V(2, 0, 2),
+
+ /* 0000 0000 ... */
+ /* 0000 */ PTR(262, 4), /* 68 */
+ /* 0001 */ PTR(278, 4),
+ /* 0010 */ PTR(294, 4),
+ /* 0011 */ PTR(310, 3),
+ /* 0100 */ PTR(318, 2),
+ /* 0101 */ PTR(322, 2),
+ /* 0110 */ PTR(326, 3),
+ /* 0111 */ PTR(334, 2),
+ /* 1000 */ PTR(338, 1),
+ /* 1001 */ PTR(340, 2),
+ /* 1010 */ PTR(344, 2),
+ /* 1011 */ PTR(348, 2),
+ /* 1100 */ PTR(352, 2),
+ /* 1101 */ PTR(356, 2),
+ /* 1110 */ V(1, 15, 4),
+ /* 1111 */ V(15, 1, 4),
+
+ /* 0000 0001 ... */
+ /* 0000 */ V(15, 0, 4), /* 84 */
+ /* 0001 */ PTR(360, 1),
+ /* 0010 */ PTR(362, 1),
+ /* 0011 */ PTR(364, 1),
+ /* 0100 */ V(14, 2, 4),
+ /* 0101 */ PTR(366, 1),
+ /* 0110 */ V(1, 14, 4),
+ /* 0111 */ V(14, 1, 4),
+ /* 1000 */ PTR(368, 1),
+ /* 1001 */ PTR(370, 1),
+ /* 1010 */ PTR(372, 1),
+ /* 1011 */ PTR(374, 1),
+ /* 1100 */ PTR(376, 1),
+ /* 1101 */ PTR(378, 1),
+ /* 1110 */ V(12, 6, 4),
+ /* 1111 */ V(3, 13, 4),
+
+ /* 0000 0010 ... */
+ /* 0000 */ PTR(380, 1), /* 100 */
+ /* 0001 */ V(2, 13, 4),
+ /* 0010 */ V(13, 2, 4),
+ /* 0011 */ V(1, 13, 4),
+ /* 0100 */ V(11, 7, 4),
+ /* 0101 */ PTR(382, 1),
+ /* 0110 */ PTR(384, 1),
+ /* 0111 */ V(12, 3, 4),
+ /* 1000 */ PTR(386, 1),
+ /* 1001 */ V(4, 11, 4),
+ /* 1010 */ V(13, 1, 3),
+ /* 1011 */ V(13, 1, 3),
+ /* 1100 */ V(0, 13, 4),
+ /* 1101 */ V(13, 0, 4),
+ /* 1110 */ V(8, 10, 4),
+ /* 1111 */ V(10, 8, 4),
+
+ /* 0000 0011 ... */
+ /* 0000 */ V(4, 12, 4), /* 116 */
+ /* 0001 */ V(12, 4, 4),
+ /* 0010 */ V(6, 11, 4),
+ /* 0011 */ V(11, 6, 4),
+ /* 0100 */ V(3, 12, 3),
+ /* 0101 */ V(3, 12, 3),
+ /* 0110 */ V(2, 12, 3),
+ /* 0111 */ V(2, 12, 3),
+ /* 1000 */ V(12, 2, 3),
+ /* 1001 */ V(12, 2, 3),
+ /* 1010 */ V(5, 11, 3),
+ /* 1011 */ V(5, 11, 3),
+ /* 1100 */ V(11, 5, 4),
+ /* 1101 */ V(8, 9, 4),
+ /* 1110 */ V(1, 12, 3),
+ /* 1111 */ V(1, 12, 3),
+
+ /* 0000 0100 ... */
+ /* 0000 */ V(12, 1, 3), /* 132 */
+ /* 0001 */ V(12, 1, 3),
+ /* 0010 */ V(9, 8, 4),
+ /* 0011 */ V(0, 12, 4),
+ /* 0100 */ V(12, 0, 3),
+ /* 0101 */ V(12, 0, 3),
+ /* 0110 */ V(11, 4, 4),
+ /* 0111 */ V(6, 10, 4),
+ /* 1000 */ V(10, 6, 4),
+ /* 1001 */ V(7, 9, 4),
+ /* 1010 */ V(3, 11, 3),
+ /* 1011 */ V(3, 11, 3),
+ /* 1100 */ V(11, 3, 3),
+ /* 1101 */ V(11, 3, 3),
+ /* 1110 */ V(8, 8, 4),
+ /* 1111 */ V(5, 10, 4),
+
+ /* 0000 0101 ... */
+ /* 0000 */ V(2, 11, 3), /* 148 */
+ /* 0001 */ V(2, 11, 3),
+ /* 0010 */ V(10, 5, 4),
+ /* 0011 */ V(6, 9, 4),
+ /* 0100 */ V(10, 4, 3),
+ /* 0101 */ V(10, 4, 3),
+ /* 0110 */ V(7, 8, 4),
+ /* 0111 */ V(8, 7, 4),
+ /* 1000 */ V(9, 4, 3),
+ /* 1001 */ V(9, 4, 3),
+ /* 1010 */ V(7, 7, 4),
+ /* 1011 */ V(7, 6, 4),
+ /* 1100 */ V(11, 2, 2),
+ /* 1101 */ V(11, 2, 2),
+ /* 1110 */ V(11, 2, 2),
+ /* 1111 */ V(11, 2, 2),
+
+ /* 0000 0110 ... */
+ /* 000 */ V(1, 11, 2), /* 164 */
+ /* 001 */ V(1, 11, 2),
+ /* 010 */ V(11, 1, 2),
+ /* 011 */ V(11, 1, 2),
+ /* 100 */ V(0, 11, 3),
+ /* 101 */ V(11, 0, 3),
+ /* 110 */ V(9, 6, 3),
+ /* 111 */ V(4, 10, 3),
+
+ /* 0000 0111 ... */
+ /* 000 */ V(3, 10, 3), /* 172 */
+ /* 001 */ V(10, 3, 3),
+ /* 010 */ V(5, 9, 3),
+ /* 011 */ V(9, 5, 3),
+ /* 100 */ V(2, 10, 2),
+ /* 101 */ V(2, 10, 2),
+ /* 110 */ V(10, 2, 2),
+ /* 111 */ V(10, 2, 2),
+
+ /* 0000 1000 ... */
+ /* 000 */ V(1, 10, 2), /* 180 */
+ /* 001 */ V(1, 10, 2),
+ /* 010 */ V(10, 1, 2),
+ /* 011 */ V(10, 1, 2),
+ /* 100 */ V(0, 10, 3),
+ /* 101 */ V(6, 8, 3),
+ /* 110 */ V(10, 0, 2),
+ /* 111 */ V(10, 0, 2),
+
+ /* 0000 1001 ... */
+ /* 000 */ V(8, 6, 3), /* 188 */
+ /* 001 */ V(4, 9, 3),
+ /* 010 */ V(9, 3, 2),
+ /* 011 */ V(9, 3, 2),
+ /* 100 */ V(3, 9, 3),
+ /* 101 */ V(5, 8, 3),
+ /* 110 */ V(8, 5, 3),
+ /* 111 */ V(6, 7, 3),
+
+ /* 0000 1010 ... */
+ /* 000 */ V(2, 9, 2), /* 196 */
+ /* 001 */ V(2, 9, 2),
+ /* 010 */ V(9, 2, 2),
+ /* 011 */ V(9, 2, 2),
+ /* 100 */ V(5, 7, 3),
+ /* 101 */ V(7, 5, 3),
+ /* 110 */ V(3, 8, 2),
+ /* 111 */ V(3, 8, 2),
+
+ /* 0000 1011 ... */
+ /* 000 */ V(8, 3, 2), /* 204 */
+ /* 001 */ V(8, 3, 2),
+ /* 010 */ V(6, 6, 3),
+ /* 011 */ V(4, 7, 3),
+ /* 100 */ V(7, 4, 3),
+ /* 101 */ V(5, 6, 3),
+ /* 110 */ V(6, 5, 3),
+ /* 111 */ V(7, 3, 3),
+
+ /* 0000 1100 ... */
+ /* 0 */ V(1, 9, 1), /* 212 */
+ /* 1 */ V(9, 1, 1),
+
+ /* 0000 1101 ... */
+ /* 00 */ V(0, 9, 2), /* 214 */
+ /* 01 */ V(9, 0, 2),
+ /* 10 */ V(4, 8, 2),
+ /* 11 */ V(8, 4, 2),
+
+ /* 0000 1110 ... */
+ /* 000 */ V(7, 2, 2), /* 218 */
+ /* 001 */ V(7, 2, 2),
+ /* 010 */ V(4, 6, 3),
+ /* 011 */ V(6, 4, 3),
+ /* 100 */ V(2, 8, 1),
+ /* 101 */ V(2, 8, 1),
+ /* 110 */ V(2, 8, 1),
+ /* 111 */ V(2, 8, 1),
+
+ /* 0000 1111 ... */
+ /* 0 */ V(8, 2, 1), /* 226 */
+ /* 1 */ V(1, 8, 1),
+
+ /* 0001 0000 ... */
+ /* 00 */ V(3, 7, 2), /* 228 */
+ /* 01 */ V(2, 7, 2),
+ /* 10 */ V(1, 7, 1),
+ /* 11 */ V(1, 7, 1),
+
+ /* 0001 0001 ... */
+ /* 00 */ V(7, 1, 1), /* 232 */
+ /* 01 */ V(7, 1, 1),
+ /* 10 */ V(5, 5, 2),
+ /* 11 */ V(0, 7, 2),
+
+ /* 0001 0010 ... */
+ /* 00 */ V(7, 0, 2), /* 236 */
+ /* 01 */ V(3, 6, 2),
+ /* 10 */ V(6, 3, 2),
+ /* 11 */ V(4, 5, 2),
+
+ /* 0001 0011 ... */
+ /* 00 */ V(5, 4, 2), /* 240 */
+ /* 01 */ V(2, 6, 2),
+ /* 10 */ V(6, 2, 2),
+ /* 11 */ V(3, 5, 2),
+
+ /* 0001 0101 ... */
+ /* 0 */ V(0, 8, 1), /* 244 */
+ /* 1 */ V(8, 0, 1),
+
+ /* 0001 0110 ... */
+ /* 0 */ V(1, 6, 1), /* 246 */
+ /* 1 */ V(6, 1, 1),
+
+ /* 0001 0111 ... */
+ /* 0 */ V(0, 6, 1), /* 248 */
+ /* 1 */ V(6, 0, 1),
+
+ /* 0001 1000 ... */
+ /* 00 */ V(5, 3, 2), /* 250 */
+ /* 01 */ V(4, 4, 2),
+ /* 10 */ V(2, 5, 1),
+ /* 11 */ V(2, 5, 1),
+
+ /* 0001 1001 ... */
+ /* 0 */ V(5, 2, 1), /* 254 */
+ /* 1 */ V(0, 5, 1),
+
+ /* 0001 1100 ... */
+ /* 0 */ V(3, 4, 1), /* 256 */
+ /* 1 */ V(4, 3, 1),
+
+ /* 0001 1101 ... */
+ /* 0 */ V(5, 0, 1), /* 258 */
+ /* 1 */ V(2, 4, 1),
+
+ /* 0001 1110 ... */
+ /* 0 */ V(4, 2, 1), /* 260 */
+ /* 1 */ V(3, 3, 1),
+
+ /* 0000 0000 0000 ... */
+ /* 0000 */ PTR(388, 3), /* 262 */
+ /* 0001 */ V(15, 15, 4),
+ /* 0010 */ V(14, 15, 4),
+ /* 0011 */ V(13, 15, 4),
+ /* 0100 */ V(14, 14, 4),
+ /* 0101 */ V(12, 15, 4),
+ /* 0110 */ V(13, 14, 4),
+ /* 0111 */ V(11, 15, 4),
+ /* 1000 */ V(15, 11, 4),
+ /* 1001 */ V(12, 14, 4),
+ /* 1010 */ V(13, 12, 4),
+ /* 1011 */ PTR(396, 1),
+ /* 1100 */ V(14, 12, 3),
+ /* 1101 */ V(14, 12, 3),
+ /* 1110 */ V(13, 13, 3),
+ /* 1111 */ V(13, 13, 3),
+
+ /* 0000 0000 0001 ... */
+ /* 0000 */ V(15, 10, 4), /* 278 */
+ /* 0001 */ V(12, 13, 4),
+ /* 0010 */ V(11, 14, 3),
+ /* 0011 */ V(11, 14, 3),
+ /* 0100 */ V(14, 11, 3),
+ /* 0101 */ V(14, 11, 3),
+ /* 0110 */ V(9, 15, 3),
+ /* 0111 */ V(9, 15, 3),
+ /* 1000 */ V(15, 9, 3),
+ /* 1001 */ V(15, 9, 3),
+ /* 1010 */ V(14, 10, 3),
+ /* 1011 */ V(14, 10, 3),
+ /* 1100 */ V(11, 13, 3),
+ /* 1101 */ V(11, 13, 3),
+ /* 1110 */ V(13, 11, 3),
+ /* 1111 */ V(13, 11, 3),
+
+ /* 0000 0000 0010 ... */
+ /* 0000 */ V(8, 15, 3), /* 294 */
+ /* 0001 */ V(8, 15, 3),
+ /* 0010 */ V(15, 8, 3),
+ /* 0011 */ V(15, 8, 3),
+ /* 0100 */ V(12, 12, 3),
+ /* 0101 */ V(12, 12, 3),
+ /* 0110 */ V(10, 14, 4),
+ /* 0111 */ V(9, 14, 4),
+ /* 1000 */ V(8, 14, 3),
+ /* 1001 */ V(8, 14, 3),
+ /* 1010 */ V(7, 15, 4),
+ /* 1011 */ V(7, 14, 4),
+ /* 1100 */ V(15, 7, 2),
+ /* 1101 */ V(15, 7, 2),
+ /* 1110 */ V(15, 7, 2),
+ /* 1111 */ V(15, 7, 2),
+
+ /* 0000 0000 0011 ... */
+ /* 000 */ V(13, 10, 2), /* 310 */
+ /* 001 */ V(13, 10, 2),
+ /* 010 */ V(10, 13, 3),
+ /* 011 */ V(11, 12, 3),
+ /* 100 */ V(12, 11, 3),
+ /* 101 */ V(15, 6, 3),
+ /* 110 */ V(6, 15, 2),
+ /* 111 */ V(6, 15, 2),
+
+ /* 0000 0000 0100 ... */
+ /* 00 */ V(14, 8, 2), /* 318 */
+ /* 01 */ V(5, 15, 2),
+ /* 10 */ V(9, 13, 2),
+ /* 11 */ V(13, 9, 2),
+
+ /* 0000 0000 0101 ... */
+ /* 00 */ V(15, 5, 2), /* 322 */
+ /* 01 */ V(14, 7, 2),
+ /* 10 */ V(10, 12, 2),
+ /* 11 */ V(11, 11, 2),
+
+ /* 0000 0000 0110 ... */
+ /* 000 */ V(4, 15, 2), /* 326 */
+ /* 001 */ V(4, 15, 2),
+ /* 010 */ V(15, 4, 2),
+ /* 011 */ V(15, 4, 2),
+ /* 100 */ V(12, 10, 3),
+ /* 101 */ V(14, 6, 3),
+ /* 110 */ V(15, 3, 2),
+ /* 111 */ V(15, 3, 2),
+
+ /* 0000 0000 0111 ... */
+ /* 00 */ V(3, 15, 1), /* 334 */
+ /* 01 */ V(3, 15, 1),
+ /* 10 */ V(8, 13, 2),
+ /* 11 */ V(13, 8, 2),
+
+ /* 0000 0000 1000 ... */
+ /* 0 */ V(2, 15, 1), /* 338 */
+ /* 1 */ V(15, 2, 1),
+
+ /* 0000 0000 1001 ... */
+ /* 00 */ V(6, 14, 2), /* 340 */
+ /* 01 */ V(9, 12, 2),
+ /* 10 */ V(0, 15, 1),
+ /* 11 */ V(0, 15, 1),
+
+ /* 0000 0000 1010 ... */
+ /* 00 */ V(12, 9, 2), /* 344 */
+ /* 01 */ V(5, 14, 2),
+ /* 10 */ V(10, 11, 1),
+ /* 11 */ V(10, 11, 1),
+
+ /* 0000 0000 1011 ... */
+ /* 00 */ V(7, 13, 2), /* 348 */
+ /* 01 */ V(13, 7, 2),
+ /* 10 */ V(4, 14, 1),
+ /* 11 */ V(4, 14, 1),
+
+ /* 0000 0000 1100 ... */
+ /* 00 */ V(12, 8, 2), /* 352 */
+ /* 01 */ V(13, 6, 2),
+ /* 10 */ V(3, 14, 1),
+ /* 11 */ V(3, 14, 1),
+
+ /* 0000 0000 1101 ... */
+ /* 00 */ V(11, 9, 1), /* 356 */
+ /* 01 */ V(11, 9, 1),
+ /* 10 */ V(9, 11, 2),
+ /* 11 */ V(10, 10, 2),
+
+ /* 0000 0001 0001 ... */
+ /* 0 */ V(11, 10, 1), /* 360 */
+ /* 1 */ V(14, 5, 1),
+
+ /* 0000 0001 0010 ... */
+ /* 0 */ V(14, 4, 1), /* 362 */
+ /* 1 */ V(8, 12, 1),
+
+ /* 0000 0001 0011 ... */
+ /* 0 */ V(6, 13, 1), /* 364 */
+ /* 1 */ V(14, 3, 1),
+
+ /* 0000 0001 0101 ... */
+ /* 0 */ V(2, 14, 1), /* 366 */
+ /* 1 */ V(0, 14, 1),
+
+ /* 0000 0001 1000 ... */
+ /* 0 */ V(14, 0, 1), /* 368 */
+ /* 1 */ V(5, 13, 1),
+
+ /* 0000 0001 1001 ... */
+ /* 0 */ V(13, 5, 1), /* 370 */
+ /* 1 */ V(7, 12, 1),
+
+ /* 0000 0001 1010 ... */
+ /* 0 */ V(12, 7, 1), /* 372 */
+ /* 1 */ V(4, 13, 1),
+
+ /* 0000 0001 1011 ... */
+ /* 0 */ V(8, 11, 1), /* 374 */
+ /* 1 */ V(11, 8, 1),
+
+ /* 0000 0001 1100 ... */
+ /* 0 */ V(13, 4, 1), /* 376 */
+ /* 1 */ V(9, 10, 1),
+
+ /* 0000 0001 1101 ... */
+ /* 0 */ V(10, 9, 1), /* 378 */
+ /* 1 */ V(6, 12, 1),
+
+ /* 0000 0010 0000 ... */
+ /* 0 */ V(13, 3, 1), /* 380 */
+ /* 1 */ V(7, 11, 1),
+
+ /* 0000 0010 0101 ... */
+ /* 0 */ V(5, 12, 1), /* 382 */
+ /* 1 */ V(12, 5, 1),
+
+ /* 0000 0010 0110 ... */
+ /* 0 */ V(9, 9, 1), /* 384 */
+ /* 1 */ V(7, 10, 1),
+
+ /* 0000 0010 1000 ... */
+ /* 0 */ V(10, 7, 1), /* 386 */
+ /* 1 */ V(9, 7, 1),
+
+ /* 0000 0000 0000 0000 ... */
+ /* 000 */ V(15, 14, 3), /* 388 */
+ /* 001 */ V(15, 12, 3),
+ /* 010 */ V(15, 13, 2),
+ /* 011 */ V(15, 13, 2),
+ /* 100 */ V(14, 13, 1),
+ /* 101 */ V(14, 13, 1),
+ /* 110 */ V(14, 13, 1),
+ /* 111 */ V(14, 13, 1),
+
+ /* 0000 0000 0000 1011 ... */
+ /* 0 */ V(10, 15, 1), /* 396 */
+ /* 1 */ V(14, 9, 1)
+};
+
+static
+union huffpair const hufftab15[] = {
+ /* 0000 */ PTR(16, 4),
+ /* 0001 */ PTR(32, 4),
+ /* 0010 */ PTR(48, 4),
+ /* 0011 */ PTR(64, 4),
+ /* 0100 */ PTR(80, 4),
+ /* 0101 */ PTR(96, 3),
+ /* 0110 */ PTR(104, 3),
+ /* 0111 */ PTR(112, 2),
+ /* 1000 */ PTR(116, 1),
+ /* 1001 */ PTR(118, 1),
+ /* 1010 */ V(1, 1, 3),
+ /* 1011 */ V(1, 1, 3),
+ /* 1100 */ V(0, 1, 4),
+ /* 1101 */ V(1, 0, 4),
+ /* 1110 */ V(0, 0, 3),
+ /* 1111 */ V(0, 0, 3),
+
+ /* 0000 ... */
+ /* 0000 */ PTR(120, 4), /* 16 */
+ /* 0001 */ PTR(136, 4),
+ /* 0010 */ PTR(152, 4),
+ /* 0011 */ PTR(168, 4),
+ /* 0100 */ PTR(184, 4),
+ /* 0101 */ PTR(200, 3),
+ /* 0110 */ PTR(208, 3),
+ /* 0111 */ PTR(216, 4),
+ /* 1000 */ PTR(232, 3),
+ /* 1001 */ PTR(240, 3),
+ /* 1010 */ PTR(248, 3),
+ /* 1011 */ PTR(256, 3),
+ /* 1100 */ PTR(264, 2),
+ /* 1101 */ PTR(268, 3),
+ /* 1110 */ PTR(276, 3),
+ /* 1111 */ PTR(284, 2),
+
+ /* 0001 ... */
+ /* 0000 */ PTR(288, 2), /* 32 */
+ /* 0001 */ PTR(292, 2),
+ /* 0010 */ PTR(296, 2),
+ /* 0011 */ PTR(300, 2),
+ /* 0100 */ PTR(304, 2),
+ /* 0101 */ PTR(308, 2),
+ /* 0110 */ PTR(312, 2),
+ /* 0111 */ PTR(316, 2),
+ /* 1000 */ PTR(320, 1),
+ /* 1001 */ PTR(322, 1),
+ /* 1010 */ PTR(324, 1),
+ /* 1011 */ PTR(326, 2),
+ /* 1100 */ PTR(330, 1),
+ /* 1101 */ PTR(332, 1),
+ /* 1110 */ PTR(334, 2),
+ /* 1111 */ PTR(338, 1),
+
+ /* 0010 ... */
+ /* 0000 */ PTR(340, 1), /* 48 */
+ /* 0001 */ PTR(342, 1),
+ /* 0010 */ V(9, 1, 4),
+ /* 0011 */ PTR(344, 1),
+ /* 0100 */ PTR(346, 1),
+ /* 0101 */ PTR(348, 1),
+ /* 0110 */ PTR(350, 1),
+ /* 0111 */ PTR(352, 1),
+ /* 1000 */ V(2, 8, 4),
+ /* 1001 */ V(8, 2, 4),
+ /* 1010 */ V(1, 8, 4),
+ /* 1011 */ V(8, 1, 4),
+ /* 1100 */ PTR(354, 1),
+ /* 1101 */ PTR(356, 1),
+ /* 1110 */ PTR(358, 1),
+ /* 1111 */ PTR(360, 1),
+
+ /* 0011 ... */
+ /* 0000 */ V(2, 7, 4), /* 64 */
+ /* 0001 */ V(7, 2, 4),
+ /* 0010 */ V(6, 4, 4),
+ /* 0011 */ V(1, 7, 4),
+ /* 0100 */ V(5, 5, 4),
+ /* 0101 */ V(7, 1, 4),
+ /* 0110 */ PTR(362, 1),
+ /* 0111 */ V(3, 6, 4),
+ /* 1000 */ V(6, 3, 4),
+ /* 1001 */ V(4, 5, 4),
+ /* 1010 */ V(5, 4, 4),
+ /* 1011 */ V(2, 6, 4),
+ /* 1100 */ V(6, 2, 4),
+ /* 1101 */ V(1, 6, 4),
+ /* 1110 */ PTR(364, 1),
+ /* 1111 */ V(3, 5, 4),
+
+ /* 0100 ... */
+ /* 0000 */ V(6, 1, 3), /* 80 */
+ /* 0001 */ V(6, 1, 3),
+ /* 0010 */ V(5, 3, 4),
+ /* 0011 */ V(4, 4, 4),
+ /* 0100 */ V(2, 5, 3),
+ /* 0101 */ V(2, 5, 3),
+ /* 0110 */ V(5, 2, 3),
+ /* 0111 */ V(5, 2, 3),
+ /* 1000 */ V(1, 5, 3),
+ /* 1001 */ V(1, 5, 3),
+ /* 1010 */ V(5, 1, 3),
+ /* 1011 */ V(5, 1, 3),
+ /* 1100 */ V(0, 5, 4),
+ /* 1101 */ V(5, 0, 4),
+ /* 1110 */ V(3, 4, 3),
+ /* 1111 */ V(3, 4, 3),
+
+ /* 0101 ... */
+ /* 000 */ V(4, 3, 3), /* 96 */
+ /* 001 */ V(2, 4, 3),
+ /* 010 */ V(4, 2, 3),
+ /* 011 */ V(3, 3, 3),
+ /* 100 */ V(4, 1, 2),
+ /* 101 */ V(4, 1, 2),
+ /* 110 */ V(1, 4, 3),
+ /* 111 */ V(0, 4, 3),
+
+ /* 0110 ... */
+ /* 000 */ V(2, 3, 2), /* 104 */
+ /* 001 */ V(2, 3, 2),
+ /* 010 */ V(3, 2, 2),
+ /* 011 */ V(3, 2, 2),
+ /* 100 */ V(4, 0, 3),
+ /* 101 */ V(0, 3, 3),
+ /* 110 */ V(1, 3, 2),
+ /* 111 */ V(1, 3, 2),
+
+ /* 0111 ... */
+ /* 00 */ V(3, 1, 2), /* 112 */
+ /* 01 */ V(3, 0, 2),
+ /* 10 */ V(2, 2, 1),
+ /* 11 */ V(2, 2, 1),
+
+ /* 1000 ... */
+ /* 0 */ V(1, 2, 1), /* 116 */
+ /* 1 */ V(2, 1, 1),
+
+ /* 1001 ... */
+ /* 0 */ V(0, 2, 1), /* 118 */
+ /* 1 */ V(2, 0, 1),
+
+ /* 0000 0000 ... */
+ /* 0000 */ PTR(366, 1), /* 120 */
+ /* 0001 */ PTR(368, 1),
+ /* 0010 */ V(14, 14, 4),
+ /* 0011 */ PTR(370, 1),
+ /* 0100 */ PTR(372, 1),
+ /* 0101 */ PTR(374, 1),
+ /* 0110 */ V(15, 11, 4),
+ /* 0111 */ PTR(376, 1),
+ /* 1000 */ V(13, 13, 4),
+ /* 1001 */ V(10, 15, 4),
+ /* 1010 */ V(15, 10, 4),
+ /* 1011 */ V(11, 14, 4),
+ /* 1100 */ V(14, 11, 4),
+ /* 1101 */ V(12, 13, 4),
+ /* 1110 */ V(13, 12, 4),
+ /* 1111 */ V(9, 15, 4),
+
+ /* 0000 0001 ... */
+ /* 0000 */ V(15, 9, 4), /* 136 */
+ /* 0001 */ V(14, 10, 4),
+ /* 0010 */ V(11, 13, 4),
+ /* 0011 */ V(13, 11, 4),
+ /* 0100 */ V(8, 15, 4),
+ /* 0101 */ V(15, 8, 4),
+ /* 0110 */ V(12, 12, 4),
+ /* 0111 */ V(9, 14, 4),
+ /* 1000 */ V(14, 9, 4),
+ /* 1001 */ V(7, 15, 4),
+ /* 1010 */ V(15, 7, 4),
+ /* 1011 */ V(10, 13, 4),
+ /* 1100 */ V(13, 10, 4),
+ /* 1101 */ V(11, 12, 4),
+ /* 1110 */ V(6, 15, 4),
+ /* 1111 */ PTR(378, 1),
+
+ /* 0000 0010 ... */
+ /* 0000 */ V(12, 11, 3), /* 152 */
+ /* 0001 */ V(12, 11, 3),
+ /* 0010 */ V(15, 6, 3),
+ /* 0011 */ V(15, 6, 3),
+ /* 0100 */ V(8, 14, 4),
+ /* 0101 */ V(14, 8, 4),
+ /* 0110 */ V(5, 15, 4),
+ /* 0111 */ V(9, 13, 4),
+ /* 1000 */ V(15, 5, 3),
+ /* 1001 */ V(15, 5, 3),
+ /* 1010 */ V(7, 14, 3),
+ /* 1011 */ V(7, 14, 3),
+ /* 1100 */ V(14, 7, 3),
+ /* 1101 */ V(14, 7, 3),
+ /* 1110 */ V(10, 12, 3),
+ /* 1111 */ V(10, 12, 3),
+
+ /* 0000 0011 ... */
+ /* 0000 */ V(12, 10, 3), /* 168 */
+ /* 0001 */ V(12, 10, 3),
+ /* 0010 */ V(11, 11, 3),
+ /* 0011 */ V(11, 11, 3),
+ /* 0100 */ V(13, 9, 4),
+ /* 0101 */ V(8, 13, 4),
+ /* 0110 */ V(4, 15, 3),
+ /* 0111 */ V(4, 15, 3),
+ /* 1000 */ V(15, 4, 3),
+ /* 1001 */ V(15, 4, 3),
+ /* 1010 */ V(3, 15, 3),
+ /* 1011 */ V(3, 15, 3),
+ /* 1100 */ V(15, 3, 3),
+ /* 1101 */ V(15, 3, 3),
+ /* 1110 */ V(13, 8, 3),
+ /* 1111 */ V(13, 8, 3),
+
+ /* 0000 0100 ... */
+ /* 0000 */ V(14, 6, 3), /* 184 */
+ /* 0001 */ V(14, 6, 3),
+ /* 0010 */ V(2, 15, 3),
+ /* 0011 */ V(2, 15, 3),
+ /* 0100 */ V(15, 2, 3),
+ /* 0101 */ V(15, 2, 3),
+ /* 0110 */ V(6, 14, 4),
+ /* 0111 */ V(15, 0, 4),
+ /* 1000 */ V(1, 15, 3),
+ /* 1001 */ V(1, 15, 3),
+ /* 1010 */ V(15, 1, 3),
+ /* 1011 */ V(15, 1, 3),
+ /* 1100 */ V(9, 12, 3),
+ /* 1101 */ V(9, 12, 3),
+ /* 1110 */ V(12, 9, 3),
+ /* 1111 */ V(12, 9, 3),
+
+ /* 0000 0101 ... */
+ /* 000 */ V(5, 14, 3), /* 200 */
+ /* 001 */ V(10, 11, 3),
+ /* 010 */ V(11, 10, 3),
+ /* 011 */ V(14, 5, 3),
+ /* 100 */ V(7, 13, 3),
+ /* 101 */ V(13, 7, 3),
+ /* 110 */ V(4, 14, 3),
+ /* 111 */ V(14, 4, 3),
+
+ /* 0000 0110 ... */
+ /* 000 */ V(8, 12, 3), /* 208 */
+ /* 001 */ V(12, 8, 3),
+ /* 010 */ V(3, 14, 3),
+ /* 011 */ V(6, 13, 3),
+ /* 100 */ V(13, 6, 3),
+ /* 101 */ V(14, 3, 3),
+ /* 110 */ V(9, 11, 3),
+ /* 111 */ V(11, 9, 3),
+
+ /* 0000 0111 ... */
+ /* 0000 */ V(2, 14, 3), /* 216 */
+ /* 0001 */ V(2, 14, 3),
+ /* 0010 */ V(10, 10, 3),
+ /* 0011 */ V(10, 10, 3),
+ /* 0100 */ V(14, 2, 3),
+ /* 0101 */ V(14, 2, 3),
+ /* 0110 */ V(1, 14, 3),
+ /* 0111 */ V(1, 14, 3),
+ /* 1000 */ V(14, 1, 3),
+ /* 1001 */ V(14, 1, 3),
+ /* 1010 */ V(0, 14, 4),
+ /* 1011 */ V(14, 0, 4),
+ /* 1100 */ V(5, 13, 3),
+ /* 1101 */ V(5, 13, 3),
+ /* 1110 */ V(13, 5, 3),
+ /* 1111 */ V(13, 5, 3),
+
+ /* 0000 1000 ... */
+ /* 000 */ V(7, 12, 3), /* 232 */
+ /* 001 */ V(12, 7, 3),
+ /* 010 */ V(4, 13, 3),
+ /* 011 */ V(8, 11, 3),
+ /* 100 */ V(13, 4, 2),
+ /* 101 */ V(13, 4, 2),
+ /* 110 */ V(11, 8, 3),
+ /* 111 */ V(9, 10, 3),
+
+ /* 0000 1001 ... */
+ /* 000 */ V(10, 9, 3), /* 240 */
+ /* 001 */ V(6, 12, 3),
+ /* 010 */ V(12, 6, 3),
+ /* 011 */ V(3, 13, 3),
+ /* 100 */ V(13, 3, 2),
+ /* 101 */ V(13, 3, 2),
+ /* 110 */ V(13, 2, 2),
+ /* 111 */ V(13, 2, 2),
+
+ /* 0000 1010 ... */
+ /* 000 */ V(2, 13, 3), /* 248 */
+ /* 001 */ V(0, 13, 3),
+ /* 010 */ V(1, 13, 2),
+ /* 011 */ V(1, 13, 2),
+ /* 100 */ V(7, 11, 2),
+ /* 101 */ V(7, 11, 2),
+ /* 110 */ V(11, 7, 2),
+ /* 111 */ V(11, 7, 2),
+
+ /* 0000 1011 ... */
+ /* 000 */ V(13, 1, 2), /* 256 */
+ /* 001 */ V(13, 1, 2),
+ /* 010 */ V(5, 12, 3),
+ /* 011 */ V(13, 0, 3),
+ /* 100 */ V(12, 5, 2),
+ /* 101 */ V(12, 5, 2),
+ /* 110 */ V(8, 10, 2),
+ /* 111 */ V(8, 10, 2),
+
+ /* 0000 1100 ... */
+ /* 00 */ V(10, 8, 2), /* 264 */
+ /* 01 */ V(4, 12, 2),
+ /* 10 */ V(12, 4, 2),
+ /* 11 */ V(6, 11, 2),
+
+ /* 0000 1101 ... */
+ /* 000 */ V(11, 6, 2), /* 268 */
+ /* 001 */ V(11, 6, 2),
+ /* 010 */ V(9, 9, 3),
+ /* 011 */ V(0, 12, 3),
+ /* 100 */ V(3, 12, 2),
+ /* 101 */ V(3, 12, 2),
+ /* 110 */ V(12, 3, 2),
+ /* 111 */ V(12, 3, 2),
+
+ /* 0000 1110 ... */
+ /* 000 */ V(7, 10, 2), /* 276 */
+ /* 001 */ V(7, 10, 2),
+ /* 010 */ V(10, 7, 2),
+ /* 011 */ V(10, 7, 2),
+ /* 100 */ V(10, 6, 2),
+ /* 101 */ V(10, 6, 2),
+ /* 110 */ V(12, 0, 3),
+ /* 111 */ V(0, 11, 3),
+
+ /* 0000 1111 ... */
+ /* 00 */ V(12, 2, 1), /* 284 */
+ /* 01 */ V(12, 2, 1),
+ /* 10 */ V(2, 12, 2),
+ /* 11 */ V(5, 11, 2),
+
+ /* 0001 0000 ... */
+ /* 00 */ V(11, 5, 2), /* 288 */
+ /* 01 */ V(1, 12, 2),
+ /* 10 */ V(8, 9, 2),
+ /* 11 */ V(9, 8, 2),
+
+ /* 0001 0001 ... */
+ /* 00 */ V(12, 1, 2), /* 292 */
+ /* 01 */ V(4, 11, 2),
+ /* 10 */ V(11, 4, 2),
+ /* 11 */ V(6, 10, 2),
+
+ /* 0001 0010 ... */
+ /* 00 */ V(3, 11, 2), /* 296 */
+ /* 01 */ V(7, 9, 2),
+ /* 10 */ V(11, 3, 1),
+ /* 11 */ V(11, 3, 1),
+
+ /* 0001 0011 ... */
+ /* 00 */ V(9, 7, 2), /* 300 */
+ /* 01 */ V(8, 8, 2),
+ /* 10 */ V(2, 11, 2),
+ /* 11 */ V(5, 10, 2),
+
+ /* 0001 0100 ... */
+ /* 00 */ V(11, 2, 1), /* 304 */
+ /* 01 */ V(11, 2, 1),
+ /* 10 */ V(10, 5, 2),
+ /* 11 */ V(1, 11, 2),
+
+ /* 0001 0101 ... */
+ /* 00 */ V(11, 1, 1), /* 308 */
+ /* 01 */ V(11, 1, 1),
+ /* 10 */ V(11, 0, 2),
+ /* 11 */ V(6, 9, 2),
+
+ /* 0001 0110 ... */
+ /* 00 */ V(9, 6, 2), /* 312 */
+ /* 01 */ V(4, 10, 2),
+ /* 10 */ V(10, 4, 2),
+ /* 11 */ V(7, 8, 2),
+
+ /* 0001 0111 ... */
+ /* 00 */ V(8, 7, 2), /* 316 */
+ /* 01 */ V(3, 10, 2),
+ /* 10 */ V(10, 3, 1),
+ /* 11 */ V(10, 3, 1),
+
+ /* 0001 1000 ... */
+ /* 0 */ V(5, 9, 1), /* 320 */
+ /* 1 */ V(9, 5, 1),
+
+ /* 0001 1001 ... */
+ /* 0 */ V(2, 10, 1), /* 322 */
+ /* 1 */ V(10, 2, 1),
+
+ /* 0001 1010 ... */
+ /* 0 */ V(1, 10, 1), /* 324 */
+ /* 1 */ V(10, 1, 1),
+
+ /* 0001 1011 ... */
+ /* 00 */ V(0, 10, 2), /* 326 */
+ /* 01 */ V(10, 0, 2),
+ /* 10 */ V(6, 8, 1),
+ /* 11 */ V(6, 8, 1),
+
+ /* 0001 1100 ... */
+ /* 0 */ V(8, 6, 1), /* 330 */
+ /* 1 */ V(4, 9, 1),
+
+ /* 0001 1101 ... */
+ /* 0 */ V(9, 4, 1), /* 332 */
+ /* 1 */ V(3, 9, 1),
+
+ /* 0001 1110 ... */
+ /* 00 */ V(9, 3, 1), /* 334 */
+ /* 01 */ V(9, 3, 1),
+ /* 10 */ V(7, 7, 2),
+ /* 11 */ V(0, 9, 2),
+
+ /* 0001 1111 ... */
+ /* 0 */ V(5, 8, 1), /* 338 */
+ /* 1 */ V(8, 5, 1),
+
+ /* 0010 0000 ... */
+ /* 0 */ V(2, 9, 1), /* 340 */
+ /* 1 */ V(6, 7, 1),
+
+ /* 0010 0001 ... */
+ /* 0 */ V(7, 6, 1), /* 342 */
+ /* 1 */ V(9, 2, 1),
+
+ /* 0010 0011 ... */
+ /* 0 */ V(1, 9, 1), /* 344 */
+ /* 1 */ V(9, 0, 1),
+
+ /* 0010 0100 ... */
+ /* 0 */ V(4, 8, 1), /* 346 */
+ /* 1 */ V(8, 4, 1),
+
+ /* 0010 0101 ... */
+ /* 0 */ V(5, 7, 1), /* 348 */
+ /* 1 */ V(7, 5, 1),
+
+ /* 0010 0110 ... */
+ /* 0 */ V(3, 8, 1), /* 350 */
+ /* 1 */ V(8, 3, 1),
+
+ /* 0010 0111 ... */
+ /* 0 */ V(6, 6, 1), /* 352 */
+ /* 1 */ V(4, 7, 1),
+
+ /* 0010 1100 ... */
+ /* 0 */ V(7, 4, 1), /* 354 */
+ /* 1 */ V(0, 8, 1),
+
+ /* 0010 1101 ... */
+ /* 0 */ V(8, 0, 1), /* 356 */
+ /* 1 */ V(5, 6, 1),
+
+ /* 0010 1110 ... */
+ /* 0 */ V(6, 5, 1), /* 358 */
+ /* 1 */ V(3, 7, 1),
+
+ /* 0010 1111 ... */
+ /* 0 */ V(7, 3, 1), /* 360 */
+ /* 1 */ V(4, 6, 1),
+
+ /* 0011 0110 ... */
+ /* 0 */ V(0, 7, 1), /* 362 */
+ /* 1 */ V(7, 0, 1),
+
+ /* 0011 1110 ... */
+ /* 0 */ V(0, 6, 1), /* 364 */
+ /* 1 */ V(6, 0, 1),
+
+ /* 0000 0000 0000 ... */
+ /* 0 */ V(15, 15, 1), /* 366 */
+ /* 1 */ V(14, 15, 1),
+
+ /* 0000 0000 0001 ... */
+ /* 0 */ V(15, 14, 1), /* 368 */
+ /* 1 */ V(13, 15, 1),
+
+ /* 0000 0000 0011 ... */
+ /* 0 */ V(15, 13, 1), /* 370 */
+ /* 1 */ V(12, 15, 1),
+
+ /* 0000 0000 0100 ... */
+ /* 0 */ V(15, 12, 1), /* 372 */
+ /* 1 */ V(13, 14, 1),
+
+ /* 0000 0000 0101 ... */
+ /* 0 */ V(14, 13, 1), /* 374 */
+ /* 1 */ V(11, 15, 1),
+
+ /* 0000 0000 0111 ... */
+ /* 0 */ V(12, 14, 1), /* 376 */
+ /* 1 */ V(14, 12, 1),
+
+ /* 0000 0001 1111 ... */
+ /* 0 */ V(10, 14, 1), /* 378 */
+ /* 1 */ V(0, 15, 1)
+};
+
+static
+union huffpair const hufftab16[] = {
+ /* 0000 */ PTR(16, 4),
+ /* 0001 */ PTR(32, 4),
+ /* 0010 */ PTR(48, 4),
+ /* 0011 */ PTR(64, 2),
+ /* 0100 */ V(1, 1, 4),
+ /* 0101 */ V(0, 1, 4),
+ /* 0110 */ V(1, 0, 3),
+ /* 0111 */ V(1, 0, 3),
+ /* 1000 */ V(0, 0, 1),
+ /* 1001 */ V(0, 0, 1),
+ /* 1010 */ V(0, 0, 1),
+ /* 1011 */ V(0, 0, 1),
+ /* 1100 */ V(0, 0, 1),
+ /* 1101 */ V(0, 0, 1),
+ /* 1110 */ V(0, 0, 1),
+ /* 1111 */ V(0, 0, 1),
+
+ /* 0000 ... */
+ /* 0000 */ PTR(68, 3), /* 16 */
+ /* 0001 */ PTR(76, 3),
+ /* 0010 */ PTR(84, 2),
+ /* 0011 */ V(15, 15, 4),
+ /* 0100 */ PTR(88, 2),
+ /* 0101 */ PTR(92, 1),
+ /* 0110 */ PTR(94, 4),
+ /* 0111 */ V(15, 2, 4),
+ /* 1000 */ PTR(110, 1),
+ /* 1001 */ V(1, 15, 4),
+ /* 1010 */ V(15, 1, 4),
+ /* 1011 */ PTR(112, 4),
+ /* 1100 */ PTR(128, 4),
+ /* 1101 */ PTR(144, 4),
+ /* 1110 */ PTR(160, 4),
+ /* 1111 */ PTR(176, 4),
+
+ /* 0001 ... */
+ /* 0000 */ PTR(192, 4), /* 32 */
+ /* 0001 */ PTR(208, 3),
+ /* 0010 */ PTR(216, 3),
+ /* 0011 */ PTR(224, 3),
+ /* 0100 */ PTR(232, 3),
+ /* 0101 */ PTR(240, 3),
+ /* 0110 */ PTR(248, 3),
+ /* 0111 */ PTR(256, 3),
+ /* 1000 */ PTR(264, 2),
+ /* 1001 */ PTR(268, 2),
+ /* 1010 */ PTR(272, 1),
+ /* 1011 */ PTR(274, 2),
+ /* 1100 */ PTR(278, 2),
+ /* 1101 */ PTR(282, 1),
+ /* 1110 */ V(5, 1, 4),
+ /* 1111 */ PTR(284, 1),
+
+ /* 0010 ... */
+ /* 0000 */ PTR(286, 1), /* 48 */
+ /* 0001 */ PTR(288, 1),
+ /* 0010 */ PTR(290, 1),
+ /* 0011 */ V(1, 4, 4),
+ /* 0100 */ V(4, 1, 4),
+ /* 0101 */ PTR(292, 1),
+ /* 0110 */ V(2, 3, 4),
+ /* 0111 */ V(3, 2, 4),
+ /* 1000 */ V(1, 3, 3),
+ /* 1001 */ V(1, 3, 3),
+ /* 1010 */ V(3, 1, 3),
+ /* 1011 */ V(3, 1, 3),
+ /* 1100 */ V(0, 3, 4),
+ /* 1101 */ V(3, 0, 4),
+ /* 1110 */ V(2, 2, 3),
+ /* 1111 */ V(2, 2, 3),
+
+ /* 0011 ... */
+ /* 00 */ V(1, 2, 2), /* 64 */
+ /* 01 */ V(2, 1, 2),
+ /* 10 */ V(0, 2, 2),
+ /* 11 */ V(2, 0, 2),
+
+ /* 0000 0000 ... */
+ /* 000 */ V(14, 15, 3), /* 68 */
+ /* 001 */ V(15, 14, 3),
+ /* 010 */ V(13, 15, 3),
+ /* 011 */ V(15, 13, 3),
+ /* 100 */ V(12, 15, 3),
+ /* 101 */ V(15, 12, 3),
+ /* 110 */ V(11, 15, 3),
+ /* 111 */ V(15, 11, 3),
+
+ /* 0000 0001 ... */
+ /* 000 */ V(10, 15, 2), /* 76 */
+ /* 001 */ V(10, 15, 2),
+ /* 010 */ V(15, 10, 3),
+ /* 011 */ V(9, 15, 3),
+ /* 100 */ V(15, 9, 3),
+ /* 101 */ V(15, 8, 3),
+ /* 110 */ V(8, 15, 2),
+ /* 111 */ V(8, 15, 2),
+
+ /* 0000 0010 ... */
+ /* 00 */ V(7, 15, 2), /* 84 */
+ /* 01 */ V(15, 7, 2),
+ /* 10 */ V(6, 15, 2),
+ /* 11 */ V(15, 6, 2),
+
+ /* 0000 0100 ... */
+ /* 00 */ V(5, 15, 2), /* 88 */
+ /* 01 */ V(15, 5, 2),
+ /* 10 */ V(4, 15, 1),
+ /* 11 */ V(4, 15, 1),
+
+ /* 0000 0101 ... */
+ /* 0 */ V(15, 4, 1), /* 92 */
+ /* 1 */ V(15, 3, 1),
+
+ /* 0000 0110 ... */
+ /* 0000 */ V(15, 0, 1), /* 94 */
+ /* 0001 */ V(15, 0, 1),
+ /* 0010 */ V(15, 0, 1),
+ /* 0011 */ V(15, 0, 1),
+ /* 0100 */ V(15, 0, 1),
+ /* 0101 */ V(15, 0, 1),
+ /* 0110 */ V(15, 0, 1),
+ /* 0111 */ V(15, 0, 1),
+ /* 1000 */ V(3, 15, 2),
+ /* 1001 */ V(3, 15, 2),
+ /* 1010 */ V(3, 15, 2),
+ /* 1011 */ V(3, 15, 2),
+ /* 1100 */ PTR(294, 4),
+ /* 1101 */ PTR(310, 3),
+ /* 1110 */ PTR(318, 3),
+ /* 1111 */ PTR(326, 3),
+
+ /* 0000 1000 ... */
+ /* 0 */ V(2, 15, 1), /* 110 */
+ /* 1 */ V(0, 15, 1),
+
+ /* 0000 1011 ... */
+ /* 0000 */ PTR(334, 2), /* 112 */
+ /* 0001 */ PTR(338, 2),
+ /* 0010 */ PTR(342, 2),
+ /* 0011 */ PTR(346, 1),
+ /* 0100 */ PTR(348, 2),
+ /* 0101 */ PTR(352, 2),
+ /* 0110 */ PTR(356, 1),
+ /* 0111 */ PTR(358, 2),
+ /* 1000 */ PTR(362, 2),
+ /* 1001 */ PTR(366, 2),
+ /* 1010 */ PTR(370, 2),
+ /* 1011 */ V(14, 3, 4),
+ /* 1100 */ PTR(374, 1),
+ /* 1101 */ PTR(376, 1),
+ /* 1110 */ PTR(378, 1),
+ /* 1111 */ PTR(380, 1),
+
+ /* 0000 1100 ... */
+ /* 0000 */ PTR(382, 1), /* 128 */
+ /* 0001 */ PTR(384, 1),
+ /* 0010 */ PTR(386, 1),
+ /* 0011 */ V(0, 13, 4),
+ /* 0100 */ PTR(388, 1),
+ /* 0101 */ PTR(390, 1),
+ /* 0110 */ PTR(392, 1),
+ /* 0111 */ V(3, 12, 4),
+ /* 1000 */ PTR(394, 1),
+ /* 1001 */ V(1, 12, 4),
+ /* 1010 */ V(12, 0, 4),
+ /* 1011 */ PTR(396, 1),
+ /* 1100 */ V(14, 2, 3),
+ /* 1101 */ V(14, 2, 3),
+ /* 1110 */ V(2, 14, 4),
+ /* 1111 */ V(1, 14, 4),
+
+ /* 0000 1101 ... */
+ /* 0000 */ V(13, 3, 4), /* 144 */
+ /* 0001 */ V(2, 13, 4),
+ /* 0010 */ V(13, 2, 4),
+ /* 0011 */ V(13, 1, 4),
+ /* 0100 */ V(3, 11, 4),
+ /* 0101 */ PTR(398, 1),
+ /* 0110 */ V(1, 13, 3),
+ /* 0111 */ V(1, 13, 3),
+ /* 1000 */ V(12, 4, 4),
+ /* 1001 */ V(6, 11, 4),
+ /* 1010 */ V(12, 3, 4),
+ /* 1011 */ V(10, 7, 4),
+ /* 1100 */ V(2, 12, 3),
+ /* 1101 */ V(2, 12, 3),
+ /* 1110 */ V(12, 2, 4),
+ /* 1111 */ V(11, 5, 4),
+
+ /* 0000 1110 ... */
+ /* 0000 */ V(12, 1, 4), /* 160 */
+ /* 0001 */ V(0, 12, 4),
+ /* 0010 */ V(4, 11, 4),
+ /* 0011 */ V(11, 4, 4),
+ /* 0100 */ V(6, 10, 4),
+ /* 0101 */ V(10, 6, 4),
+ /* 0110 */ V(11, 3, 3),
+ /* 0111 */ V(11, 3, 3),
+ /* 1000 */ V(5, 10, 4),
+ /* 1001 */ V(10, 5, 4),
+ /* 1010 */ V(2, 11, 3),
+ /* 1011 */ V(2, 11, 3),
+ /* 1100 */ V(11, 2, 3),
+ /* 1101 */ V(11, 2, 3),
+ /* 1110 */ V(1, 11, 3),
+ /* 1111 */ V(1, 11, 3),
+
+ /* 0000 1111 ... */
+ /* 0000 */ V(11, 1, 3), /* 176 */
+ /* 0001 */ V(11, 1, 3),
+ /* 0010 */ V(0, 11, 4),
+ /* 0011 */ V(11, 0, 4),
+ /* 0100 */ V(6, 9, 4),
+ /* 0101 */ V(9, 6, 4),
+ /* 0110 */ V(4, 10, 4),
+ /* 0111 */ V(10, 4, 4),
+ /* 1000 */ V(7, 8, 4),
+ /* 1001 */ V(8, 7, 4),
+ /* 1010 */ V(10, 3, 3),
+ /* 1011 */ V(10, 3, 3),
+ /* 1100 */ V(3, 10, 4),
+ /* 1101 */ V(5, 9, 4),
+ /* 1110 */ V(2, 10, 3),
+ /* 1111 */ V(2, 10, 3),
+
+ /* 0001 0000 ... */
+ /* 0000 */ V(9, 5, 4), /* 192 */
+ /* 0001 */ V(6, 8, 4),
+ /* 0010 */ V(10, 1, 3),
+ /* 0011 */ V(10, 1, 3),
+ /* 0100 */ V(8, 6, 4),
+ /* 0101 */ V(7, 7, 4),
+ /* 0110 */ V(9, 4, 3),
+ /* 0111 */ V(9, 4, 3),
+ /* 1000 */ V(4, 9, 4),
+ /* 1001 */ V(5, 7, 4),
+ /* 1010 */ V(6, 7, 3),
+ /* 1011 */ V(6, 7, 3),
+ /* 1100 */ V(10, 2, 2),
+ /* 1101 */ V(10, 2, 2),
+ /* 1110 */ V(10, 2, 2),
+ /* 1111 */ V(10, 2, 2),
+
+ /* 0001 0001 ... */
+ /* 000 */ V(1, 10, 2), /* 208 */
+ /* 001 */ V(1, 10, 2),
+ /* 010 */ V(0, 10, 3),
+ /* 011 */ V(10, 0, 3),
+ /* 100 */ V(3, 9, 3),
+ /* 101 */ V(9, 3, 3),
+ /* 110 */ V(5, 8, 3),
+ /* 111 */ V(8, 5, 3),
+
+ /* 0001 0010 ... */
+ /* 000 */ V(2, 9, 2), /* 216 */
+ /* 001 */ V(2, 9, 2),
+ /* 010 */ V(9, 2, 2),
+ /* 011 */ V(9, 2, 2),
+ /* 100 */ V(7, 6, 3),
+ /* 101 */ V(0, 9, 3),
+ /* 110 */ V(1, 9, 2),
+ /* 111 */ V(1, 9, 2),
+
+ /* 0001 0011 ... */
+ /* 000 */ V(9, 1, 2), /* 224 */
+ /* 001 */ V(9, 1, 2),
+ /* 010 */ V(9, 0, 3),
+ /* 011 */ V(4, 8, 3),
+ /* 100 */ V(8, 4, 3),
+ /* 101 */ V(7, 5, 3),
+ /* 110 */ V(3, 8, 3),
+ /* 111 */ V(8, 3, 3),
+
+ /* 0001 0100 ... */
+ /* 000 */ V(6, 6, 3), /* 232 */
+ /* 001 */ V(2, 8, 3),
+ /* 010 */ V(8, 2, 2),
+ /* 011 */ V(8, 2, 2),
+ /* 100 */ V(4, 7, 3),
+ /* 101 */ V(7, 4, 3),
+ /* 110 */ V(1, 8, 2),
+ /* 111 */ V(1, 8, 2),
+
+ /* 0001 0101 ... */
+ /* 000 */ V(8, 1, 2), /* 240 */
+ /* 001 */ V(8, 1, 2),
+ /* 010 */ V(8, 0, 2),
+ /* 011 */ V(8, 0, 2),
+ /* 100 */ V(0, 8, 3),
+ /* 101 */ V(5, 6, 3),
+ /* 110 */ V(3, 7, 2),
+ /* 111 */ V(3, 7, 2),
+
+ /* 0001 0110 ... */
+ /* 000 */ V(7, 3, 2), /* 248 */
+ /* 001 */ V(7, 3, 2),
+ /* 010 */ V(6, 5, 3),
+ /* 011 */ V(4, 6, 3),
+ /* 100 */ V(2, 7, 2),
+ /* 101 */ V(2, 7, 2),
+ /* 110 */ V(7, 2, 2),
+ /* 111 */ V(7, 2, 2),
+
+ /* 0001 0111 ... */
+ /* 000 */ V(6, 4, 3), /* 256 */
+ /* 001 */ V(5, 5, 3),
+ /* 010 */ V(0, 7, 2),
+ /* 011 */ V(0, 7, 2),
+ /* 100 */ V(1, 7, 1),
+ /* 101 */ V(1, 7, 1),
+ /* 110 */ V(1, 7, 1),
+ /* 111 */ V(1, 7, 1),
+
+ /* 0001 1000 ... */
+ /* 00 */ V(7, 1, 1), /* 264 */
+ /* 01 */ V(7, 1, 1),
+ /* 10 */ V(7, 0, 2),
+ /* 11 */ V(3, 6, 2),
+
+ /* 0001 1001 ... */
+ /* 00 */ V(6, 3, 2), /* 268 */
+ /* 01 */ V(4, 5, 2),
+ /* 10 */ V(5, 4, 2),
+ /* 11 */ V(2, 6, 2),
+
+ /* 0001 1010 ... */
+ /* 0 */ V(6, 2, 1), /* 272 */
+ /* 1 */ V(1, 6, 1),
+
+ /* 0001 1011 ... */
+ /* 00 */ V(6, 1, 1), /* 274 */
+ /* 01 */ V(6, 1, 1),
+ /* 10 */ V(0, 6, 2),
+ /* 11 */ V(6, 0, 2),
+
+ /* 0001 1100 ... */
+ /* 00 */ V(5, 3, 1), /* 278 */
+ /* 01 */ V(5, 3, 1),
+ /* 10 */ V(3, 5, 2),
+ /* 11 */ V(4, 4, 2),
+
+ /* 0001 1101 ... */
+ /* 0 */ V(2, 5, 1), /* 282 */
+ /* 1 */ V(5, 2, 1),
+
+ /* 0001 1111 ... */
+ /* 0 */ V(1, 5, 1), /* 284 */
+ /* 1 */ V(0, 5, 1),
+
+ /* 0010 0000 ... */
+ /* 0 */ V(3, 4, 1), /* 286 */
+ /* 1 */ V(4, 3, 1),
+
+ /* 0010 0001 ... */
+ /* 0 */ V(5, 0, 1), /* 288 */
+ /* 1 */ V(2, 4, 1),
+
+ /* 0010 0010 ... */
+ /* 0 */ V(4, 2, 1), /* 290 */
+ /* 1 */ V(3, 3, 1),
+
+ /* 0010 0101 ... */
+ /* 0 */ V(0, 4, 1), /* 292 */
+ /* 1 */ V(4, 0, 1),
+
+ /* 0000 0110 1100 ... */
+ /* 0000 */ V(12, 14, 4), /* 294 */
+ /* 0001 */ PTR(400, 1),
+ /* 0010 */ V(13, 14, 3),
+ /* 0011 */ V(13, 14, 3),
+ /* 0100 */ V(14, 9, 3),
+ /* 0101 */ V(14, 9, 3),
+ /* 0110 */ V(14, 10, 4),
+ /* 0111 */ V(13, 9, 4),
+ /* 1000 */ V(14, 14, 2),
+ /* 1001 */ V(14, 14, 2),
+ /* 1010 */ V(14, 14, 2),
+ /* 1011 */ V(14, 14, 2),
+ /* 1100 */ V(14, 13, 3),
+ /* 1101 */ V(14, 13, 3),
+ /* 1110 */ V(14, 11, 3),
+ /* 1111 */ V(14, 11, 3),
+
+ /* 0000 0110 1101 ... */
+ /* 000 */ V(11, 14, 2), /* 310 */
+ /* 001 */ V(11, 14, 2),
+ /* 010 */ V(12, 13, 2),
+ /* 011 */ V(12, 13, 2),
+ /* 100 */ V(13, 12, 3),
+ /* 101 */ V(13, 11, 3),
+ /* 110 */ V(10, 14, 2),
+ /* 111 */ V(10, 14, 2),
+
+ /* 0000 0110 1110 ... */
+ /* 000 */ V(12, 12, 2), /* 318 */
+ /* 001 */ V(12, 12, 2),
+ /* 010 */ V(10, 13, 3),
+ /* 011 */ V(13, 10, 3),
+ /* 100 */ V(7, 14, 3),
+ /* 101 */ V(10, 12, 3),
+ /* 110 */ V(12, 10, 2),
+ /* 111 */ V(12, 10, 2),
+
+ /* 0000 0110 1111 ... */
+ /* 000 */ V(12, 9, 3), /* 326 */
+ /* 001 */ V(7, 13, 3),
+ /* 010 */ V(5, 14, 2),
+ /* 011 */ V(5, 14, 2),
+ /* 100 */ V(11, 13, 1),
+ /* 101 */ V(11, 13, 1),
+ /* 110 */ V(11, 13, 1),
+ /* 111 */ V(11, 13, 1),
+
+ /* 0000 1011 0000 ... */
+ /* 00 */ V(9, 14, 1), /* 334 */
+ /* 01 */ V(9, 14, 1),
+ /* 10 */ V(11, 12, 2),
+ /* 11 */ V(12, 11, 2),
+
+ /* 0000 1011 0001 ... */
+ /* 00 */ V(8, 14, 2), /* 338 */
+ /* 01 */ V(14, 8, 2),
+ /* 10 */ V(9, 13, 2),
+ /* 11 */ V(14, 7, 2),
+
+ /* 0000 1011 0010 ... */
+ /* 00 */ V(11, 11, 2), /* 342 */
+ /* 01 */ V(8, 13, 2),
+ /* 10 */ V(13, 8, 2),
+ /* 11 */ V(6, 14, 2),
+
+ /* 0000 1011 0011 ... */
+ /* 0 */ V(14, 6, 1), /* 346 */
+ /* 1 */ V(9, 12, 1),
+
+ /* 0000 1011 0100 ... */
+ /* 00 */ V(10, 11, 2), /* 348 */
+ /* 01 */ V(11, 10, 2),
+ /* 10 */ V(14, 5, 2),
+ /* 11 */ V(13, 7, 2),
+
+ /* 0000 1011 0101 ... */
+ /* 00 */ V(4, 14, 1), /* 352 */
+ /* 01 */ V(4, 14, 1),
+ /* 10 */ V(14, 4, 2),
+ /* 11 */ V(8, 12, 2),
+
+ /* 0000 1011 0110 ... */
+ /* 0 */ V(12, 8, 1), /* 356 */
+ /* 1 */ V(3, 14, 1),
+
+ /* 0000 1011 0111 ... */
+ /* 00 */ V(6, 13, 1), /* 358 */
+ /* 01 */ V(6, 13, 1),
+ /* 10 */ V(13, 6, 2),
+ /* 11 */ V(9, 11, 2),
+
+ /* 0000 1011 1000 ... */
+ /* 00 */ V(11, 9, 2), /* 362 */
+ /* 01 */ V(10, 10, 2),
+ /* 10 */ V(14, 1, 1),
+ /* 11 */ V(14, 1, 1),
+
+ /* 0000 1011 1001 ... */
+ /* 00 */ V(13, 4, 1), /* 366 */
+ /* 01 */ V(13, 4, 1),
+ /* 10 */ V(11, 8, 2),
+ /* 11 */ V(10, 9, 2),
+
+ /* 0000 1011 1010 ... */
+ /* 00 */ V(7, 11, 1), /* 370 */
+ /* 01 */ V(7, 11, 1),
+ /* 10 */ V(11, 7, 2),
+ /* 11 */ V(13, 0, 2),
+
+ /* 0000 1011 1100 ... */
+ /* 0 */ V(0, 14, 1), /* 374 */
+ /* 1 */ V(14, 0, 1),
+
+ /* 0000 1011 1101 ... */
+ /* 0 */ V(5, 13, 1), /* 376 */
+ /* 1 */ V(13, 5, 1),
+
+ /* 0000 1011 1110 ... */
+ /* 0 */ V(7, 12, 1), /* 378 */
+ /* 1 */ V(12, 7, 1),
+
+ /* 0000 1011 1111 ... */
+ /* 0 */ V(4, 13, 1), /* 380 */
+ /* 1 */ V(8, 11, 1),
+
+ /* 0000 1100 0000 ... */
+ /* 0 */ V(9, 10, 1), /* 382 */
+ /* 1 */ V(6, 12, 1),
+
+ /* 0000 1100 0001 ... */
+ /* 0 */ V(12, 6, 1), /* 384 */
+ /* 1 */ V(3, 13, 1),
+
+ /* 0000 1100 0010 ... */
+ /* 0 */ V(5, 12, 1), /* 386 */
+ /* 1 */ V(12, 5, 1),
+
+ /* 0000 1100 0100 ... */
+ /* 0 */ V(8, 10, 1), /* 388 */
+ /* 1 */ V(10, 8, 1),
+
+ /* 0000 1100 0101 ... */
+ /* 0 */ V(9, 9, 1), /* 390 */
+ /* 1 */ V(4, 12, 1),
+
+ /* 0000 1100 0110 ... */
+ /* 0 */ V(11, 6, 1), /* 392 */
+ /* 1 */ V(7, 10, 1),
+
+ /* 0000 1100 1000 ... */
+ /* 0 */ V(5, 11, 1), /* 394 */
+ /* 1 */ V(8, 9, 1),
+
+ /* 0000 1100 1011 ... */
+ /* 0 */ V(9, 8, 1), /* 396 */
+ /* 1 */ V(7, 9, 1),
+
+ /* 0000 1101 0101 ... */
+ /* 0 */ V(9, 7, 1), /* 398 */
+ /* 1 */ V(8, 8, 1),
+
+ /* 0000 0110 1100 0001 ... */
+ /* 0 */ V(14, 12, 1), /* 400 */
+ /* 1 */ V(13, 13, 1)
+};
+
+static
+union huffpair const hufftab24[] = {
+ /* 0000 */ PTR(16, 4),
+ /* 0001 */ PTR(32, 4),
+ /* 0010 */ PTR(48, 4),
+ /* 0011 */ V(15, 15, 4),
+ /* 0100 */ PTR(64, 4),
+ /* 0101 */ PTR(80, 4),
+ /* 0110 */ PTR(96, 4),
+ /* 0111 */ PTR(112, 4),
+ /* 1000 */ PTR(128, 4),
+ /* 1001 */ PTR(144, 4),
+ /* 1010 */ PTR(160, 3),
+ /* 1011 */ PTR(168, 2),
+ /* 1100 */ V(1, 1, 4),
+ /* 1101 */ V(0, 1, 4),
+ /* 1110 */ V(1, 0, 4),
+ /* 1111 */ V(0, 0, 4),
+
+ /* 0000 ... */
+ /* 0000 */ V(14, 15, 4), /* 16 */
+ /* 0001 */ V(15, 14, 4),
+ /* 0010 */ V(13, 15, 4),
+ /* 0011 */ V(15, 13, 4),
+ /* 0100 */ V(12, 15, 4),
+ /* 0101 */ V(15, 12, 4),
+ /* 0110 */ V(11, 15, 4),
+ /* 0111 */ V(15, 11, 4),
+ /* 1000 */ V(15, 10, 3),
+ /* 1001 */ V(15, 10, 3),
+ /* 1010 */ V(10, 15, 4),
+ /* 1011 */ V(9, 15, 4),
+ /* 1100 */ V(15, 9, 3),
+ /* 1101 */ V(15, 9, 3),
+ /* 1110 */ V(15, 8, 3),
+ /* 1111 */ V(15, 8, 3),
+
+ /* 0001 ... */
+ /* 0000 */ V(8, 15, 4), /* 32 */
+ /* 0001 */ V(7, 15, 4),
+ /* 0010 */ V(15, 7, 3),
+ /* 0011 */ V(15, 7, 3),
+ /* 0100 */ V(6, 15, 3),
+ /* 0101 */ V(6, 15, 3),
+ /* 0110 */ V(15, 6, 3),
+ /* 0111 */ V(15, 6, 3),
+ /* 1000 */ V(5, 15, 3),
+ /* 1001 */ V(5, 15, 3),
+ /* 1010 */ V(15, 5, 3),
+ /* 1011 */ V(15, 5, 3),
+ /* 1100 */ V(4, 15, 3),
+ /* 1101 */ V(4, 15, 3),
+ /* 1110 */ V(15, 4, 3),
+ /* 1111 */ V(15, 4, 3),
+
+ /* 0010 ... */
+ /* 0000 */ V(3, 15, 3), /* 48 */
+ /* 0001 */ V(3, 15, 3),
+ /* 0010 */ V(15, 3, 3),
+ /* 0011 */ V(15, 3, 3),
+ /* 0100 */ V(2, 15, 3),
+ /* 0101 */ V(2, 15, 3),
+ /* 0110 */ V(15, 2, 3),
+ /* 0111 */ V(15, 2, 3),
+ /* 1000 */ V(15, 1, 3),
+ /* 1001 */ V(15, 1, 3),
+ /* 1010 */ V(1, 15, 4),
+ /* 1011 */ V(15, 0, 4),
+ /* 1100 */ PTR(172, 3),
+ /* 1101 */ PTR(180, 3),
+ /* 1110 */ PTR(188, 3),
+ /* 1111 */ PTR(196, 3),
+
+ /* 0100 ... */
+ /* 0000 */ PTR(204, 4), /* 64 */
+ /* 0001 */ PTR(220, 3),
+ /* 0010 */ PTR(228, 3),
+ /* 0011 */ PTR(236, 3),
+ /* 0100 */ PTR(244, 2),
+ /* 0101 */ PTR(248, 2),
+ /* 0110 */ PTR(252, 2),
+ /* 0111 */ PTR(256, 2),
+ /* 1000 */ PTR(260, 2),
+ /* 1001 */ PTR(264, 2),
+ /* 1010 */ PTR(268, 2),
+ /* 1011 */ PTR(272, 2),
+ /* 1100 */ PTR(276, 2),
+ /* 1101 */ PTR(280, 3),
+ /* 1110 */ PTR(288, 2),
+ /* 1111 */ PTR(292, 2),
+
+ /* 0101 ... */
+ /* 0000 */ PTR(296, 2), /* 80 */
+ /* 0001 */ PTR(300, 3),
+ /* 0010 */ PTR(308, 2),
+ /* 0011 */ PTR(312, 3),
+ /* 0100 */ PTR(320, 1),
+ /* 0101 */ PTR(322, 2),
+ /* 0110 */ PTR(326, 2),
+ /* 0111 */ PTR(330, 1),
+ /* 1000 */ PTR(332, 2),
+ /* 1001 */ PTR(336, 1),
+ /* 1010 */ PTR(338, 1),
+ /* 1011 */ PTR(340, 1),
+ /* 1100 */ PTR(342, 1),
+ /* 1101 */ PTR(344, 1),
+ /* 1110 */ PTR(346, 1),
+ /* 1111 */ PTR(348, 1),
+
+ /* 0110 ... */
+ /* 0000 */ PTR(350, 1), /* 96 */
+ /* 0001 */ PTR(352, 1),
+ /* 0010 */ PTR(354, 1),
+ /* 0011 */ PTR(356, 1),
+ /* 0100 */ PTR(358, 1),
+ /* 0101 */ PTR(360, 1),
+ /* 0110 */ PTR(362, 1),
+ /* 0111 */ PTR(364, 1),
+ /* 1000 */ PTR(366, 1),
+ /* 1001 */ PTR(368, 1),
+ /* 1010 */ PTR(370, 2),
+ /* 1011 */ PTR(374, 1),
+ /* 1100 */ PTR(376, 2),
+ /* 1101 */ V(7, 3, 4),
+ /* 1110 */ PTR(380, 1),
+ /* 1111 */ V(7, 2, 4),
+
+ /* 0111 ... */
+ /* 0000 */ V(4, 6, 4), /* 112 */
+ /* 0001 */ V(6, 4, 4),
+ /* 0010 */ V(5, 5, 4),
+ /* 0011 */ V(7, 1, 4),
+ /* 0100 */ V(3, 6, 4),
+ /* 0101 */ V(6, 3, 4),
+ /* 0110 */ V(4, 5, 4),
+ /* 0111 */ V(5, 4, 4),
+ /* 1000 */ V(2, 6, 4),
+ /* 1001 */ V(6, 2, 4),
+ /* 1010 */ V(1, 6, 4),
+ /* 1011 */ V(6, 1, 4),
+ /* 1100 */ PTR(382, 1),
+ /* 1101 */ V(3, 5, 4),
+ /* 1110 */ V(5, 3, 4),
+ /* 1111 */ V(4, 4, 4),
+
+ /* 1000 ... */
+ /* 0000 */ V(2, 5, 4), /* 128 */
+ /* 0001 */ V(5, 2, 4),
+ /* 0010 */ V(1, 5, 4),
+ /* 0011 */ PTR(384, 1),
+ /* 0100 */ V(5, 1, 3),
+ /* 0101 */ V(5, 1, 3),
+ /* 0110 */ V(3, 4, 4),
+ /* 0111 */ V(4, 3, 4),
+ /* 1000 */ V(2, 4, 3),
+ /* 1001 */ V(2, 4, 3),
+ /* 1010 */ V(4, 2, 3),
+ /* 1011 */ V(4, 2, 3),
+ /* 1100 */ V(3, 3, 3),
+ /* 1101 */ V(3, 3, 3),
+ /* 1110 */ V(1, 4, 3),
+ /* 1111 */ V(1, 4, 3),
+
+ /* 1001 ... */
+ /* 0000 */ V(4, 1, 3), /* 144 */
+ /* 0001 */ V(4, 1, 3),
+ /* 0010 */ V(0, 4, 4),
+ /* 0011 */ V(4, 0, 4),
+ /* 0100 */ V(2, 3, 3),
+ /* 0101 */ V(2, 3, 3),
+ /* 0110 */ V(3, 2, 3),
+ /* 0111 */ V(3, 2, 3),
+ /* 1000 */ V(1, 3, 2),
+ /* 1001 */ V(1, 3, 2),
+ /* 1010 */ V(1, 3, 2),
+ /* 1011 */ V(1, 3, 2),
+ /* 1100 */ V(3, 1, 2),
+ /* 1101 */ V(3, 1, 2),
+ /* 1110 */ V(3, 1, 2),
+ /* 1111 */ V(3, 1, 2),
+
+ /* 1010 ... */
+ /* 000 */ V(0, 3, 3), /* 160 */
+ /* 001 */ V(3, 0, 3),
+ /* 010 */ V(2, 2, 2),
+ /* 011 */ V(2, 2, 2),
+ /* 100 */ V(1, 2, 1),
+ /* 101 */ V(1, 2, 1),
+ /* 110 */ V(1, 2, 1),
+ /* 111 */ V(1, 2, 1),
+
+ /* 1011 ... */
+ /* 00 */ V(2, 1, 1), /* 168 */
+ /* 01 */ V(2, 1, 1),
+ /* 10 */ V(0, 2, 2),
+ /* 11 */ V(2, 0, 2),
+
+ /* 0010 1100 ... */
+ /* 000 */ V(0, 15, 1), /* 172 */
+ /* 001 */ V(0, 15, 1),
+ /* 010 */ V(0, 15, 1),
+ /* 011 */ V(0, 15, 1),
+ /* 100 */ V(14, 14, 3),
+ /* 101 */ V(13, 14, 3),
+ /* 110 */ V(14, 13, 3),
+ /* 111 */ V(12, 14, 3),
+
+ /* 0010 1101 ... */
+ /* 000 */ V(14, 12, 3), /* 180 */
+ /* 001 */ V(13, 13, 3),
+ /* 010 */ V(11, 14, 3),
+ /* 011 */ V(14, 11, 3),
+ /* 100 */ V(12, 13, 3),
+ /* 101 */ V(13, 12, 3),
+ /* 110 */ V(10, 14, 3),
+ /* 111 */ V(14, 10, 3),
+
+ /* 0010 1110 ... */
+ /* 000 */ V(11, 13, 3), /* 188 */
+ /* 001 */ V(13, 11, 3),
+ /* 010 */ V(12, 12, 3),
+ /* 011 */ V(9, 14, 3),
+ /* 100 */ V(14, 9, 3),
+ /* 101 */ V(10, 13, 3),
+ /* 110 */ V(13, 10, 3),
+ /* 111 */ V(11, 12, 3),
+
+ /* 0010 1111 ... */
+ /* 000 */ V(12, 11, 3), /* 196 */
+ /* 001 */ V(8, 14, 3),
+ /* 010 */ V(14, 8, 3),
+ /* 011 */ V(9, 13, 3),
+ /* 100 */ V(13, 9, 3),
+ /* 101 */ V(7, 14, 3),
+ /* 110 */ V(14, 7, 3),
+ /* 111 */ V(10, 12, 3),
+
+ /* 0100 0000 ... */
+ /* 0000 */ V(12, 10, 3), /* 204 */
+ /* 0001 */ V(12, 10, 3),
+ /* 0010 */ V(11, 11, 3),
+ /* 0011 */ V(11, 11, 3),
+ /* 0100 */ V(8, 13, 3),
+ /* 0101 */ V(8, 13, 3),
+ /* 0110 */ V(13, 8, 3),
+ /* 0111 */ V(13, 8, 3),
+ /* 1000 */ V(0, 14, 4),
+ /* 1001 */ V(14, 0, 4),
+ /* 1010 */ V(0, 13, 3),
+ /* 1011 */ V(0, 13, 3),
+ /* 1100 */ V(14, 6, 2),
+ /* 1101 */ V(14, 6, 2),
+ /* 1110 */ V(14, 6, 2),
+ /* 1111 */ V(14, 6, 2),
+
+ /* 0100 0001 ... */
+ /* 000 */ V(6, 14, 3), /* 220 */
+ /* 001 */ V(9, 12, 3),
+ /* 010 */ V(12, 9, 2),
+ /* 011 */ V(12, 9, 2),
+ /* 100 */ V(5, 14, 2),
+ /* 101 */ V(5, 14, 2),
+ /* 110 */ V(11, 10, 2),
+ /* 111 */ V(11, 10, 2),
+
+ /* 0100 0010 ... */
+ /* 000 */ V(14, 5, 2), /* 228 */
+ /* 001 */ V(14, 5, 2),
+ /* 010 */ V(10, 11, 3),
+ /* 011 */ V(7, 13, 3),
+ /* 100 */ V(13, 7, 2),
+ /* 101 */ V(13, 7, 2),
+ /* 110 */ V(14, 4, 2),
+ /* 111 */ V(14, 4, 2),
+
+ /* 0100 0011 ... */
+ /* 000 */ V(8, 12, 2), /* 236 */
+ /* 001 */ V(8, 12, 2),
+ /* 010 */ V(12, 8, 2),
+ /* 011 */ V(12, 8, 2),
+ /* 100 */ V(4, 14, 3),
+ /* 101 */ V(2, 14, 3),
+ /* 110 */ V(3, 14, 2),
+ /* 111 */ V(3, 14, 2),
+
+ /* 0100 0100 ... */
+ /* 00 */ V(6, 13, 2), /* 244 */
+ /* 01 */ V(13, 6, 2),
+ /* 10 */ V(14, 3, 2),
+ /* 11 */ V(9, 11, 2),
+
+ /* 0100 0101 ... */
+ /* 00 */ V(11, 9, 2), /* 248 */
+ /* 01 */ V(10, 10, 2),
+ /* 10 */ V(14, 2, 2),
+ /* 11 */ V(1, 14, 2),
+
+ /* 0100 0110 ... */
+ /* 00 */ V(14, 1, 2), /* 252 */
+ /* 01 */ V(5, 13, 2),
+ /* 10 */ V(13, 5, 2),
+ /* 11 */ V(7, 12, 2),
+
+ /* 0100 0111 ... */
+ /* 00 */ V(12, 7, 2), /* 256 */
+ /* 01 */ V(4, 13, 2),
+ /* 10 */ V(8, 11, 2),
+ /* 11 */ V(11, 8, 2),
+
+ /* 0100 1000 ... */
+ /* 00 */ V(13, 4, 2), /* 260 */
+ /* 01 */ V(9, 10, 2),
+ /* 10 */ V(10, 9, 2),
+ /* 11 */ V(6, 12, 2),
+
+ /* 0100 1001 ... */
+ /* 00 */ V(12, 6, 2), /* 264 */
+ /* 01 */ V(3, 13, 2),
+ /* 10 */ V(13, 3, 2),
+ /* 11 */ V(2, 13, 2),
+
+ /* 0100 1010 ... */
+ /* 00 */ V(13, 2, 2), /* 268 */
+ /* 01 */ V(1, 13, 2),
+ /* 10 */ V(7, 11, 2),
+ /* 11 */ V(11, 7, 2),
+
+ /* 0100 1011 ... */
+ /* 00 */ V(13, 1, 2), /* 272 */
+ /* 01 */ V(5, 12, 2),
+ /* 10 */ V(12, 5, 2),
+ /* 11 */ V(8, 10, 2),
+
+ /* 0100 1100 ... */
+ /* 00 */ V(10, 8, 2), /* 276 */
+ /* 01 */ V(9, 9, 2),
+ /* 10 */ V(4, 12, 2),
+ /* 11 */ V(12, 4, 2),
+
+ /* 0100 1101 ... */
+ /* 000 */ V(6, 11, 2), /* 280 */
+ /* 001 */ V(6, 11, 2),
+ /* 010 */ V(11, 6, 2),
+ /* 011 */ V(11, 6, 2),
+ /* 100 */ V(13, 0, 3),
+ /* 101 */ V(0, 12, 3),
+ /* 110 */ V(3, 12, 2),
+ /* 111 */ V(3, 12, 2),
+
+ /* 0100 1110 ... */
+ /* 00 */ V(12, 3, 2), /* 288 */
+ /* 01 */ V(7, 10, 2),
+ /* 10 */ V(10, 7, 2),
+ /* 11 */ V(2, 12, 2),
+
+ /* 0100 1111 ... */
+ /* 00 */ V(12, 2, 2), /* 292 */
+ /* 01 */ V(5, 11, 2),
+ /* 10 */ V(11, 5, 2),
+ /* 11 */ V(1, 12, 2),
+
+ /* 0101 0000 ... */
+ /* 00 */ V(8, 9, 2), /* 296 */
+ /* 01 */ V(9, 8, 2),
+ /* 10 */ V(12, 1, 2),
+ /* 11 */ V(4, 11, 2),
+
+ /* 0101 0001 ... */
+ /* 000 */ V(12, 0, 3), /* 300 */
+ /* 001 */ V(0, 11, 3),
+ /* 010 */ V(3, 11, 2),
+ /* 011 */ V(3, 11, 2),
+ /* 100 */ V(11, 0, 3),
+ /* 101 */ V(0, 10, 3),
+ /* 110 */ V(1, 10, 2),
+ /* 111 */ V(1, 10, 2),
+
+ /* 0101 0010 ... */
+ /* 00 */ V(11, 4, 1), /* 308 */
+ /* 01 */ V(11, 4, 1),
+ /* 10 */ V(6, 10, 2),
+ /* 11 */ V(10, 6, 2),
+
+ /* 0101 0011 ... */
+ /* 000 */ V(7, 9, 2), /* 312 */
+ /* 001 */ V(7, 9, 2),
+ /* 010 */ V(9, 7, 2),
+ /* 011 */ V(9, 7, 2),
+ /* 100 */ V(10, 0, 3),
+ /* 101 */ V(0, 9, 3),
+ /* 110 */ V(9, 0, 2),
+ /* 111 */ V(9, 0, 2),
+
+ /* 0101 0100 ... */
+ /* 0 */ V(11, 3, 1), /* 320 */
+ /* 1 */ V(8, 8, 1),
+
+ /* 0101 0101 ... */
+ /* 00 */ V(2, 11, 2), /* 322 */
+ /* 01 */ V(5, 10, 2),
+ /* 10 */ V(11, 2, 1),
+ /* 11 */ V(11, 2, 1),
+
+ /* 0101 0110 ... */
+ /* 00 */ V(10, 5, 2), /* 326 */
+ /* 01 */ V(1, 11, 2),
+ /* 10 */ V(11, 1, 2),
+ /* 11 */ V(6, 9, 2),
+
+ /* 0101 0111 ... */
+ /* 0 */ V(9, 6, 1), /* 330 */
+ /* 1 */ V(10, 4, 1),
+
+ /* 0101 1000 ... */
+ /* 00 */ V(4, 10, 2), /* 332 */
+ /* 01 */ V(7, 8, 2),
+ /* 10 */ V(8, 7, 1),
+ /* 11 */ V(8, 7, 1),
+
+ /* 0101 1001 ... */
+ /* 0 */ V(3, 10, 1), /* 336 */
+ /* 1 */ V(10, 3, 1),
+
+ /* 0101 1010 ... */
+ /* 0 */ V(5, 9, 1), /* 338 */
+ /* 1 */ V(9, 5, 1),
+
+ /* 0101 1011 ... */
+ /* 0 */ V(2, 10, 1), /* 340 */
+ /* 1 */ V(10, 2, 1),
+
+ /* 0101 1100 ... */
+ /* 0 */ V(10, 1, 1), /* 342 */
+ /* 1 */ V(6, 8, 1),
+
+ /* 0101 1101 ... */
+ /* 0 */ V(8, 6, 1), /* 344 */
+ /* 1 */ V(7, 7, 1),
+
+ /* 0101 1110 ... */
+ /* 0 */ V(4, 9, 1), /* 346 */
+ /* 1 */ V(9, 4, 1),
+
+ /* 0101 1111 ... */
+ /* 0 */ V(3, 9, 1), /* 348 */
+ /* 1 */ V(9, 3, 1),
+
+ /* 0110 0000 ... */
+ /* 0 */ V(5, 8, 1), /* 350 */
+ /* 1 */ V(8, 5, 1),
+
+ /* 0110 0001 ... */
+ /* 0 */ V(2, 9, 1), /* 352 */
+ /* 1 */ V(6, 7, 1),
+
+ /* 0110 0010 ... */
+ /* 0 */ V(7, 6, 1), /* 354 */
+ /* 1 */ V(9, 2, 1),
+
+ /* 0110 0011 ... */
+ /* 0 */ V(1, 9, 1), /* 356 */
+ /* 1 */ V(9, 1, 1),
+
+ /* 0110 0100 ... */
+ /* 0 */ V(4, 8, 1), /* 358 */
+ /* 1 */ V(8, 4, 1),
+
+ /* 0110 0101 ... */
+ /* 0 */ V(5, 7, 1), /* 360 */
+ /* 1 */ V(7, 5, 1),
+
+ /* 0110 0110 ... */
+ /* 0 */ V(3, 8, 1), /* 362 */
+ /* 1 */ V(8, 3, 1),
+
+ /* 0110 0111 ... */
+ /* 0 */ V(6, 6, 1), /* 364 */
+ /* 1 */ V(2, 8, 1),
+
+ /* 0110 1000 ... */
+ /* 0 */ V(8, 2, 1), /* 366 */
+ /* 1 */ V(1, 8, 1),
+
+ /* 0110 1001 ... */
+ /* 0 */ V(4, 7, 1), /* 368 */
+ /* 1 */ V(7, 4, 1),
+
+ /* 0110 1010 ... */
+ /* 00 */ V(8, 1, 1), /* 370 */
+ /* 01 */ V(8, 1, 1),
+ /* 10 */ V(0, 8, 2),
+ /* 11 */ V(8, 0, 2),
+
+ /* 0110 1011 ... */
+ /* 0 */ V(5, 6, 1), /* 374 */
+ /* 1 */ V(6, 5, 1),
+
+ /* 0110 1100 ... */
+ /* 00 */ V(1, 7, 1), /* 376 */
+ /* 01 */ V(1, 7, 1),
+ /* 10 */ V(0, 7, 2),
+ /* 11 */ V(7, 0, 2),
+
+ /* 0110 1110 ... */
+ /* 0 */ V(3, 7, 1), /* 380 */
+ /* 1 */ V(2, 7, 1),
+
+ /* 0111 1100 ... */
+ /* 0 */ V(0, 6, 1), /* 382 */
+ /* 1 */ V(6, 0, 1),
+
+ /* 1000 0011 ... */
+ /* 0 */ V(0, 5, 1), /* 384 */
+ /* 1 */ V(5, 0, 1)
+};
+
+# undef V
+# undef PTR
+
+/* external tables */
+
+union huffquad const *const mad_huff_quad_table[2] = { hufftabA, hufftabB };
+
+struct hufftable const mad_huff_pair_table[32] = {
+ /* 0 */ { hufftab0, 0, 0 },
+ /* 1 */ { hufftab1, 0, 3 },
+ /* 2 */ { hufftab2, 0, 3 },
+ /* 3 */ { hufftab3, 0, 3 },
+ /* 4 */ { 0 /* not used */ },
+ /* 5 */ { hufftab5, 0, 3 },
+ /* 6 */ { hufftab6, 0, 4 },
+ /* 7 */ { hufftab7, 0, 4 },
+ /* 8 */ { hufftab8, 0, 4 },
+ /* 9 */ { hufftab9, 0, 4 },
+ /* 10 */ { hufftab10, 0, 4 },
+ /* 11 */ { hufftab11, 0, 4 },
+ /* 12 */ { hufftab12, 0, 4 },
+ /* 13 */ { hufftab13, 0, 4 },
+ /* 14 */ { 0 /* not used */ },
+ /* 15 */ { hufftab15, 0, 4 },
+ /* 16 */ { hufftab16, 1, 4 },
+ /* 17 */ { hufftab16, 2, 4 },
+ /* 18 */ { hufftab16, 3, 4 },
+ /* 19 */ { hufftab16, 4, 4 },
+ /* 20 */ { hufftab16, 6, 4 },
+ /* 21 */ { hufftab16, 8, 4 },
+ /* 22 */ { hufftab16, 10, 4 },
+ /* 23 */ { hufftab16, 13, 4 },
+ /* 24 */ { hufftab24, 4, 4 },
+ /* 25 */ { hufftab24, 5, 4 },
+ /* 26 */ { hufftab24, 6, 4 },
+ /* 27 */ { hufftab24, 7, 4 },
+ /* 28 */ { hufftab24, 8, 4 },
+ /* 29 */ { hufftab24, 9, 4 },
+ /* 30 */ { hufftab24, 11, 4 },
+ /* 31 */ { hufftab24, 13, 4 }
+};
diff --git a/core/multimedia/opieplayer/libmad/huffman.h b/core/multimedia/opieplayer/libmad/huffman.h
new file mode 100644
index 0000000..1801210
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/huffman.h
@@ -0,0 +1,66 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifndef LIBMAD_HUFFMAN_H
+# define LIBMAD_HUFFMAN_H
+
+union huffquad {
+ struct {
+ unsigned short final : 1;
+ unsigned short hlen : 3;
+ unsigned short v : 1;
+ unsigned short w : 1;
+ unsigned short x : 1;
+ unsigned short y : 1;
+ } value;
+ struct {
+ unsigned short final : 1;
+ unsigned short bits : 3;
+ unsigned short offset : 12;
+ } ptr;
+ unsigned short final : 1;
+};
+
+union huffpair {
+ struct {
+ unsigned short final : 1;
+ unsigned short hlen : 3;
+ unsigned short x : 4;
+ unsigned short y : 4;
+ } value;
+ struct {
+ unsigned short final : 1;
+ unsigned short bits : 3;
+ unsigned short offset : 12;
+ } ptr;
+ unsigned short final : 1;
+};
+
+struct hufftable {
+ union huffpair const *table;
+ unsigned short linbits;
+ unsigned short startbits;
+};
+
+extern union huffquad const *const mad_huff_quad_table[2];
+extern struct hufftable const mad_huff_pair_table[32];
+
+# endif
diff --git a/core/multimedia/opieplayer/libmad/imdct_l_arm.S b/core/multimedia/opieplayer/libmad/imdct_l_arm.S
new file mode 100644
index 0000000..b86ba11
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/imdct_l_arm.S
@@ -0,0 +1,1000 @@
+/*****************************************************************************
+* Copyright (C) 2000-2001 Andre McCurdy <armccurdy@yahoo.co.uk>
+*
+* 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
+*
+*****************************************************************************
+*
+* Notes:
+*
+*
+*****************************************************************************
+*
+* $Id$
+*
+* 2001/03/24: Andre McCurdy <armccurdy@yahoo.co.uk>
+* - Corrected PIC unsafe loading of address of 'imdct36_long_karray'
+*
+* 2000/09/20: Robert Leslie <rob@mars.org>
+* - Added a global symbol with leading underscore per suggestion of
+* Simon Burge to support linking with the a.out format.
+*
+* 2000/09/15: Robert Leslie <rob@mars.org>
+* - Fixed a small bug where flags were changed before a conditional branch.
+*
+* 2000/09/15: Andre McCurdy <armccurdy@yahoo.co.uk>
+* - Applied Nicolas Pitre's rounding optimisation in all remaining places.
+*
+* 2000/09/09: Nicolas Pitre <nico@cam.org>
+* - Optimized rounding + scaling operations.
+*
+* 2000/08/09: Andre McCurdy <armccurdy@yahoo.co.uk>
+* - Original created.
+*
+****************************************************************************/
+
+
+/*
+ On entry:
+
+ r0 = pointer to 18 element input array
+ r1 = pointer to 36 element output array
+ r2 = windowing block type
+
+
+ Stack frame created during execution of the function:
+
+ Initial Holds:
+ Stack
+ pointer
+ minus:
+
+ 0
+ 4 lr
+ 8 r11
+ 12 r10
+ 16 r9
+ 20 r8
+ 24 r7
+ 28 r6
+ 32 r5
+ 36 r4
+
+ 40 r2 : windowing block type
+
+ 44 ct00 high
+ 48 ct00 low
+ 52 ct01 high
+ 56 ct01 low
+ 60 ct04 high
+ 64 ct04 low
+ 68 ct06 high
+ 72 ct06 low
+ 76 ct05 high
+ 80 ct05 low
+ 84 ct03 high
+ 88 ct03 low
+ 92 -ct05 high
+ 96 -ct05 low
+ 100 -ct07 high
+ 104 -ct07 low
+ 108 ct07 high
+ 112 ct07 low
+ 116 ct02 high
+ 120 ct02 low
+*/
+
+#define BLOCK_MODE_NORMAL 0
+#define BLOCK_MODE_START 1
+#define BLOCK_MODE_STOP 3
+
+
+#define X0 0x00
+#define X1 0x04
+#define X2 0x08
+#define X3 0x0C
+#define X4 0x10
+#define X5 0x14
+#define X6 0x18
+#define X7 0x1c
+#define X8 0x20
+#define X9 0x24
+#define X10 0x28
+#define X11 0x2c
+#define X12 0x30
+#define X13 0x34
+#define X14 0x38
+#define X15 0x3c
+#define X16 0x40
+#define X17 0x44
+
+#define x0 0x00
+#define x1 0x04
+#define x2 0x08
+#define x3 0x0C
+#define x4 0x10
+#define x5 0x14
+#define x6 0x18
+#define x7 0x1c
+#define x8 0x20
+#define x9 0x24
+#define x10 0x28
+#define x11 0x2c
+#define x12 0x30
+#define x13 0x34
+#define x14 0x38
+#define x15 0x3c
+#define x16 0x40
+#define x17 0x44
+#define x18 0x48
+#define x19 0x4c
+#define x20 0x50
+#define x21 0x54
+#define x22 0x58
+#define x23 0x5c
+#define x24 0x60
+#define x25 0x64
+#define x26 0x68
+#define x27 0x6c
+#define x28 0x70
+#define x29 0x74
+#define x30 0x78
+#define x31 0x7c
+#define x32 0x80
+#define x33 0x84
+#define x34 0x88
+#define x35 0x8c
+
+#define K00 0x0ffc19fd
+#define K01 0x00b2aa3e
+#define K02 0x0fdcf549
+#define K03 0x0216a2a2
+#define K04 0x0f9ee890
+#define K05 0x03768962
+#define K06 0x0f426cb5
+#define K07 0x04cfb0e2
+#define K08 0x0ec835e8
+#define K09 0x061f78aa
+#define K10 0x0e313245
+#define K11 0x07635284
+#define K12 0x0d7e8807
+#define K13 0x0898c779
+#define K14 0x0cb19346
+#define K15 0x09bd7ca0
+#define K16 0x0bcbe352
+#define K17 0x0acf37ad
+
+#define minus_K02 0xf0230ab7
+
+#define WL0 0x00b2aa3e
+#define WL1 0x0216a2a2
+#define WL2 0x03768962
+#define WL3 0x04cfb0e2
+#define WL4 0x061f78aa
+#define WL5 0x07635284
+#define WL6 0x0898c779
+#define WL7 0x09bd7ca0
+#define WL8 0x0acf37ad
+#define WL9 0x0bcbe352
+#define WL10 0x0cb19346
+#define WL11 0x0d7e8807
+#define WL12 0x0e313245
+#define WL13 0x0ec835e8
+#define WL14 0x0f426cb5
+#define WL15 0x0f9ee890
+#define WL16 0x0fdcf549
+#define WL17 0x0ffc19fd
+
+
+@*****************************************************************************
+
+
+ .text
+ .align
+
+ .global III_imdct_l
+ .global _III_imdct_l
+
+III_imdct_l:
+_III_imdct_l:
+
+ stmdb sp!, { r2, r4 - r11, lr } @ all callee saved regs, plus arg3
+
+ ldr r4, =K08 @ r4 = K08
+ ldr r5, =K09 @ r5 = K09
+ ldr r8, [r0, #X4] @ r8 = X4
+ ldr r9, [r0, #X13] @ r9 = X13
+ rsb r6, r4, #0 @ r6 = -K08
+ rsb r7, r5, #0 @ r7 = -K09
+
+ smull r2, r3, r4, r8 @ r2..r3 = (X4 * K08)
+ smlal r2, r3, r5, r9 @ r2..r3 = (X4 * K08) + (X13 * K09) = ct01
+
+ smull r10, lr, r8, r5 @ r10..lr = (X4 * K09)
+ smlal r10, lr, r9, r6 @ r10..lr = (X4 * K09) + (X13 * -K08) = ct00
+
+ ldr r8, [r0, #X7] @ r8 = X7
+ ldr r9, [r0, #X16] @ r9 = X16
+
+ stmdb sp!, { r2, r3, r10, lr } @ stack ct00_h, ct00_l, ct01_h, ct01_l
+
+ add r8, r8, r9 @ r8 = (X7 + X16)
+ ldr r9, [r0, #X1] @ r9 = X1
+
+ smlal r2, r3, r6, r8 @ r2..r3 = ct01 + ((X7 + X16) * -K08)
+ smlal r2, r3, r7, r9 @ r2..r3 += (X1 * -K09)
+
+ ldr r7, [r0, #X10] @ r7 = X10
+
+ rsbs r10, r10, #0
+ rsc lr, lr, #0 @ r10..lr = -ct00
+
+ smlal r2, r3, r5, r7 @ r2..r3 += (X10 * K09) = ct06
+
+ smlal r10, lr, r9, r6 @ r10..lr = -ct00 + ( X1 * -K08)
+ smlal r10, lr, r8, r5 @ r10..lr += ((X7 + X16) * K09)
+ smlal r10, lr, r7, r4 @ r10..lr += ( X10 * K08) = ct04
+
+ stmdb sp!, { r2, r3, r10, lr } @ stack ct04_h, ct04_l, ct06_h, ct06_l
+
+ @----
+
+ ldr r7, [r0, #X0]
+ ldr r8, [r0, #X11]
+ ldr r9, [r0, #X12]
+ sub r7, r7, r8
+ sub r7, r7, r9 @ r7 = (X0 - X11 -X12) = ct14
+
+ ldr r9, [r0, #X3]
+ ldr r8, [r0, #X8]
+ ldr r11, [r0, #X15]
+ sub r8, r8, r9
+ add r8, r8, r11 @ r8 = (X8 - X3 + X15) = ct16
+
+ add r11, r7, r8 @ r11 = ct14 + ct16 = ct18
+
+ smlal r2, r3, r6, r11 @ r2..r3 = ct06 + ((X0 - X11 - X3 + X15 + X8 - X12) * -K08)
+
+ ldr r6, [r0, #X2]
+ ldr r9, [r0, #X9]
+ ldr r12, [r0, #X14]
+ sub r6, r6, r9
+ sub r6, r6, r12 @ r6 = (X2 - X9 - X14) = ct15
+
+ ldr r9, [r0, #X5]
+ ldr r12, [r0, #X6]
+ sub r9, r9, r12
+ ldr r12, [r0, #X17]
+ sub r9, r9, r12 @ r9 = (X5 - X6 - X17) = ct17
+
+ add r12, r9, r6 @ r12 = ct15 + ct17 = ct19
+
+ smlal r2, r3, r5, r12 @ r2..r3 += ((X2 - X9 + X5 - X6 - X17 - X14) * K09)
+
+ smlal r10, lr, r11, r5 @ r10..lr = ct04 + (ct18 * K09)
+ smlal r10, lr, r12, r4 @ r10..lr = ct04 + (ct18 * K09) + (ct19 * K08)
+
+ movs r2, r2, lsr #28
+ adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3
+ str r2, [r1, #x22] @ store result x22
+
+ movs r10, r10, lsr #28
+ adc r10, r10, lr, lsl #4 @ r10 = bits[59..28] of r10..lr
+ str r10, [r1, #x4] @ store result x4
+
+ @----
+
+ ldmia sp, { r2, r3, r4, r5 } @ r2..r3 = ct06, r4..r5 = ct04 (dont update sp)
+
+ @ r2..r3 = ct06
+ @ r4..r5 = ct04
+ @ r6 = ct15
+ @ r7 = ct14
+ @ r8 = ct16
+ @ r9 = ct17
+ @ r10 = .
+ @ r11 = .
+ @ r12 = .
+ @ lr = .
+
+ ldr r10, =K03 @ r10 = K03
+ ldr lr, =K15 @ lr = K15
+
+ smlal r2, r3, r10, r7 @ r2..r3 = ct06 + (ct14 * K03)
+ smlal r4, r5, lr, r7 @ r4..r5 = ct04 + (ct14 * K15)
+
+ ldr r12, =K14 @ r12 = K14
+ rsb r10, r10, #0 @ r10 = -K03
+
+ smlal r2, r3, lr, r6 @ r2..r3 += (ct15 * K15)
+ smlal r4, r5, r10, r6 @ r4..r5 += (ct15 * -K03)
+ smlal r2, r3, r12, r8 @ r2..r3 += (ct16 * K14)
+
+ ldr r11, =minus_K02 @ r11 = -K02
+ rsb r12, r12, #0 @ r12 = -K14
+
+ smlal r4, r5, r12, r9 @ r4..r5 += (ct17 * -K14)
+ smlal r2, r3, r11, r9 @ r2..r3 += (ct17 * -K02)
+ smlal r4, r5, r11, r8 @ r4..r5 += (ct16 * -K02)
+
+ movs r2, r2, lsr #28
+ adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3
+ str r2, [r1, #x7] @ store result x7
+
+ movs r4, r4, lsr #28
+ adc r4, r4, r5, lsl #4 @ r4 = bits[59..28] of r4..r5
+ str r4, [r1, #x1] @ store result x1
+
+ @----
+
+ ldmia sp, { r2, r3, r4, r5 } @ r2..r3 = ct06, r4..r5 = ct04 (dont update sp)
+
+ @ r2..r3 = ct06
+ @ r4..r5 = ct04
+ @ r6 = ct15
+ @ r7 = ct14
+ @ r8 = ct16
+ @ r9 = ct17
+ @ r10 = -K03
+ @ r11 = -K02
+ @ r12 = -K14
+ @ lr = K15
+
+ rsbs r2, r2, #0
+ rsc r3, r3, #0 @ r2..r3 = -ct06
+
+ smlal r2, r3, r12, r7 @ r2..r3 = -ct06 + (ct14 * -K14)
+ smlal r2, r3, r10, r8 @ r2..r3 += (ct16 * -K03)
+
+ smlal r4, r5, r12, r6 @ r4..r5 = ct04 + (ct15 * -K14)
+ smlal r4, r5, r10, r9 @ r4..r5 += (ct17 * -K03)
+ smlal r4, r5, lr, r8 @ r4..r5 += (ct16 * K15)
+ smlal r4, r5, r11, r7 @ r4..r5 += (ct14 * -K02)
+
+ rsb lr, lr, #0 @ lr = -K15
+ rsb r11, r11, #0 @ r11 = K02
+
+ smlal r2, r3, lr, r9 @ r2..r3 += (ct17 * -K15)
+ smlal r2, r3, r11, r6 @ r2..r3 += (ct15 * K02)
+
+ movs r4, r4, lsr #28
+ adc r4, r4, r5, lsl #4 @ r4 = bits[59..28] of r4..r5
+ str r4, [r1, #x25] @ store result x25
+
+ movs r2, r2, lsr #28
+ adc r2, r2, r3, lsl #4 @ r2 = bits[59..28] of r2..r3
+ str r2, [r1, #x19] @ store result x19
+
+ @----
+
+ ldr r2, [sp, #16] @ r2 = ct01_l
+ ldr r3, [sp, #20] @ r3 = ct01_h
+
+ ldr r6, [r0, #X1]
+ ldr r8, [r0, #X7]
+ ldr r9, [r0, #X10]
+ ldr r7, [r0, #X16]
+
+ rsbs r2, r2, #0
+ rsc r3, r3, #0 @ r2..r3 = -ct01
+
+ mov r4, r2
+ mov r5, r3 @ r4..r5 = -ct01
+
+ @ r2..r3 = -ct01
+ @ r4..r5 = -ct01
+ @ r6 = X1
+ @ r7 = X16
+ @ r8 = X7
+ @ r9 = X10
+ @ r10 = -K03
+ @ r11 = K02
+ @ r12 = -K14
+ @ lr = -K15
+
+ smlal r4, r5, r12, r7 @ r4..r5 = -ct01 + (X16 * -K14)
+ smlal r2, r3, lr, r9 @ r2..r3 = -ct01 + (X10 * -K15)
+
+ smlal r4, r5, r10, r8 @ r4..r5 += (X7 * -K03)
+ smlal r2, r3, r10, r7 @ r2..r3 += (X16 * -K03)
+
+ smlal r4, r5, r11, r9 @ r4..r5 += (X10 * K02)
+ smlal r2, r3, r12, r8 @ r2..r3 += (X7 * -K14)
+
+ rsb lr, lr, #0 @ lr = K15
+ rsb r11, r11, #0 @ r11 = -K02
+
+ smlal r4, r5, lr, r6 @ r4..r5 += (X1 * K15) = ct05
+ smlal r2, r3, r11, r6 @ r2..r3 += (X1 * -K02) = ct03
+
+ stmdb sp!, { r2, r3, r4, r5 } @ stack ct05_h, ct05_l, ct03_h, ct03_l
+
+ rsbs r4, r4, #0
+ rsc r5, r5, #0 @ r4..r5 = -ct05
+
+ stmdb sp!, { r4, r5 } @ stack -ct05_h, -ct05_l
+
+ ldr r2, [sp, #48] @ r2 = ct00_l
+ ldr r3, [sp, #52] @ r3 = ct00_h
+
+ rsb r10, r10, #0 @ r10 = K03
+
+ rsbs r4, r2, #0
+ rsc r5, r3, #0 @ r4..r5 = -ct00
+
+ @ r2..r3 = ct00
+ @ r4..r5 = -ct00
+ @ r6 = X1
+ @ r7 = X16
+ @ r8 = X7
+ @ r9 = X10
+ @ r10 = K03
+ @ r11 = -K02
+ @ r12 = -K14
+ @ lr = K15
+
+ smlal r4, r5, r10, r6 @ r4..r5 = -ct00 + (X1 * K03)
+ smlal r2, r3, r10, r9 @ r2..r3 = ct00 + (X10 * K03)
+
+ smlal r4, r5, r12, r9 @ r4..r5 += (X10 * -K14)
+ smlal r2, r3, r12, r6 @ r2..r3 += (X1 * -K14)
+
+ smlal r4, r5, r11, r7 @ r4..r5 += (X16 * -K02)
+ smlal r4, r5, lr, r8 @ r4..r5 += (X7 * K15) = ct07
+
+ rsb lr, lr, #0 @ lr = -K15
+ rsb r11, r11, #0 @ r11 = K02
+
+ smlal r2, r3, r11, r8 @ r2..r3 += (X7 * K02)
+ smlal r2, r3, lr, r7 @ r2..r3 += (X16 * -K15) = ct02
+
+ rsbs r6, r4, #0
+ rsc r7, r5, #0 @ r6..r7 = -ct07
+
+ stmdb sp!, { r2 - r7 } @ stack -ct07_h, -ct07_l, ct07_h, ct07_l, ct02_h, ct02_l
+
+
+ @----
+
+ add r2, pc, #(imdct36_long_karray-.-8) @ r2 = base address of Knn array (PIC safe ?)
+
+
+loop:
+ ldr r12, [r0, #X0]
+
+ ldmia r2!, { r5 - r11 } @ first 7 words from Karray element
+
+ smull r3, r4, r5, r12 @ sum = (Kxx * X0)
+ ldr r12, [r0, #X2]
+ ldr r5, [r0, #X3]
+ smlal r3, r4, r6, r12 @ sum += (Kxx * X2)
+ ldr r12, [r0, #X5]
+ ldr r6, [r0, #X6]
+ smlal r3, r4, r7, r5 @ sum += (Kxx * X3)
+ smlal r3, r4, r8, r12 @ sum += (Kxx * X5)
+ ldr r12, [r0, #X8]
+ ldr r5, [r0, #X9]
+ smlal r3, r4, r9, r6 @ sum += (Kxx * X6)
+ smlal r3, r4, r10, r12 @ sum += (Kxx * X8)
+ smlal r3, r4, r11, r5 @ sum += (Kxx * X9)
+
+ ldmia r2!, { r5 - r10 } @ final 6 words from Karray element
+
+ ldr r11, [r0, #X11]
+ ldr r12, [r0, #X12]
+ smlal r3, r4, r5, r11 @ sum += (Kxx * X11)
+ ldr r11, [r0, #X14]
+ ldr r5, [r0, #X15]
+ smlal r3, r4, r6, r12 @ sum += (Kxx * X12)
+ smlal r3, r4, r7, r11 @ sum += (Kxx * X14)
+ ldr r11, [r0, #X17]
+ smlal r3, r4, r8, r5 @ sum += (Kxx * X15)
+ smlal r3, r4, r9, r11 @ sum += (Kxx * X17)
+
+ add r5, sp, r10, lsr #16 @ create index back into stack for required ctxx
+
+ ldmia r5, { r6, r7 } @ r6..r7 = ctxx
+
+ mov r8, r10, lsl #16 @ push ctxx index off the top end
+
+ adds r3, r3, r6 @ add low words
+ adc r4, r4, r7 @ add high words, with carry
+ movs r3, r3, lsr #28
+ adc r3, r3, r4, lsl #4 @ r3 = bits[59..28] of r3..r4
+
+ str r3, [r1, r8, lsr #24] @ push completion flag off the bottom end
+
+ movs r8, r8, lsl #8 @ push result location index off the top end
+ beq loop @ loop back if completion flag not set
+ b imdct_l_windowing @ branch to windowing stage if looping finished
+
+imdct36_long_karray:
+
+ .word K17, -K13, K10, -K06, -K05, K01, -K00, K04, -K07, K11, K12, -K16, 0x00000000
+ .word K13, K07, K16, K01, K10, -K05, K04, -K11, K00, -K17, K06, -K12, 0x00200800
+ .word K11, K17, K05, K12, -K01, K06, -K07, K00, -K13, K04, -K16, K10, 0x00200c00
+ .word K07, K00, -K12, K05, -K16, -K10, K11, -K17, K04, K13, K01, K06, 0x00001400
+ .word K05, K10, -K00, -K17, K07, -K13, K12, K06, -K16, K01, -K11, -K04, 0x00181800
+ .word K01, K05, -K07, -K11, K13, K17, -K16, -K12, K10, K06, -K04, -K00, 0x00102000
+ .word -K16, K12, -K11, K07, K04, -K00, -K01, K05, -K06, K10, K13, -K17, 0x00284800
+ .word -K12, K06, K17, -K00, -K11, K04, K05, -K10, K01, K16, -K07, -K13, 0x00085000
+ .word -K10, K16, K04, -K13, -K00, K07, K06, -K01, -K12, -K05, K17, K11, 0x00105400
+ .word -K06, -K01, K13, K04, K17, -K11, -K10, -K16, -K05, K12, K00, K07, 0x00185c00
+ .word -K04, -K11, -K01, K16, K06, K12, K13, -K07, -K17, -K00, -K10, -K05, 0x00006000
+ .word -K00, -K04, -K06, -K10, -K12, -K16, -K17, -K13, -K11, -K07, -K05, -K01, 0x00206801
+
+
+ @----
+ @-------------------------------------------------------------------------
+ @----
+
+imdct_l_windowing:
+
+ ldr r11, [sp, #80] @ fetch function parameter 3 from out of the stack
+ ldmia r1!, { r0, r2 - r9 } @ load 9 words from x0, update pointer
+
+ @ r0 = x0
+ @ r1 = &x[9]
+ @ r2 = x1
+ @ r3 = x2
+ @ r4 = x3
+ @ r5 = x4
+ @ r6 = x5
+ @ r7 = x6
+ @ r8 = x7
+ @ r9 = x8
+ @ r10 = .
+ @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block)
+ @ r12 = .
+ @ lr = .
+
+ cmp r11, #BLOCK_MODE_STOP @ setup flags
+ rsb r10, r0, #0 @ r10 = -x0 (DONT change flags !!)
+ beq stop_block_x0_to_x17
+
+
+ @ start and normal blocks are treated the same for x[0]..x[17]
+
+normal_block_x0_to_x17:
+
+ ldr r12, =WL9 @ r12 = window_l[9]
+
+ rsb r0, r9, #0 @ r0 = -x8
+ rsb r9, r2, #0 @ r9 = -x1
+ rsb r2, r8, #0 @ r2 = -x7
+ rsb r8, r3, #0 @ r8 = -x2
+ rsb r3, r7, #0 @ r3 = -x6
+ rsb r7, r4, #0 @ r7 = -x3
+ rsb r4, r6, #0 @ r4 = -x5
+ rsb r6, r5, #0 @ r6 = -x4
+
+ @ r0 = -x8
+ @ r1 = &x[9]
+ @ r2 = -x7
+ @ r3 = -x6
+ @ r4 = -x5
+ @ r5 = .
+ @ r6 = -x4
+ @ r7 = -x3
+ @ r8 = -x2
+ @ r9 = -x1
+ @ r10 = -x0
+ @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block)
+ @ r12 = window_l[9]
+ @ lr = .
+
+ smull r5, lr, r12, r0 @ r5..lr = (window_l[9] * (x[9] == -x[8]))
+ ldr r12, =WL10 @ r12 = window_l[10]
+ movs r5, r5, lsr #28
+ adc r0, r5, lr, lsl #4 @ r0 = bits[59..28] of windowed x9
+
+ smull r5, lr, r12, r2 @ r5..lr = (window_l[10] * (x[10] == -x[7]))
+ ldr r12, =WL11 @ r12 = window_l[11]
+ movs r5, r5, lsr #28
+ adc r2, r5, lr, lsl #4 @ r2 = bits[59..28] of windowed x10
+
+ smull r5, lr, r12, r3 @ r5..lr = (window_l[11] * (x[11] == -x[6]))
+ ldr r12, =WL12 @ r12 = window_l[12]
+ movs r5, r5, lsr #28
+ adc r3, r5, lr, lsl #4 @ r3 = bits[59..28] of windowed x11
+
+ smull r5, lr, r12, r4 @ r5..lr = (window_l[12] * (x[12] == -x[5]))
+ ldr r12, =WL13 @ r12 = window_l[13]
+ movs r5, r5, lsr #28
+ adc r4, r5, lr, lsl #4 @ r4 = bits[59..28] of windowed x12
+
+ smull r5, lr, r12, r6 @ r5..lr = (window_l[13] * (x[13] == -x[4]))
+ ldr r12, =WL14 @ r12 = window_l[14]
+ movs r5, r5, lsr #28
+ adc r6, r5, lr, lsl #4 @ r6 = bits[59..28] of windowed x13
+
+ smull r5, lr, r12, r7 @ r5..lr = (window_l[14] * (x[14] == -x[3]))
+ ldr r12, =WL15 @ r12 = window_l[15]
+ movs r5, r5, lsr #28
+ adc r7, r5, lr, lsl #4 @ r7 = bits[59..28] of windowed x14
+
+ smull r5, lr, r12, r8 @ r5..lr = (window_l[15] * (x[15] == -x[2]))
+ ldr r12, =WL16 @ r12 = window_l[16]
+ movs r5, r5, lsr #28
+ adc r8, r5, lr, lsl #4 @ r8 = bits[59..28] of windowed x15
+
+ smull r5, lr, r12, r9 @ r5..lr = (window_l[16] * (x[16] == -x[1]))
+ ldr r12, =WL17 @ r12 = window_l[17]
+ movs r5, r5, lsr #28
+ adc r9, r5, lr, lsl #4 @ r9 = bits[59..28] of windowed x16
+
+ smull r5, lr, r12, r10 @ r5..lr = (window_l[17] * (x[17] == -x[0]))
+ ldr r12, =WL0 @ r12 = window_l[0]
+ movs r5, r5, lsr #28
+ adc r10, r5, lr, lsl #4 @ r10 = bits[59..28] of windowed x17
+
+
+ stmia r1, { r0, r2 - r4, r6 - r10 } @ store windowed x[9] .. x[17]
+ ldmdb r1!, { r0, r2 - r9 } @ load 9 words downto (and including) x0
+
+
+ smull r10, lr, r12, r0 @ r10..lr = (window_l[0] * x[0])
+ ldr r12, =WL1 @ r12 = window_l[1]
+ movs r10, r10, lsr #28
+ adc r0, r10, lr, lsl #4 @ r0 = bits[59..28] of windowed x0
+
+ smull r10, lr, r12, r2 @ r10..lr = (window_l[1] * x[1])
+ ldr r12, =WL2 @ r12 = window_l[2]
+ movs r10, r10, lsr #28
+ adc r2, r10, lr, lsl #4 @ r2 = bits[59..28] of windowed x1
+
+ smull r10, lr, r12, r3 @ r10..lr = (window_l[2] * x[2])
+ ldr r12, =WL3 @ r12 = window_l[3]
+ movs r10, r10, lsr #28
+ adc r3, r10, lr, lsl #4 @ r3 = bits[59..28] of windowed x2
+
+ smull r10, lr, r12, r4 @ r10..lr = (window_l[3] * x[3])
+ ldr r12, =WL4 @ r12 = window_l[4]
+ movs r10, r10, lsr #28
+ adc r4, r10, lr, lsl #4 @ r4 = bits[59..28] of windowed x3
+
+ smull r10, lr, r12, r5 @ r10..lr = (window_l[4] * x[4])
+ ldr r12, =WL5 @ r12 = window_l[5]
+ movs r10, r10, lsr #28
+ adc r5, r10, lr, lsl #4 @ r5 = bits[59..28] of windowed x4
+
+ smull r10, lr, r12, r6 @ r10..lr = (window_l[5] * x[5])
+ ldr r12, =WL6 @ r12 = window_l[6]
+ movs r10, r10, lsr #28
+ adc r6, r10, lr, lsl #4 @ r6 = bits[59..28] of windowed x5
+
+ smull r10, lr, r12, r7 @ r10..lr = (window_l[6] * x[6])
+ ldr r12, =WL7 @ r12 = window_l[7]
+ movs r10, r10, lsr #28
+ adc r7, r10, lr, lsl #4 @ r7 = bits[59..28] of windowed x6
+
+ smull r10, lr, r12, r8 @ r10..lr = (window_l[7] * x[7])
+ ldr r12, =WL8 @ r12 = window_l[8]
+ movs r10, r10, lsr #28
+ adc r8, r10, lr, lsl #4 @ r8 = bits[59..28] of windowed x7
+
+ smull r10, lr, r12, r9 @ r10..lr = (window_l[8] * x[8])
+ movs r10, r10, lsr #28
+ adc r9, r10, lr, lsl #4 @ r9 = bits[59..28] of windowed x8
+
+ stmia r1, { r0, r2 - r9 } @ store windowed x[0] .. x[8]
+
+ cmp r11, #BLOCK_MODE_START
+ beq start_block_x18_to_x35
+
+
+ @----
+
+
+normal_block_x18_to_x35:
+
+ ldr r11, =WL3 @ r11 = window_l[3]
+ ldr r12, =WL4 @ r12 = window_l[4]
+
+ add r1, r1, #(18*4) @ r1 = &x[18]
+
+ ldmia r1!, { r0, r2 - r4, r6 - r10 } @ load 9 words from x18, update pointer
+
+ @ r0 = x18
+ @ r1 = &x[27]
+ @ r2 = x19
+ @ r3 = x20
+ @ r4 = x21
+ @ r5 = .
+ @ r6 = x22
+ @ r7 = x23
+ @ r8 = x24
+ @ r9 = x25
+ @ r10 = x26
+ @ r11 = window_l[3]
+ @ r12 = window_l[4]
+ @ lr = .
+
+ smull r5, lr, r12, r6 @ r5..lr = (window_l[4] * (x[22] == x[31]))
+ movs r5, r5, lsr #28
+ adc r5, r5, lr, lsl #4 @ r5 = bits[59..28] of windowed x31
+
+ smull r6, lr, r11, r4 @ r5..lr = (window_l[3] * (x[21] == x[32]))
+ ldr r12, =WL5 @ r12 = window_l[5]
+ movs r6, r6, lsr #28
+ adc r6, r6, lr, lsl #4 @ r6 = bits[59..28] of windowed x32
+
+ smull r4, lr, r12, r7 @ r4..lr = (window_l[5] * (x[23] == x[30]))
+ ldr r11, =WL1 @ r11 = window_l[1]
+ ldr r12, =WL2 @ r12 = window_l[2]
+ movs r4, r4, lsr #28
+ adc r4, r4, lr, lsl #4 @ r4 = bits[59..28] of windowed x30
+
+ smull r7, lr, r12, r3 @ r7..lr = (window_l[2] * (x[20] == x[33]))
+ ldr r12, =WL6 @ r12 = window_l[6]
+ movs r7, r7, lsr #28
+ adc r7, r7, lr, lsl #4 @ r7 = bits[59..28] of windowed x33
+
+ smull r3, lr, r12, r8 @ r3..lr = (window_l[6] * (x[24] == x[29]))
+ movs r3, r3, lsr #28
+ adc r3, r3, lr, lsl #4 @ r3 = bits[59..28] of windowed x29
+
+ smull r8, lr, r11, r2 @ r7..lr = (window_l[1] * (x[19] == x[34]))
+ ldr r12, =WL7 @ r12 = window_l[7]
+ ldr r11, =WL8 @ r11 = window_l[8]
+ movs r8, r8, lsr #28
+ adc r8, r8, lr, lsl #4 @ r8 = bits[59..28] of windowed x34
+
+ smull r2, lr, r12, r9 @ r7..lr = (window_l[7] * (x[25] == x[28]))
+ ldr r12, =WL0 @ r12 = window_l[0]
+ movs r2, r2, lsr #28
+ adc r2, r2, lr, lsl #4 @ r2 = bits[59..28] of windowed x28
+
+ smull r9, lr, r12, r0 @ r3..lr = (window_l[0] * (x[18] == x[35]))
+ movs r9, r9, lsr #28
+ adc r9, r9, lr, lsl #4 @ r9 = bits[59..28] of windowed x35
+
+ smull r0, lr, r11, r10 @ r7..lr = (window_l[8] * (x[26] == x[27]))
+ ldr r11, =WL16 @ r11 = window_l[16]
+ ldr r12, =WL17 @ r12 = window_l[17]
+ movs r0, r0, lsr #28
+ adc r0, r0, lr, lsl #4 @ r0 = bits[59..28] of windowed x27
+
+
+ stmia r1, { r0, r2 - r9 } @ store windowed x[27] .. x[35]
+ ldmdb r1!, { r0, r2 - r9 } @ load 9 words downto (and including) x18
+
+
+ smull r10, lr, r12, r0 @ r10..lr = (window_l[17] * x[18])
+ movs r10, r10, lsr #28
+ adc r0, r10, lr, lsl #4 @ r0 = bits[59..28] of windowed x0
+
+ smull r10, lr, r11, r2 @ r10..lr = (window_l[16] * x[19])
+ ldr r11, =WL14 @ r11 = window_l[14]
+ ldr r12, =WL15 @ r12 = window_l[15]
+ movs r10, r10, lsr #28
+ adc r2, r10, lr, lsl #4 @ r2 = bits[59..28] of windowed x1
+
+ smull r10, lr, r12, r3 @ r10..lr = (window_l[15] * x[20])
+ movs r10, r10, lsr #28
+ adc r3, r10, lr, lsl #4 @ r3 = bits[59..28] of windowed x2
+
+ smull r10, lr, r11, r4 @ r10..lr = (window_l[14] * x[21])
+ ldr r11, =WL12 @ r11 = window_l[12]
+ ldr r12, =WL13 @ r12 = window_l[13]
+ movs r10, r10, lsr #28
+ adc r4, r10, lr, lsl #4 @ r4 = bits[59..28] of windowed x3
+
+ smull r10, lr, r12, r5 @ r10..lr = (window_l[13] * x[22])
+ movs r10, r10, lsr #28
+ adc r5, r10, lr, lsl #4 @ r5 = bits[59..28] of windowed x4
+
+ smull r10, lr, r11, r6 @ r10..lr = (window_l[12] * x[23])
+ ldr r11, =WL10 @ r12 = window_l[10]
+ ldr r12, =WL11 @ r12 = window_l[11]
+ movs r10, r10, lsr #28
+ adc r6, r10, lr, lsl #4 @ r6 = bits[59..28] of windowed x5
+
+ smull r10, lr, r12, r7 @ r10..lr = (window_l[11] * x[24])
+ movs r10, r10, lsr #28
+ adc r7, r10, lr, lsl #4 @ r7 = bits[59..28] of windowed x6
+
+ smull r10, lr, r11, r8 @ r10..lr = (window_l[10] * x[25])
+ ldr r12, =WL9 @ r12 = window_l[9]
+ movs r10, r10, lsr #28
+ adc r8, r10, lr, lsl #4 @ r8 = bits[59..28] of windowed x7
+
+ smull r10, lr, r12, r9 @ r10..lr = (window_l[9] * x[26])
+
+ movs r10, r10, lsr #28
+ adc r9, r10, lr, lsl #4 @ r9 = bits[59..28] of windowed x8
+
+ stmia r1, { r0, r2 - r9 } @ store windowed x[18] .. x[26]
+
+ @----
+ @ NB there are 2 possible exits from this function - this is only one of them
+ @----
+
+ add sp, sp, #(21*4) @ return stack frame
+ ldmia sp!, { r4 - r11, pc } @ restore callee saved regs, and return
+
+ @----
+
+
+stop_block_x0_to_x17:
+
+ @ r0 = x0
+ @ r1 = &x[9]
+ @ r2 = x1
+ @ r3 = x2
+ @ r4 = x3
+ @ r5 = x4
+ @ r6 = x5
+ @ r7 = x6
+ @ r8 = x7
+ @ r9 = x8
+ @ r10 = -x0
+ @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block)
+ @ r12 = .
+ @ lr = .
+
+ rsb r0, r6, #0 @ r0 = -x5
+ rsb r6, r2, #0 @ r6 = -x1
+ rsb r2, r5, #0 @ r2 = -x4
+ rsb r5, r3, #0 @ r5 = -x2
+ rsb r3, r4, #0 @ r3 = -x3
+
+ add r1, r1, #(3*4) @ r1 = &x[12]
+ stmia r1, { r0, r2, r3, r5, r6, r10 } @ store unchanged x[12] .. x[17]
+
+ ldr r0, =WL1 @ r0 = window_l[1] == window_s[0]
+
+ rsb r10, r9, #0 @ r10 = -x8
+ rsb r12, r8, #0 @ r12 = -x7
+ rsb lr, r7, #0 @ lr = -x6
+
+ @ r0 = WL1
+ @ r1 = &x[12]
+ @ r2 = .
+ @ r3 = .
+ @ r4 = .
+ @ r5 = .
+ @ r6 = .
+ @ r7 = x6
+ @ r8 = x7
+ @ r9 = x8
+ @ r10 = -x8
+ @ r11 = window mode: (0 == normal), (1 == start block), (3 == stop block)
+ @ r12 = -x7
+ @ lr = -x6
+
+ smull r5, r6, r0, r7 @ r5..r6 = (window_l[1] * x[6])
+ ldr r2, =WL4 @ r2 = window_l[4] == window_s[1]
+ movs r5, r5, lsr #28
+ adc r7, r5, r6, lsl #4 @ r7 = bits[59..28] of windowed x6
+
+ smull r5, r6, r2, r8 @ r5..r6 = (window_l[4] * x[7])
+ ldr r3, =WL7 @ r3 = window_l[7] == window_s[2]
+ movs r5, r5, lsr #28
+ adc r8, r5, r6, lsl #4 @ r8 = bits[59..28] of windowed x7
+
+ smull r5, r6, r3, r9 @ r5..r6 = (window_l[7] * x[8])
+ ldr r4, =WL10 @ r4 = window_l[10] == window_s[3]
+ movs r5, r5, lsr #28
+ adc r9, r5, r6, lsl #4 @ r9 = bits[59..28] of windowed x8
+
+ smull r5, r6, r4, r10 @ r5..r6 = (window_l[10] * (x[9] == -x[8]))
+ ldr r0, =WL13 @ r0 = window_l[13] == window_s[4]
+ movs r5, r5, lsr #28
+ adc r10, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9
+
+ smull r5, r6, r0, r12 @ r5..r6 = (window_l[13] * (x[10] == -x[7]))
+ ldr r2, =WL16 @ r2 = window_l[16] == window_s[5]
+ movs r5, r5, lsr #28
+ adc r12, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9
+
+ smull r5, r6, r2, lr @ r5..r6 = (window_l[16] * (x[11] == -x[6]))
+
+ ldr r0, =0x00
+
+ movs r5, r5, lsr #28
+ adc lr, r5, r6, lsl #4 @ r10 = bits[59..28] of windowed x9
+
+ stmdb r1!, { r7 - r10, r12, lr } @ store windowed x[6] .. x[11]
+
+ ldr r5, =0x00
+ ldr r6, =0x00
+ ldr r2, =0x00
+ ldr r3, =0x00
+ ldr r4, =0x00
+
+ stmdb r1!, { r0, r2 - r6 } @ store windowed x[0] .. x[5]
+
+ b normal_block_x18_to_x35
+
+
+ @----
+
+
+start_block_x18_to_x35:
+
+ ldr r4, =WL1 @ r0 = window_l[1] == window_s[0]
+
+ add r1, r1, #(24*4) @ r1 = &x[24]
+
+ ldmia r1, { r0, r2, r3 } @ load 3 words from x24, dont update pointer
+
+ @ r0 = x24
+ @ r1 = &x[24]
+ @ r2 = x25
+ @ r3 = x26
+ @ r4 = WL1
+ @ r5 = WL4
+ @ r6 = WL7
+ @ r7 = WL10
+ @ r8 = WL13
+ @ r9 = WL16
+ @ r10 = .
+ @ r11 = .
+ @ r12 = .
+ @ lr = .
+
+ ldr r5, =WL4 @ r5 = window_l[4] == window_s[1]
+
+ smull r10, r11, r4, r0 @ r10..r11 = (window_l[1] * (x[24] == x[29]))
+ ldr r6, =WL7 @ r6 = window_l[7] == window_s[2]
+ movs r10, r10, lsr #28
+ adc lr, r10, r11, lsl #4 @ lr = bits[59..28] of windowed x29
+
+ smull r10, r11, r5, r2 @ r10..r11 = (window_l[4] * (x[25] == x[28]))
+ ldr r7, =WL10 @ r7 = window_l[10] == window_s[3]
+ movs r10, r10, lsr #28
+ adc r12, r10, r11, lsl #4 @ r12 = bits[59..28] of windowed x28
+
+ smull r10, r11, r6, r3 @ r10..r11 = (window_l[7] * (x[26] == x[27]))
+ ldr r8, =WL13 @ r8 = window_l[13] == window_s[4]
+ movs r10, r10, lsr #28
+ adc r4, r10, r11, lsl #4 @ r4 = bits[59..28] of windowed x27
+
+ smull r10, r11, r7, r3 @ r10..r11 = (window_l[10] * x[26])
+ ldr r9, =WL16 @ r9 = window_l[16] == window_s[5]
+ movs r10, r10, lsr #28
+ adc r3, r10, r11, lsl #4 @ r3 = bits[59..28] of windowed x26
+
+ smull r10, r11, r8, r2 @ r10..r11 = (window_l[13] * x[25])
+ ldr r5, =0x00
+ movs r10, r10, lsr #28
+ adc r2, r10, r11, lsl #4 @ r2 = bits[59..28] of windowed x25
+
+ smull r10, r11, r9, r0 @ r10..r11 = (window_l[16] * x[24])
+ ldr r6, =0x00
+ movs r10, r10, lsr #28
+ adc r0, r10, r11, lsl #4 @ r0 = bits[59..28] of windowed x24
+
+ stmia r1!, { r0, r2, r3, r4, r12, lr } @ store windowed x[24] .. x[29]
+
+ ldr r7, =0x00
+ ldr r8, =0x00
+ ldr r9, =0x00
+ ldr r10, =0x00
+
+ stmia r1!, { r5 - r10 } @ store windowed x[30] .. x[35]
+
+ @----
+ @ NB there are 2 possible exits from this function - this is only one of them
+ @----
+
+ add sp, sp, #(21*4) @ return stack frame
+ ldmia sp!, { r4 - r11, pc } @ restore callee saved regs, and return
+
+ @----
+ @END
+ @----
+
diff --git a/core/multimedia/opieplayer/libmad/imdct_s.dat b/core/multimedia/opieplayer/libmad/imdct_s.dat
new file mode 100644
index 0000000..00d62eb
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/imdct_s.dat
@@ -0,0 +1,62 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+ /* 0 */ { MAD_F(0x09bd7ca0) /* 0.608761429 */,
+ -MAD_F(0x0ec835e8) /* -0.923879533 */,
+ -MAD_F(0x0216a2a2) /* -0.130526192 */,
+ MAD_F(0x0fdcf549) /* 0.991444861 */,
+ -MAD_F(0x061f78aa) /* -0.382683432 */,
+ -MAD_F(0x0cb19346) /* -0.793353340 */ },
+
+ /* 6 */ { -MAD_F(0x0cb19346) /* -0.793353340 */,
+ MAD_F(0x061f78aa) /* 0.382683432 */,
+ MAD_F(0x0fdcf549) /* 0.991444861 */,
+ MAD_F(0x0216a2a2) /* 0.130526192 */,
+ -MAD_F(0x0ec835e8) /* -0.923879533 */,
+ -MAD_F(0x09bd7ca0) /* -0.608761429 */ },
+
+ /* 1 */ { MAD_F(0x061f78aa) /* 0.382683432 */,
+ -MAD_F(0x0ec835e8) /* -0.923879533 */,
+ MAD_F(0x0ec835e8) /* 0.923879533 */,
+ -MAD_F(0x061f78aa) /* -0.382683432 */,
+ -MAD_F(0x061f78aa) /* -0.382683432 */,
+ MAD_F(0x0ec835e8) /* 0.923879533 */ },
+
+ /* 7 */ { -MAD_F(0x0ec835e8) /* -0.923879533 */,
+ -MAD_F(0x061f78aa) /* -0.382683432 */,
+ MAD_F(0x061f78aa) /* 0.382683432 */,
+ MAD_F(0x0ec835e8) /* 0.923879533 */,
+ MAD_F(0x0ec835e8) /* 0.923879533 */,
+ MAD_F(0x061f78aa) /* 0.382683432 */ },
+
+ /* 2 */ { MAD_F(0x0216a2a2) /* 0.130526192 */,
+ -MAD_F(0x061f78aa) /* -0.382683432 */,
+ MAD_F(0x09bd7ca0) /* 0.608761429 */,
+ -MAD_F(0x0cb19346) /* -0.793353340 */,
+ MAD_F(0x0ec835e8) /* 0.923879533 */,
+ -MAD_F(0x0fdcf549) /* -0.991444861 */ },
+
+ /* 8 */ { -MAD_F(0x0fdcf549) /* -0.991444861 */,
+ -MAD_F(0x0ec835e8) /* -0.923879533 */,
+ -MAD_F(0x0cb19346) /* -0.793353340 */,
+ -MAD_F(0x09bd7ca0) /* -0.608761429 */,
+ -MAD_F(0x061f78aa) /* -0.382683432 */,
+ -MAD_F(0x0216a2a2) /* -0.130526192 */ }
diff --git a/core/multimedia/opieplayer/libmad/layer12.c b/core/multimedia/opieplayer/libmad/layer12.c
new file mode 100644
index 0000000..41b17ca
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/layer12.c
@@ -0,0 +1,496 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifdef HAVE_CONFIG_H
+# include "libmad_config.h"
+# endif
+
+# include "libmad_global.h"
+
+# ifdef HAVE_LIMITS_H
+# include <limits.h>
+# else
+# define CHAR_BIT 8
+# endif
+
+# include "fixed.h"
+# include "bit.h"
+# include "stream.h"
+# include "frame.h"
+# include "layer12.h"
+
+/*
+ * scalefactor table
+ * used in both Layer I and Layer II decoding
+ */
+static
+mad_fixed_t const sf_table[63] = {
+# include "sf_table.dat"
+};
+
+/* --- Layer I ------------------------------------------------------------- */
+
+/* linear scaling table */
+static
+mad_fixed_t const linear_table[14] = {
+ MAD_F(0x15555555), /* 2^2 / (2^2 - 1) == 1.33333333333333 */
+ MAD_F(0x12492492), /* 2^3 / (2^3 - 1) == 1.14285714285714 */
+ MAD_F(0x11111111), /* 2^4 / (2^4 - 1) == 1.06666666666667 */
+ MAD_F(0x10842108), /* 2^5 / (2^5 - 1) == 1.03225806451613 */
+ MAD_F(0x10410410), /* 2^6 / (2^6 - 1) == 1.01587301587302 */
+ MAD_F(0x10204081), /* 2^7 / (2^7 - 1) == 1.00787401574803 */
+ MAD_F(0x10101010), /* 2^8 / (2^8 - 1) == 1.00392156862745 */
+ MAD_F(0x10080402), /* 2^9 / (2^9 - 1) == 1.00195694716243 */
+ MAD_F(0x10040100), /* 2^10 / (2^10 - 1) == 1.00097751710655 */
+ MAD_F(0x10020040), /* 2^11 / (2^11 - 1) == 1.00048851978505 */
+ MAD_F(0x10010010), /* 2^12 / (2^12 - 1) == 1.00024420024420 */
+ MAD_F(0x10008004), /* 2^13 / (2^13 - 1) == 1.00012208521548 */
+ MAD_F(0x10004001), /* 2^14 / (2^14 - 1) == 1.00006103888177 */
+ MAD_F(0x10002000) /* 2^15 / (2^15 - 1) == 1.00003051850948 */
+};
+
+/*
+ * NAME: I_sample()
+ * DESCRIPTION: decode one requantized Layer I sample from a bitstream
+ */
+static
+mad_fixed_t I_sample(struct mad_bitptr *ptr, unsigned int nb)
+{
+ mad_fixed_t sample;
+
+ sample = mad_bit_read(ptr, nb);
+
+ /* invert most significant bit, extend sign, then scale to fixed format */
+
+ sample ^= 1 << (nb - 1);
+ sample |= -(sample & (1 << (nb - 1)));
+
+ sample <<= MAD_F_FRACBITS - (nb - 1);
+
+ /* requantize the sample */
+
+ /* s'' = (2^nb / (2^nb - 1)) * (s''' + 2^(-nb + 1)) */
+
+ sample += MAD_F_ONE >> (nb - 1);
+
+ return mad_f_mul(sample, linear_table[nb - 2]);
+
+ /* s' = factor * s'' */
+ /* (to be performed by caller) */
+}
+
+/*
+ * NAME: layer->I()
+ * DESCRIPTION: decode a single Layer I frame
+ */
+int mad_layer_I(struct mad_stream *stream, struct mad_frame *frame)
+{
+ struct mad_header *header = &frame->header;
+ unsigned int nch, bound, ch, s, sb, nb;
+ unsigned char allocation[2][32], scalefactor[2][32];
+
+ nch = MAD_NCHANNELS(header);
+
+ bound = 32;
+ if (header->mode == MAD_MODE_JOINT_STEREO) {
+ header->flags |= MAD_FLAG_I_STEREO;
+ bound = 4 + header->mode_extension * 4;
+ }
+
+ /* check CRC word */
+
+ if (header->flags & MAD_FLAG_PROTECTION) {
+ header->crc_check =
+ mad_bit_crc(stream->ptr, 4 * (bound * nch + (32 - bound)),
+ header->crc_check);
+
+ if (header->crc_check != header->crc_target &&
+ !(frame->options & MAD_OPTION_IGNORECRC)) {
+ stream->error = MAD_ERROR_BADCRC;
+ return -1;
+ }
+ }
+
+ /* decode bit allocations */
+
+ for (sb = 0; sb < bound; ++sb) {
+ for (ch = 0; ch < nch; ++ch) {
+ nb = mad_bit_read(&stream->ptr, 4);
+
+ if (nb == 15) {
+ stream->error = MAD_ERROR_BADBITALLOC;
+ return -1;
+ }
+
+ allocation[ch][sb] = nb ? nb + 1 : 0;
+ }
+ }
+
+ for (sb = bound; sb < 32; ++sb) {
+ nb = mad_bit_read(&stream->ptr, 4);
+
+ if (nb == 15) {
+ stream->error = MAD_ERROR_BADBITALLOC;
+ return -1;
+ }
+
+ allocation[0][sb] =
+ allocation[1][sb] = nb ? nb + 1 : 0;
+ }
+
+ /* decode scalefactors */
+
+ for (sb = 0; sb < 32; ++sb) {
+ for (ch = 0; ch < nch; ++ch) {
+ if (allocation[ch][sb]) {
+ scalefactor[ch][sb] = mad_bit_read(&stream->ptr, 6);
+
+ if (scalefactor[ch][sb] == 63) {
+ stream->error = MAD_ERROR_BADSCALEFACTOR;
+ return -1;
+ }
+ }
+ }
+ }
+
+ /* decode samples */
+
+ for (s = 0; s < 12; ++s) {
+ for (sb = 0; sb < bound; ++sb) {
+ for (ch = 0; ch < nch; ++ch) {
+ nb = allocation[ch][sb];
+ frame->sbsample[ch][s][sb] = nb ?
+ mad_f_mul(I_sample(&stream->ptr, nb),
+ sf_table[scalefactor[ch][sb]]) : 0;
+ }
+ }
+
+ for (sb = bound; sb < 32; ++sb) {
+ if ((nb = allocation[0][sb])) {
+ mad_fixed_t sample;
+
+ sample = I_sample(&stream->ptr, nb);
+
+ for (ch = 0; ch < nch; ++ch) {
+ frame->sbsample[ch][s][sb] =
+ mad_f_mul(sample, sf_table[scalefactor[ch][sb]]);
+ }
+ }
+ else {
+ for (ch = 0; ch < nch; ++ch)
+ frame->sbsample[ch][s][sb] = 0;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* --- Layer II ------------------------------------------------------------ */
+
+/* possible quantization per subband table */
+static
+struct {
+ unsigned int sblimit;
+ unsigned char const offsets[30];
+} const sbquant_table[5] = {
+ /* ISO/IEC 11172-3 Table B.2a */
+ { 27, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, /* 0 */
+ 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 } },
+ /* ISO/IEC 11172-3 Table B.2b */
+ { 30, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, /* 1 */
+ 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0 } },
+ /* ISO/IEC 11172-3 Table B.2c */
+ { 8, { 5, 5, 2, 2, 2, 2, 2, 2 } }, /* 2 */
+ /* ISO/IEC 11172-3 Table B.2d */
+ { 12, { 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 } }, /* 3 */
+ /* ISO/IEC 13818-3 Table B.1 */
+ { 30, { 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, /* 4 */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } }
+};
+
+/* bit allocation table */
+static
+struct {
+ unsigned short nbal;
+ unsigned short offset;
+} const bitalloc_table[8] = {
+ { 2, 0 }, /* 0 */
+ { 2, 3 }, /* 1 */
+ { 3, 3 }, /* 2 */
+ { 3, 1 }, /* 3 */
+ { 4, 2 }, /* 4 */
+ { 4, 3 }, /* 5 */
+ { 4, 4 }, /* 6 */
+ { 4, 5 } /* 7 */
+};
+
+/* offsets into quantization class table */
+static
+unsigned char const offset_table[6][15] = {
+ { 0, 1, 16 }, /* 0 */
+ { 0, 1, 2, 3, 4, 5, 16 }, /* 1 */
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, /* 2 */
+ { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, /* 3 */
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 }, /* 4 */
+ { 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 } /* 5 */
+};
+
+/* quantization class table */
+static
+struct quantclass {
+ unsigned short nlevels;
+ unsigned char group;
+ unsigned char bits;
+ mad_fixed_t C;
+ mad_fixed_t D;
+} const qc_table[17] = {
+# include "qc_table.dat"
+};
+
+/*
+ * NAME: II_samples()
+ * DESCRIPTION: decode three requantized Layer II samples from a bitstream
+ */
+static
+void II_samples(struct mad_bitptr *ptr,
+ struct quantclass const *quantclass,
+ mad_fixed_t output[3])
+{
+ unsigned int nb, s, sample[3];
+
+ if ((nb = quantclass->group)) {
+ unsigned int c, nlevels;
+
+ /* degrouping */
+ c = mad_bit_read(ptr, quantclass->bits);
+ nlevels = quantclass->nlevels;
+
+ for (s = 0; s < 3; ++s) {
+ sample[s] = c % nlevels;
+ c /= nlevels;
+ }
+ }
+ else {
+ nb = quantclass->bits;
+
+ for (s = 0; s < 3; ++s)
+ sample[s] = mad_bit_read(ptr, nb);
+ }
+
+ for (s = 0; s < 3; ++s) {
+ mad_fixed_t requantized;
+
+ /* invert most significant bit, extend sign, then scale to fixed format */
+
+ requantized = sample[s] ^ (1 << (nb - 1));
+ requantized |= -(requantized & (1 << (nb - 1)));
+
+ requantized <<= MAD_F_FRACBITS - (nb - 1);
+
+ /* requantize the sample */
+
+ /* s'' = C * (s''' + D) */
+
+ output[s] = mad_f_mul(requantized + quantclass->D, quantclass->C);
+
+ /* s' = factor * s'' */
+ /* (to be performed by caller) */
+ }
+}
+
+/*
+ * NAME: layer->II()
+ * DESCRIPTION: decode a single Layer II frame
+ */
+int mad_layer_II(struct mad_stream *stream, struct mad_frame *frame)
+{
+ struct mad_header *header = &frame->header;
+ struct mad_bitptr start;
+ unsigned int index, sblimit, nbal, nch, bound, gr, ch, s, sb;
+ unsigned char const *offsets;
+ unsigned char allocation[2][32], scfsi[2][32], scalefactor[2][32][3];
+ mad_fixed_t samples[3];
+
+ nch = MAD_NCHANNELS(header);
+
+ if (header->flags & MAD_FLAG_LSF_EXT)
+ index = 4;
+ else {
+ switch (nch == 2 ? header->bitrate / 2 : header->bitrate) {
+ case 32000:
+ case 48000:
+ index = (header->samplerate == 32000) ? 3 : 2;
+ break;
+
+ case 56000:
+ case 64000:
+ case 80000:
+ index = 0;
+ break;
+
+ default:
+ index = (header->samplerate == 48000) ? 0 : 1;
+ }
+ }
+
+ sblimit = sbquant_table[index].sblimit;
+ offsets = sbquant_table[index].offsets;
+
+ bound = 32;
+ if (header->mode == MAD_MODE_JOINT_STEREO) {
+ header->flags |= MAD_FLAG_I_STEREO;
+ bound = 4 + header->mode_extension * 4;
+ }
+
+ if (bound > sblimit)
+ bound = sblimit;
+
+ start = stream->ptr;
+
+ /* decode bit allocations */
+
+ for (sb = 0; sb < bound; ++sb) {
+ nbal = bitalloc_table[offsets[sb]].nbal;
+
+ for (ch = 0; ch < nch; ++ch)
+ allocation[ch][sb] = mad_bit_read(&stream->ptr, nbal);
+ }
+
+ for (sb = bound; sb < sblimit; ++sb) {
+ nbal = bitalloc_table[offsets[sb]].nbal;
+
+ allocation[0][sb] =
+ allocation[1][sb] = mad_bit_read(&stream->ptr, nbal);
+ }
+
+ /* decode scalefactor selection info */
+
+ for (sb = 0; sb < sblimit; ++sb) {
+ for (ch = 0; ch < nch; ++ch) {
+ if (allocation[ch][sb])
+ scfsi[ch][sb] = mad_bit_read(&stream->ptr, 2);
+ }
+ }
+
+ /* check CRC word */
+
+ if (header->flags & MAD_FLAG_PROTECTION) {
+ header->crc_check =
+ mad_bit_crc(start, mad_bit_length(&start, &stream->ptr),
+ header->crc_check);
+
+ if (header->crc_check != header->crc_target &&
+ !(frame->options & MAD_OPTION_IGNORECRC)) {
+ stream->error = MAD_ERROR_BADCRC;
+ return -1;
+ }
+ }
+
+ /* decode scalefactors */
+
+ for (sb = 0; sb < sblimit; ++sb) {
+ for (ch = 0; ch < nch; ++ch) {
+ if (allocation[ch][sb]) {
+ scalefactor[ch][sb][0] = mad_bit_read(&stream->ptr, 6);
+
+ switch (scfsi[ch][sb]) {
+ case 2:
+ scalefactor[ch][sb][2] =
+ scalefactor[ch][sb][1] =
+ scalefactor[ch][sb][0];
+ break;
+
+ case 0:
+ scalefactor[ch][sb][1] = mad_bit_read(&stream->ptr, 6);
+ /* fall through */
+
+ case 1:
+ case 3:
+ scalefactor[ch][sb][2] = mad_bit_read(&stream->ptr, 6);
+ }
+
+ if (scfsi[ch][sb] & 1)
+ scalefactor[ch][sb][1] = scalefactor[ch][sb][scfsi[ch][sb] - 1];
+
+ if (scalefactor[ch][sb][0] == 63 ||
+ scalefactor[ch][sb][1] == 63 ||
+ scalefactor[ch][sb][2] == 63) {
+ stream->error = MAD_ERROR_BADSCALEFACTOR;
+ return -1;
+ }
+ }
+ }
+ }
+
+ /* decode samples */
+
+ for (gr = 0; gr < 12; ++gr) {
+ for (sb = 0; sb < bound; ++sb) {
+ for (ch = 0; ch < nch; ++ch) {
+ if ((index = allocation[ch][sb])) {
+ index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];
+
+ II_samples(&stream->ptr, &qc_table[index], samples);
+
+ for (s = 0; s < 3; ++s) {
+ frame->sbsample[ch][3 * gr + s][sb] =
+ mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
+ }
+ }
+ else {
+ for (s = 0; s < 3; ++s)
+ frame->sbsample[ch][3 * gr + s][sb] = 0;
+ }
+ }
+ }
+
+ for (sb = bound; sb < sblimit; ++sb) {
+ if ((index = allocation[0][sb])) {
+ index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1];
+
+ II_samples(&stream->ptr, &qc_table[index], samples);
+
+ for (ch = 0; ch < nch; ++ch) {
+ for (s = 0; s < 3; ++s) {
+ frame->sbsample[ch][3 * gr + s][sb] =
+ mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]);
+ }
+ }
+ }
+ else {
+ for (ch = 0; ch < nch; ++ch) {
+ for (s = 0; s < 3; ++s)
+ frame->sbsample[ch][3 * gr + s][sb] = 0;
+ }
+ }
+ }
+
+ for (ch = 0; ch < nch; ++ch) {
+ for (s = 0; s < 3; ++s) {
+ for (sb = sblimit; sb < 32; ++sb)
+ frame->sbsample[ch][3 * gr + s][sb] = 0;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmad/layer12.h b/core/multimedia/opieplayer/libmad/layer12.h
new file mode 100644
index 0000000..d2c81ac
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/layer12.h
@@ -0,0 +1,31 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifndef LIBMAD_LAYER12_H
+# define LIBMAD_LAYER12_H
+
+# include "stream.h"
+# include "frame.h"
+
+int mad_layer_I(struct mad_stream *, struct mad_frame *);
+int mad_layer_II(struct mad_stream *, struct mad_frame *);
+
+# endif
diff --git a/core/multimedia/opieplayer/libmad/layer3.c b/core/multimedia/opieplayer/libmad/layer3.c
new file mode 100644
index 0000000..194fc7e
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/layer3.c
@@ -0,0 +1,2492 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifdef HAVE_CONFIG_H
+# include "libmad_config.h"
+# endif
+
+# include "libmad_global.h"
+
+# include <stdlib.h>
+# include <string.h>
+# include <assert.h>
+
+# ifdef HAVE_LIMITS_H
+# include <limits.h>
+# else
+# define CHAR_BIT 8
+# endif
+
+# include "fixed.h"
+# include "bit.h"
+# include "stream.h"
+# include "frame.h"
+# include "huffman.h"
+# include "layer3.h"
+
+/* --- Layer III ----------------------------------------------------------- */
+
+enum {
+ count1table_select = 0x01,
+ scalefac_scale = 0x02,
+ preflag = 0x04,
+ mixed_block_flag = 0x08
+};
+
+struct sideinfo {
+ unsigned int main_data_begin;
+ unsigned int private_bits;
+
+ unsigned char scfsi[2];
+
+ struct granule {
+ struct channel {
+ /* from side info */
+ unsigned short part2_3_length;
+ unsigned short big_values;
+ unsigned short global_gain;
+ unsigned short scalefac_compress;
+
+ unsigned char flags;
+ unsigned char block_type;
+ unsigned char table_select[3];
+ unsigned char subblock_gain[3];
+ unsigned char region0_count;
+ unsigned char region1_count;
+
+ /* from main_data */
+ unsigned char scalefac[39]; /* scalefac_l and/or scalefac_s */
+ } ch[2];
+ } gr[2];
+};
+
+/*
+ * scalefactor bit lengths
+ * derived from section 2.4.2.7 of ISO/IEC 11172-3
+ */
+static
+struct {
+ unsigned char slen1;
+ unsigned char slen2;
+} const sflen_table[16] = {
+ { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 },
+ { 3, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 },
+ { 2, 1 }, { 2, 2 }, { 2, 3 }, { 3, 1 },
+ { 3, 2 }, { 3, 3 }, { 4, 2 }, { 4, 3 }
+};
+
+/*
+ * number of LSF scalefactor band values
+ * derived from section 2.4.3.2 of ISO/IEC 13818-3
+ */
+static
+unsigned char const nsfb_table[6][3][4] = {
+ { { 6, 5, 5, 5 },
+ { 9, 9, 9, 9 },
+ { 6, 9, 9, 9 } },
+
+ { { 6, 5, 7, 3 },
+ { 9, 9, 12, 6 },
+ { 6, 9, 12, 6 } },
+
+ { { 11, 10, 0, 0 },
+ { 18, 18, 0, 0 },
+ { 15, 18, 0, 0 } },
+
+ { { 7, 7, 7, 0 },
+ { 12, 12, 12, 0 },
+ { 6, 15, 12, 0 } },
+
+ { { 6, 6, 6, 3 },
+ { 12, 9, 9, 6 },
+ { 6, 12, 9, 6 } },
+
+ { { 8, 8, 5, 0 },
+ { 15, 12, 9, 0 },
+ { 6, 18, 9, 0 } }
+};
+
+/*
+ * MPEG-1 scalefactor band widths
+ * derived from Table B.8 of ISO/IEC 11172-3
+ */
+static
+unsigned char const sfb_48000_long[] = {
+ 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10,
+ 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192
+};
+
+static
+unsigned char const sfb_44100_long[] = {
+ 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10,
+ 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158
+};
+
+static
+unsigned char const sfb_32000_long[] = {
+ 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12,
+ 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26
+};
+
+static
+unsigned char const sfb_48000_short[] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
+ 6, 6, 6, 6, 6, 10, 10, 10, 12, 12, 12, 14, 14,
+ 14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66
+};
+
+static
+unsigned char const sfb_44100_short[] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
+ 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14,
+ 14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56
+};
+
+static
+unsigned char const sfb_32000_short[] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6,
+ 6, 6, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20,
+ 20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12
+};
+
+static
+unsigned char const sfb_48000_mixed[] = {
+ /* long */ 4, 4, 4, 4, 4, 4, 6, 6,
+ /* short */ 4, 4, 4, 6, 6, 6, 6, 6, 6, 10,
+ 10, 10, 12, 12, 12, 14, 14, 14, 16, 16,
+ 16, 20, 20, 20, 26, 26, 26, 66, 66, 66
+};
+
+static
+unsigned char const sfb_44100_mixed[] = {
+ /* long */ 4, 4, 4, 4, 4, 4, 6, 6,
+ /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 10,
+ 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
+ 18, 22, 22, 22, 30, 30, 30, 56, 56, 56
+};
+
+static
+unsigned char const sfb_32000_mixed[] = {
+ /* long */ 4, 4, 4, 4, 4, 4, 6, 6,
+ /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 12,
+ 12, 12, 16, 16, 16, 20, 20, 20, 26, 26,
+ 26, 34, 34, 34, 42, 42, 42, 12, 12, 12
+};
+
+/*
+ * MPEG-2 scalefactor band widths
+ * derived from Table B.2 of ISO/IEC 13818-3
+ */
+static
+unsigned char const sfb_24000_long[] = {
+ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
+ 18, 22, 26, 32, 38, 46, 54, 62, 70, 76, 36
+};
+
+static
+unsigned char const sfb_22050_long[] = {
+ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
+ 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54
+};
+
+# define sfb_16000_long sfb_22050_long
+
+static
+unsigned char const sfb_24000_short[] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8,
+ 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
+ 18, 24, 24, 24, 32, 32, 32, 44, 44, 44, 12, 12, 12
+};
+
+static
+unsigned char const sfb_22050_short[] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6,
+ 6, 6, 8, 8, 8, 10, 10, 10, 14, 14, 14, 18, 18,
+ 18, 26, 26, 26, 32, 32, 32, 42, 42, 42, 18, 18, 18
+};
+
+static
+unsigned char const sfb_16000_short[] = {
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8,
+ 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18,
+ 18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18
+};
+
+static
+unsigned char const sfb_24000_mixed[] = {
+ /* long */ 6, 6, 6, 6, 6, 6,
+ /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12,
+ 12, 12, 14, 14, 14, 18, 18, 18, 24, 24,
+ 24, 32, 32, 32, 44, 44, 44, 12, 12, 12
+};
+
+static
+unsigned char const sfb_22050_mixed[] = {
+ /* long */ 6, 6, 6, 6, 6, 6,
+ /* short */ 6, 6, 6, 6, 6, 6, 8, 8, 8, 10,
+ 10, 10, 14, 14, 14, 18, 18, 18, 26, 26,
+ 26, 32, 32, 32, 42, 42, 42, 18, 18, 18
+};
+
+static
+unsigned char const sfb_16000_mixed[] = {
+ /* long */ 6, 6, 6, 6, 6, 6,
+ /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12,
+ 12, 12, 14, 14, 14, 18, 18, 18, 24, 24,
+ 24, 30, 30, 30, 40, 40, 40, 18, 18, 18
+};
+
+/*
+ * MPEG 2.5 scalefactor band widths
+ * derived from public sources
+ */
+# define sfb_12000_long sfb_16000_long
+# define sfb_11025_long sfb_12000_long
+
+static
+unsigned char const sfb_8000_long[] = {
+ 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32,
+ 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2
+};
+
+# define sfb_12000_short sfb_16000_short
+# define sfb_11025_short sfb_12000_short
+
+static
+unsigned char const sfb_8000_short[] = {
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 16,
+ 16, 16, 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36,
+ 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26
+};
+
+# define sfb_12000_mixed sfb_16000_mixed
+# define sfb_11025_mixed sfb_12000_mixed
+
+/* the 8000 Hz short block scalefactor bands do not break after the first 36
+ frequency lines, so this is probably wrong */
+static
+unsigned char const sfb_8000_mixed[] = {
+ /* long */ 12, 12, 12,
+ /* short */ 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16,
+ 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, 36,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26
+};
+
+static
+struct {
+ unsigned char const *l;
+ unsigned char const *s;
+ unsigned char const *m;
+} const sfbwidth_table[9] = {
+ { sfb_48000_long, sfb_48000_short, sfb_48000_mixed },
+ { sfb_44100_long, sfb_44100_short, sfb_44100_mixed },
+ { sfb_32000_long, sfb_32000_short, sfb_32000_mixed },
+ { sfb_24000_long, sfb_24000_short, sfb_24000_mixed },
+ { sfb_22050_long, sfb_22050_short, sfb_22050_mixed },
+ { sfb_16000_long, sfb_16000_short, sfb_16000_mixed },
+ { sfb_12000_long, sfb_12000_short, sfb_12000_mixed },
+ { sfb_11025_long, sfb_11025_short, sfb_11025_mixed },
+ { sfb_8000_long, sfb_8000_short, sfb_8000_mixed }
+};
+
+/*
+ * scalefactor band preemphasis (used only when preflag is set)
+ * derived from Table B.6 of ISO/IEC 11172-3
+ */
+static
+unsigned char const pretab[22] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0
+};
+
+/*
+ * table for requantization
+ *
+ * rq_table[x].mantissa * 2^(rq_table[x].exponent) = x^(4/3)
+ */
+static
+struct fixedfloat {
+ unsigned long mantissa : 27;
+ unsigned short exponent : 5;
+} const rq_table[8207] = {
+# include "rq_table.dat"
+};
+
+/*
+ * fractional powers of two
+ * used for requantization and joint stereo decoding
+ *
+ * root_table[3 + x] = 2^(x/4)
+ */
+static
+mad_fixed_t const root_table[7] = {
+ MAD_F(0x09837f05) /* 2^(-3/4) == 0.59460355750136 */,
+ MAD_F(0x0b504f33) /* 2^(-2/4) == 0.70710678118655 */,
+ MAD_F(0x0d744fcd) /* 2^(-1/4) == 0.84089641525371 */,
+ MAD_F(0x10000000) /* 2^( 0/4) == 1.00000000000000 */,
+ MAD_F(0x1306fe0a) /* 2^(+1/4) == 1.18920711500272 */,
+ MAD_F(0x16a09e66) /* 2^(+2/4) == 1.41421356237310 */,
+ MAD_F(0x1ae89f99) /* 2^(+3/4) == 1.68179283050743 */
+};
+
+/*
+ * coefficients for aliasing reduction
+ * derived from Table B.9 of ISO/IEC 11172-3
+ *
+ * c[] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 }
+ * cs[i] = 1 / sqrt(1 + c[i]^2)
+ * ca[i] = c[i] / sqrt(1 + c[i]^2)
+ */
+static
+mad_fixed_t const cs[8] = {
+ +MAD_F(0x0db84a81) /* +0.857492926 */, +MAD_F(0x0e1b9d7f) /* +0.881741997 */,
+ +MAD_F(0x0f31adcf) /* +0.949628649 */, +MAD_F(0x0fbba815) /* +0.983314592 */,
+ +MAD_F(0x0feda417) /* +0.995517816 */, +MAD_F(0x0ffc8fc8) /* +0.999160558 */,
+ +MAD_F(0x0fff964c) /* +0.999899195 */, +MAD_F(0x0ffff8d3) /* +0.999993155 */
+};
+
+static
+mad_fixed_t const ca[8] = {
+ -MAD_F(0x083b5fe7) /* -0.514495755 */, -MAD_F(0x078c36d2) /* -0.471731969 */,
+ -MAD_F(0x05039814) /* -0.313377454 */, -MAD_F(0x02e91dd1) /* -0.181913200 */,
+ -MAD_F(0x0183603a) /* -0.094574193 */, -MAD_F(0x00a7cb87) /* -0.040965583 */,
+ -MAD_F(0x003a2847) /* -0.014198569 */, -MAD_F(0x000f27b4) /* -0.003699975 */
+};
+
+/*
+ * IMDCT coefficients for short blocks
+ * derived from section 2.4.3.4.10.2 of ISO/IEC 11172-3
+ *
+ * imdct_s[i/even][k] = cos((PI / 24) * (2 * (i / 2) + 7) * (2 * k + 1))
+ * imdct_s[i /odd][k] = cos((PI / 24) * (2 * (6 + (i-1)/2) + 7) * (2 * k + 1))
+ */
+static
+mad_fixed_t const imdct_s[6][6] = {
+# include "imdct_s.dat"
+};
+
+# if !defined(ASO_IMDCT)
+/*
+ * windowing coefficients for long blocks
+ * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3
+ *
+ * window_l[i] = sin((PI / 36) * (i + 1/2))
+ */
+static
+mad_fixed_t const window_l[36] = {
+ MAD_F(0x00b2aa3e) /* 0.043619387 */, MAD_F(0x0216a2a2) /* 0.130526192 */,
+ MAD_F(0x03768962) /* 0.216439614 */, MAD_F(0x04cfb0e2) /* 0.300705800 */,
+ MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x07635284) /* 0.461748613 */,
+ MAD_F(0x0898c779) /* 0.537299608 */, MAD_F(0x09bd7ca0) /* 0.608761429 */,
+ MAD_F(0x0acf37ad) /* 0.675590208 */, MAD_F(0x0bcbe352) /* 0.737277337 */,
+ MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x0d7e8807) /* 0.843391446 */,
+
+ MAD_F(0x0e313245) /* 0.887010833 */, MAD_F(0x0ec835e8) /* 0.923879533 */,
+ MAD_F(0x0f426cb5) /* 0.953716951 */, MAD_F(0x0f9ee890) /* 0.976296007 */,
+ MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ffc19fd) /* 0.999048222 */,
+ MAD_F(0x0ffc19fd) /* 0.999048222 */, MAD_F(0x0fdcf549) /* 0.991444861 */,
+ MAD_F(0x0f9ee890) /* 0.976296007 */, MAD_F(0x0f426cb5) /* 0.953716951 */,
+ MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0e313245) /* 0.887010833 */,
+
+ MAD_F(0x0d7e8807) /* 0.843391446 */, MAD_F(0x0cb19346) /* 0.793353340 */,
+ MAD_F(0x0bcbe352) /* 0.737277337 */, MAD_F(0x0acf37ad) /* 0.675590208 */,
+ MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0898c779) /* 0.537299608 */,
+ MAD_F(0x07635284) /* 0.461748613 */, MAD_F(0x061f78aa) /* 0.382683432 */,
+ MAD_F(0x04cfb0e2) /* 0.300705800 */, MAD_F(0x03768962) /* 0.216439614 */,
+ MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x00b2aa3e) /* 0.043619387 */,
+};
+# endif /* ASO_IMDCT */
+
+/*
+ * windowing coefficients for short blocks
+ * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3
+ *
+ * window_s[i] = sin((PI / 12) * (i + 1/2))
+ */
+static
+mad_fixed_t const window_s[12] = {
+ MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x061f78aa) /* 0.382683432 */,
+ MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0cb19346) /* 0.793353340 */,
+ MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0fdcf549) /* 0.991444861 */,
+ MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ec835e8) /* 0.923879533 */,
+ MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x09bd7ca0) /* 0.608761429 */,
+ MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0216a2a2) /* 0.130526192 */,
+};
+
+/*
+ * coefficients for intensity stereo processing
+ * derived from section 2.4.3.4.9.3 of ISO/IEC 11172-3
+ *
+ * is_ratio[i] = tan(i * (PI / 12))
+ * is_table[i] = is_ratio[i] / (1 + is_ratio[i])
+ */
+static
+mad_fixed_t const is_table[7] = {
+ MAD_F(0x00000000) /* 0.000000000 */,
+ MAD_F(0x0361962f) /* 0.211324865 */,
+ MAD_F(0x05db3d74) /* 0.366025404 */,
+ MAD_F(0x08000000) /* 0.500000000 */,
+ MAD_F(0x0a24c28c) /* 0.633974596 */,
+ MAD_F(0x0c9e69d1) /* 0.788675135 */,
+ MAD_F(0x10000000) /* 1.000000000 */
+};
+
+/*
+ * coefficients for LSF intensity stereo processing
+ * derived from section 2.4.3.2 of ISO/IEC 13818-3
+ *
+ * is_lsf_table[0][i] = (1 / sqrt(sqrt(2)))^(i + 1)
+ * is_lsf_table[1][i] = (1 / sqrt(2))^(i + 1)
+ */
+static
+mad_fixed_t const is_lsf_table[2][15] = {
+ {
+ MAD_F(0x0d744fcd) /* 0.840896415 */,
+ MAD_F(0x0b504f33) /* 0.707106781 */,
+ MAD_F(0x09837f05) /* 0.594603558 */,
+ MAD_F(0x08000000) /* 0.500000000 */,
+ MAD_F(0x06ba27e6) /* 0.420448208 */,
+ MAD_F(0x05a8279a) /* 0.353553391 */,
+ MAD_F(0x04c1bf83) /* 0.297301779 */,
+ MAD_F(0x04000000) /* 0.250000000 */,
+ MAD_F(0x035d13f3) /* 0.210224104 */,
+ MAD_F(0x02d413cd) /* 0.176776695 */,
+ MAD_F(0x0260dfc1) /* 0.148650889 */,
+ MAD_F(0x02000000) /* 0.125000000 */,
+ MAD_F(0x01ae89fa) /* 0.105112052 */,
+ MAD_F(0x016a09e6) /* 0.088388348 */,
+ MAD_F(0x01306fe1) /* 0.074325445 */
+ }, {
+ MAD_F(0x0b504f33) /* 0.707106781 */,
+ MAD_F(0x08000000) /* 0.500000000 */,
+ MAD_F(0x05a8279a) /* 0.353553391 */,
+ MAD_F(0x04000000) /* 0.250000000 */,
+ MAD_F(0x02d413cd) /* 0.176776695 */,
+ MAD_F(0x02000000) /* 0.125000000 */,
+ MAD_F(0x016a09e6) /* 0.088388348 */,
+ MAD_F(0x01000000) /* 0.062500000 */,
+ MAD_F(0x00b504f3) /* 0.044194174 */,
+ MAD_F(0x00800000) /* 0.031250000 */,
+ MAD_F(0x005a827a) /* 0.022097087 */,
+ MAD_F(0x00400000) /* 0.015625000 */,
+ MAD_F(0x002d413d) /* 0.011048543 */,
+ MAD_F(0x00200000) /* 0.007812500 */,
+ MAD_F(0x0016a09e) /* 0.005524272 */
+ }
+};
+
+/*
+ * NAME: III_sideinfo()
+ * DESCRIPTION: decode frame side information from a bitstream
+ */
+static
+enum mad_error III_sideinfo(struct mad_bitptr *ptr, unsigned int nch,
+ int lsf, struct sideinfo *si,
+ unsigned int *data_bitlen,
+ unsigned int *priv_bitlen)
+{
+ unsigned int ngr, gr, ch, i;
+ enum mad_error result = 0;
+
+ *data_bitlen = 0;
+ *priv_bitlen = lsf ? ((nch == 1) ? 1 : 2) : ((nch == 1) ? 5 : 3);
+
+ si->main_data_begin = mad_bit_read(ptr, lsf ? 8 : 9);
+ si->private_bits = mad_bit_read(ptr, *priv_bitlen);
+
+ ngr = 1;
+ if (!lsf) {
+ ngr = 2;
+
+ for (ch = 0; ch < nch; ++ch)
+ si->scfsi[ch] = mad_bit_read(ptr, 4);
+ }
+
+ for (gr = 0; gr < ngr; ++gr) {
+ struct granule *granule = &si->gr[gr];
+
+ for (ch = 0; ch < nch; ++ch) {
+ struct channel *channel = &granule->ch[ch];
+
+ channel->part2_3_length = mad_bit_read(ptr, 12);
+ channel->big_values = mad_bit_read(ptr, 9);
+ channel->global_gain = mad_bit_read(ptr, 8);
+ channel->scalefac_compress = mad_bit_read(ptr, lsf ? 9 : 4);
+
+ *data_bitlen += channel->part2_3_length;
+
+ if (channel->big_values > 288 && result == 0)
+ result = MAD_ERROR_BADBIGVALUES;
+
+ channel->flags = 0;
+
+ /* window_switching_flag */
+ if (mad_bit_read(ptr, 1)) {
+ channel->block_type = mad_bit_read(ptr, 2);
+
+ if (channel->block_type == 0 && result == 0)
+ result = MAD_ERROR_BADBLOCKTYPE;
+
+ if (!lsf && channel->block_type == 2 && si->scfsi[ch] && result == 0)
+ result = MAD_ERROR_BADSCFSI;
+
+ channel->region0_count = 7;
+ channel->region1_count = 36;
+
+ if (mad_bit_read(ptr, 1))
+ channel->flags |= mixed_block_flag;
+ else if (channel->block_type == 2)
+ channel->region0_count = 8;
+
+ for (i = 0; i < 2; ++i)
+ channel->table_select[i] = mad_bit_read(ptr, 5);
+
+# if defined(DEBUG)
+ channel->table_select[2] = 4; /* not used */
+# endif
+
+ for (i = 0; i < 3; ++i)
+ channel->subblock_gain[i] = mad_bit_read(ptr, 3);
+ }
+ else {
+ channel->block_type = 0;
+
+ for (i = 0; i < 3; ++i)
+ channel->table_select[i] = mad_bit_read(ptr, 5);
+
+ channel->region0_count = mad_bit_read(ptr, 4);
+ channel->region1_count = mad_bit_read(ptr, 3);
+ }
+
+ /* [preflag,] scalefac_scale, count1table_select */
+ channel->flags |= mad_bit_read(ptr, lsf ? 2 : 3);
+ }
+ }
+
+ return result;
+}
+
+/*
+ * NAME: III_scalefactors_lsf()
+ * DESCRIPTION: decode channel scalefactors for LSF from a bitstream
+ */
+static
+unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr,
+ struct channel *channel,
+ struct channel *gr1ch, int mode_extension)
+{
+ struct mad_bitptr start;
+ unsigned int scalefac_compress, index, slen[4], part, n, i;
+ unsigned char const *nsfb;
+
+ start = *ptr;
+
+ scalefac_compress = channel->scalefac_compress;
+ index = (channel->block_type == 2) ?
+ ((channel->flags & mixed_block_flag) ? 2 : 1) : 0;
+
+ if (!((mode_extension & 0x1) && gr1ch)) {
+ if (scalefac_compress < 400) {
+ slen[0] = (scalefac_compress >> 4) / 5;
+ slen[1] = (scalefac_compress >> 4) % 5;
+ slen[2] = (scalefac_compress % 16) >> 2;
+ slen[3] = scalefac_compress % 4;
+
+ nsfb = nsfb_table[0][index];
+ }
+ else if (scalefac_compress < 500) {
+ scalefac_compress -= 400;
+
+ slen[0] = (scalefac_compress >> 2) / 5;
+ slen[1] = (scalefac_compress >> 2) % 5;
+ slen[2] = scalefac_compress % 4;
+ slen[3] = 0;
+
+ nsfb = nsfb_table[1][index];
+ }
+ else {
+ scalefac_compress -= 500;
+
+ slen[0] = scalefac_compress / 3;
+ slen[1] = scalefac_compress % 3;
+ slen[2] = 0;
+ slen[3] = 0;
+
+ channel->flags |= preflag;
+
+ nsfb = nsfb_table[2][index];
+ }
+
+ n = 0;
+ for (part = 0; part < 4; ++part) {
+ for (i = 0; i < nsfb[part]; ++i)
+ channel->scalefac[n++] = mad_bit_read(ptr, slen[part]);
+ }
+
+ while (n < 39)
+ channel->scalefac[n++] = 0;
+ }
+ else { /* (mode_extension & 0x1) && gr1ch (i.e. ch == 1) */
+ scalefac_compress >>= 1;
+
+ if (scalefac_compress < 180) {
+ slen[0] = scalefac_compress / 36;
+ slen[1] = (scalefac_compress % 36) / 6;
+ slen[2] = (scalefac_compress % 36) % 6;
+ slen[3] = 0;
+
+ nsfb = nsfb_table[3][index];
+ }
+ else if (scalefac_compress < 244) {
+ scalefac_compress -= 180;
+
+ slen[0] = (scalefac_compress % 64) >> 4;
+ slen[1] = (scalefac_compress % 16) >> 2;
+ slen[2] = scalefac_compress % 4;
+ slen[3] = 0;
+
+ nsfb = nsfb_table[4][index];
+ }
+ else {
+ scalefac_compress -= 244;
+
+ slen[0] = scalefac_compress / 3;
+ slen[1] = scalefac_compress % 3;
+ slen[2] = 0;
+ slen[3] = 0;
+
+ nsfb = nsfb_table[5][index];
+ }
+
+ n = 0;
+ for (part = 0; part < 4; ++part) {
+ unsigned int max, is_pos;
+
+ max = (1 << slen[part]) - 1;
+
+ for (i = 0; i < nsfb[part]; ++i) {
+ is_pos = mad_bit_read(ptr, slen[part]);
+
+ channel->scalefac[n] = is_pos;
+ gr1ch->scalefac[n++] = (is_pos == max);
+ }
+ }
+
+ while (n < 39) {
+ channel->scalefac[n] = 0;
+ gr1ch->scalefac[n++] = 0; /* apparently not illegal */
+ }
+ }
+
+ return mad_bit_length(&start, ptr);
+}
+
+/*
+ * NAME: III_scalefactors()
+ * DESCRIPTION: decode channel scalefactors of one granule from a bitstream
+ */
+static
+unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel,
+ struct channel const *gr0ch, unsigned int scfsi)
+{
+ struct mad_bitptr start;
+ unsigned int slen1, slen2, sfbi;
+
+ start = *ptr;
+
+ slen1 = sflen_table[channel->scalefac_compress].slen1;
+ slen2 = sflen_table[channel->scalefac_compress].slen2;
+
+ if (channel->block_type == 2) {
+ unsigned int nsfb;
+
+ sfbi = 0;
+
+ nsfb = (channel->flags & mixed_block_flag) ? 8 + 3 * 3 : 6 * 3;
+ while (nsfb--)
+ channel->scalefac[sfbi++] = mad_bit_read(ptr, slen1);
+
+ nsfb = 6 * 3;
+ while (nsfb--)
+ channel->scalefac[sfbi++] = mad_bit_read(ptr, slen2);
+
+ nsfb = 1 * 3;
+ while (nsfb--)
+ channel->scalefac[sfbi++] = 0;
+ }
+ else { /* channel->block_type != 2 */
+ if (scfsi & 0x8) {
+ for (sfbi = 0; sfbi < 6; ++sfbi)
+ channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
+ }
+ else {
+ for (sfbi = 0; sfbi < 6; ++sfbi)
+ channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
+ }
+
+ if (scfsi & 0x4) {
+ for (sfbi = 6; sfbi < 11; ++sfbi)
+ channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
+ }
+ else {
+ for (sfbi = 6; sfbi < 11; ++sfbi)
+ channel->scalefac[sfbi] = mad_bit_read(ptr, slen1);
+ }
+
+ if (scfsi & 0x2) {
+ for (sfbi = 11; sfbi < 16; ++sfbi)
+ channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
+ }
+ else {
+ for (sfbi = 11; sfbi < 16; ++sfbi)
+ channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
+ }
+
+ if (scfsi & 0x1) {
+ for (sfbi = 16; sfbi < 21; ++sfbi)
+ channel->scalefac[sfbi] = gr0ch->scalefac[sfbi];
+ }
+ else {
+ for (sfbi = 16; sfbi < 21; ++sfbi)
+ channel->scalefac[sfbi] = mad_bit_read(ptr, slen2);
+ }
+
+ channel->scalefac[21] = 0;
+ }
+
+ return mad_bit_length(&start, ptr);
+}
+
+/*
+ * NAME: III_exponents()
+ * DESCRIPTION: calculate scalefactor exponents
+ */
+static
+void III_exponents(struct channel const *channel,
+ unsigned char const *sfbwidth, signed int exponents[39])
+{
+ signed int gain;
+ unsigned int scalefac_multiplier, sfbi;
+
+ gain = (signed int) channel->global_gain - 210;
+ scalefac_multiplier = (channel->flags & scalefac_scale) ? 2 : 1;
+
+ if (channel->block_type == 2) {
+ unsigned int l;
+ signed int gain0, gain1, gain2;
+
+ sfbi = l = 0;
+
+ if (channel->flags & mixed_block_flag) {
+ unsigned int premask;
+
+ premask = (channel->flags & preflag) ? ~0 : 0;
+
+ /* long block subbands 0-1 */
+
+ while (l < 36) {
+ exponents[sfbi] = gain -
+ (signed int) ((channel->scalefac[sfbi] + (pretab[sfbi] & premask)) <<
+ scalefac_multiplier);
+
+ l += sfbwidth[sfbi++];
+ }
+ }
+
+ /* this is probably wrong for 8000 Hz short/mixed blocks */
+
+ gain0 = gain - 8 * (signed int) channel->subblock_gain[0];
+ gain1 = gain - 8 * (signed int) channel->subblock_gain[1];
+ gain2 = gain - 8 * (signed int) channel->subblock_gain[2];
+
+ while (l < 576) {
+ exponents[sfbi + 0] = gain0 -
+ (signed int) (channel->scalefac[sfbi + 0] << scalefac_multiplier);
+ exponents[sfbi + 1] = gain1 -
+ (signed int) (channel->scalefac[sfbi + 1] << scalefac_multiplier);
+ exponents[sfbi + 2] = gain2 -
+ (signed int) (channel->scalefac[sfbi + 2] << scalefac_multiplier);
+
+ l += 3 * sfbwidth[sfbi];
+ sfbi += 3;
+ }
+ }
+ else { /* channel->block_type != 2 */
+ if (channel->flags & preflag) {
+ for (sfbi = 0; sfbi < 22; ++sfbi) {
+ exponents[sfbi] = gain -
+ (signed int) ((channel->scalefac[sfbi] + pretab[sfbi]) <<
+ scalefac_multiplier);
+ }
+ }
+ else {
+ for (sfbi = 0; sfbi < 22; ++sfbi) {
+ exponents[sfbi] = gain -
+ (signed int) (channel->scalefac[sfbi] << scalefac_multiplier);
+ }
+ }
+ }
+}
+
+/*
+ * NAME: III_requantize()
+ * DESCRIPTION: requantize one (positive) value
+ */
+static
+mad_fixed_t III_requantize(unsigned int value, signed int exp)
+{
+ mad_fixed_t requantized;
+ signed int frac;
+ struct fixedfloat const *power;
+
+ /*
+ * long blocks:
+ * xr[i] = sign(is[i]) * abs(is[i])^(4/3) *
+ * 2^((1/4) * (global_gain - 210)) *
+ * 2^-(scalefac_multiplier *
+ * (scalefac_l[sfb] + preflag * pretab[sfb]))
+ *
+ * short blocks:
+ * xr[i] = sign(is[i]) * abs(is[i])^(4/3) *
+ * 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) *
+ * 2^-(scalefac_multiplier * scalefac_s[sfb][w])
+ *
+ * where:
+ * scalefac_multiplier = (scalefac_scale + 1) / 2
+ */
+
+ frac = exp % 4;
+ exp /= 4;
+
+ power = &rq_table[value];
+ requantized = power->mantissa;
+ exp += power->exponent;
+
+ if (exp < 0) {
+ if (-exp >= sizeof(mad_fixed_t) * CHAR_BIT) {
+ /* underflow */
+ requantized = 0;
+ }
+ else
+ requantized >>= -exp;
+ }
+ else {
+ if (exp >= 5) {
+ /* overflow */
+# if defined(DEBUG)
+ fprintf(stderr, "requantize overflow (%f * 2^%d)\n",
+ mad_f_todouble(requantized), exp);
+# endif
+ requantized = MAD_F_MAX;
+ }
+ else
+ requantized <<= exp;
+ }
+
+ return frac ? mad_f_mul(requantized, root_table[3 + frac]) : requantized;
+}
+
+/* we must take care that sz >= bits and sz < sizeof(long) lest bits == 0 */
+# define MASK(cache, sz, bits) \
+ (((cache) >> ((sz) - (bits))) & ((1 << (bits)) - 1))
+# define MASK1BIT(cache, sz) \
+ ((cache) & (1 << ((sz) - 1)))
+
+/*
+ * NAME: III_huffdecode()
+ * DESCRIPTION: decode Huffman code words of one channel of one granule
+ */
+static
+enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576],
+ struct channel *channel,
+ unsigned char const *sfbwidth,
+ unsigned int part2_length)
+{
+ signed int exponents[39], exp;
+ signed int const *expptr;
+ struct mad_bitptr peek;
+ signed int bits_left, cachesz;
+ register mad_fixed_t *xrptr;
+ mad_fixed_t const *sfbound;
+ register unsigned long bitcache;
+
+ bits_left = (signed) channel->part2_3_length - (signed) part2_length;
+ if (bits_left < 0)
+ return MAD_ERROR_BADPART3LEN;
+
+ III_exponents(channel, sfbwidth, exponents);
+
+ peek = *ptr;
+ mad_bit_skip(ptr, bits_left);
+
+ /* align bit reads to byte boundaries */
+ cachesz = mad_bit_bitsleft(&peek);
+ cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7;
+
+ bitcache = mad_bit_read(&peek, cachesz);
+ bits_left -= cachesz;
+
+ xrptr = &xr[0];
+
+ /* big_values */
+ {
+ unsigned int region, rcount;
+ struct hufftable const *entry;
+ union huffpair const *table;
+ unsigned int linbits, startbits, big_values, reqhits;
+ mad_fixed_t reqcache[16];
+
+ sfbound = xrptr + *sfbwidth++;
+ rcount = channel->region0_count + 1;
+
+ entry = &mad_huff_pair_table[channel->table_select[region = 0]];
+ table = entry->table;
+ linbits = entry->linbits;
+ startbits = entry->startbits;
+
+ if (table == 0)
+ return MAD_ERROR_BADHUFFTABLE;
+
+ expptr = &exponents[0];
+ exp = *expptr++;
+ reqhits = 0;
+
+ big_values = channel->big_values;
+
+ while (big_values-- && cachesz + bits_left > 0) {
+ union huffpair const *pair;
+ unsigned int clumpsz, value;
+ register mad_fixed_t requantized;
+
+ if (xrptr == sfbound) {
+ sfbound += *sfbwidth++;
+
+ /* change table if region boundary */
+
+ if (--rcount == 0) {
+ if (region == 0)
+ rcount = channel->region1_count + 1;
+ else
+ rcount = 0; /* all remaining */
+
+ entry = &mad_huff_pair_table[channel->table_select[++region]];
+ table = entry->table;
+ linbits = entry->linbits;
+ startbits = entry->startbits;
+
+ if (table == 0)
+ return MAD_ERROR_BADHUFFTABLE;
+ }
+
+ if (exp != *expptr) {
+ exp = *expptr;
+ reqhits = 0;
+ }
+
+ ++expptr;
+ }
+
+ if (cachesz < 21) {
+ unsigned int bits;
+
+ bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7;
+ bitcache = (bitcache << bits) | mad_bit_read(&peek, bits);
+ cachesz += bits;
+ bits_left -= bits;
+ }
+
+ /* hcod (0..19) */
+
+ clumpsz = startbits;
+ pair = &table[MASK(bitcache, cachesz, clumpsz)];
+
+ while (!pair->final) {
+ cachesz -= clumpsz;
+
+ clumpsz = pair->ptr.bits;
+ pair = &table[pair->ptr.offset + MASK(bitcache, cachesz, clumpsz)];
+ }
+
+ cachesz -= pair->value.hlen;
+
+ if (linbits) {
+ /* x (0..14) */
+
+ value = pair->value.x;
+
+ switch (value) {
+ case 0:
+ xrptr[0] = 0;
+ break;
+
+ case 15:
+ if (cachesz < linbits + 2) {
+ bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
+ cachesz += 16;
+ bits_left -= 16;
+ }
+
+ value += MASK(bitcache, cachesz, linbits);
+ cachesz -= linbits;
+
+ requantized = III_requantize(value, exp);
+ goto x_final;
+
+ default:
+ if (reqhits & (1 << value))
+ requantized = reqcache[value];
+ else {
+ reqhits |= (1 << value);
+ requantized = reqcache[value] = III_requantize(value, exp);
+ }
+
+ x_final:
+ xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
+ -requantized : requantized;
+ }
+
+ /* y (0..14) */
+
+ value = pair->value.y;
+
+ switch (value) {
+ case 0:
+ xrptr[1] = 0;
+ break;
+
+ case 15:
+ if (cachesz < linbits + 1) {
+ bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
+ cachesz += 16;
+ bits_left -= 16;
+ }
+
+ value += MASK(bitcache, cachesz, linbits);
+ cachesz -= linbits;
+
+ requantized = III_requantize(value, exp);
+ goto y_final;
+
+ default:
+ if (reqhits & (1 << value))
+ requantized = reqcache[value];
+ else {
+ reqhits |= (1 << value);
+ requantized = reqcache[value] = III_requantize(value, exp);
+ }
+
+ y_final:
+ xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
+ -requantized : requantized;
+ }
+ }
+ else {
+ /* x (0..1) */
+
+ value = pair->value.x;
+
+ if (value == 0)
+ xrptr[0] = 0;
+ else {
+ if (reqhits & (1 << value))
+ requantized = reqcache[value];
+ else {
+ reqhits |= (1 << value);
+ requantized = reqcache[value] = III_requantize(value, exp);
+ }
+
+ xrptr[0] = MASK1BIT(bitcache, cachesz--) ?
+ -requantized : requantized;
+ }
+
+ /* y (0..1) */
+
+ value = pair->value.y;
+
+ if (value == 0)
+ xrptr[1] = 0;
+ else {
+ if (reqhits & (1 << value))
+ requantized = reqcache[value];
+ else {
+ reqhits |= (1 << value);
+ requantized = reqcache[value] = III_requantize(value, exp);
+ }
+
+ xrptr[1] = MASK1BIT(bitcache, cachesz--) ?
+ -requantized : requantized;
+ }
+ }
+
+ xrptr += 2;
+ }
+ }
+
+ if (cachesz + bits_left < 0)
+ return MAD_ERROR_BADHUFFDATA; /* big_values overrun */
+
+ /* count1 */
+ {
+ union huffquad const *table;
+ register mad_fixed_t requantized;
+
+ table = mad_huff_quad_table[channel->flags & count1table_select];
+
+ requantized = III_requantize(1, exp);
+
+ while (cachesz + bits_left > 0 && xrptr <= &xr[572]) {
+ union huffquad const *quad;
+
+ /* hcod (1..6) */
+
+ if (cachesz < 10) {
+ bitcache = (bitcache << 16) | mad_bit_read(&peek, 16);
+ cachesz += 16;
+ bits_left -= 16;
+ }
+
+ quad = &table[MASK(bitcache, cachesz, 4)];
+
+ /* quad tables guaranteed to have at most one extra lookup */
+ if (!quad->final) {
+ cachesz -= 4;
+
+ quad = &table[quad->ptr.offset +
+ MASK(bitcache, cachesz, quad->ptr.bits)];
+ }
+
+ cachesz -= quad->value.hlen;
+
+ if (xrptr == sfbound) {
+ sfbound += *sfbwidth++;
+
+ if (exp != *expptr) {
+ exp = *expptr;
+ requantized = III_requantize(1, exp);
+ }
+
+ ++expptr;
+ }
+
+ /* v (0..1) */
+
+ xrptr[0] = quad->value.v ?
+ (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
+
+ /* w (0..1) */
+
+ xrptr[1] = quad->value.w ?
+ (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
+
+ xrptr += 2;
+
+ if (xrptr == sfbound) {
+ sfbound += *sfbwidth++;
+
+ if (exp != *expptr) {
+ exp = *expptr;
+ requantized = III_requantize(1, exp);
+ }
+
+ ++expptr;
+ }
+
+ /* x (0..1) */
+
+ xrptr[0] = quad->value.x ?
+ (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
+
+ /* y (0..1) */
+
+ xrptr[1] = quad->value.y ?
+ (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0;
+
+ xrptr += 2;
+ }
+
+ if (cachesz + bits_left < 0) {
+# if 0 && defined(DEBUG)
+ fprintf(stderr, "huffman count1 overrun (%d bits)\n",
+ -(cachesz + bits_left));
+# endif
+
+ /* technically the bitstream is misformatted, but apparently
+ some encoders are just a bit sloppy with stuffing bits */
+
+ xrptr -= 4;
+ }
+ }
+
+ assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT);
+
+# if 0 && defined(DEBUG)
+ if (bits_left < 0)
+ fprintf(stderr, "read %d bits too many\n", -bits_left);
+ else if (cachesz + bits_left > 0)
+ fprintf(stderr, "%d stuffing bits\n", cachesz + bits_left);
+# endif
+
+ /* rzero */
+ while (xrptr < &xr[576]) {
+ xrptr[0] = 0;
+ xrptr[1] = 0;
+
+ xrptr += 2;
+ }
+
+ return 0;
+}
+
+# undef MASK
+# undef MASK1BIT
+
+/*
+ * NAME: III_reorder()
+ * DESCRIPTION: reorder frequency lines of a short block into subband order
+ */
+static
+void III_reorder(mad_fixed_t xr[576], struct channel const *channel,
+ unsigned char const sfbwidth[39])
+{
+ mad_fixed_t tmp[32][3][6];
+ unsigned int sb, l, sfbi, f, w, sbw[3], sw[3];
+
+ /* this is probably wrong for 8000 Hz mixed blocks */
+
+ if (channel->flags & mixed_block_flag)
+ sb = 2, sfbi = 3 * 3;
+ else
+ sb = 0, sfbi = 0;
+
+ for (w = 0; w < 3; ++w) {
+ sbw[w] = sb;
+ sw[w] = 0;
+ }
+
+ f = sfbwidth[sfbi];
+ w = 0;
+
+ for (l = 18 * sb; l < 576; ++l) {
+ tmp[sbw[w]][w][sw[w]++] = xr[l];
+
+ if (sw[w] == 6) {
+ sw[w] = 0;
+ ++sbw[w];
+ }
+
+ if (--f == 0) {
+ if (++w == 3)
+ w = 0;
+
+ f = sfbwidth[++sfbi];
+ }
+ }
+
+ memcpy(&xr[18 * sb], &tmp[sb], (576 - 18 * sb) * sizeof(mad_fixed_t));
+}
+
+/*
+ * NAME: III_stereo()
+ * DESCRIPTION: perform joint stereo processing on a granule
+ */
+static
+enum mad_error III_stereo(mad_fixed_t xr[2][576],
+ struct granule const *granule,
+ struct mad_header *header,
+ unsigned char const *sfbwidth)
+{
+ short modes[39];
+ unsigned int sfbi, l, n, i;
+
+ enum {
+ i_stereo = 0x1,
+ ms_stereo = 0x2
+ };
+
+ if (granule->ch[0].block_type !=
+ granule->ch[1].block_type ||
+ (granule->ch[0].flags & mixed_block_flag) !=
+ (granule->ch[1].flags & mixed_block_flag))
+ return MAD_ERROR_BADSTEREO;
+
+ for (i = 0; i < 39; ++i)
+ modes[i] = header->mode_extension;
+
+ /* intensity stereo */
+
+ if (header->mode_extension & i_stereo) {
+ struct channel const *right_ch = &granule->ch[1];
+ mad_fixed_t const *right_xr = xr[1];
+ unsigned int is_pos;
+
+ header->flags |= MAD_FLAG_I_STEREO;
+
+ /* first determine which scalefactor bands are to be processed */
+
+ if (right_ch->block_type == 2) {
+ unsigned int lower, start, max, bound[3], w;
+
+ lower = start = max = bound[0] = bound[1] = bound[2] = 0;
+
+ sfbi = l = 0;
+
+ if (right_ch->flags & mixed_block_flag) {
+ while (l < 36) {
+ n = sfbwidth[sfbi++];
+
+ for (i = 0; i < n; ++i) {
+ if (right_xr[i]) {
+ lower = sfbi;
+ break;
+ }
+ }
+
+ right_xr += n;
+ l += n;
+ }
+
+ start = sfbi;
+ }
+
+ w = 0;
+ while (l < 576) {
+ n = sfbwidth[sfbi++];
+
+ for (i = 0; i < n; ++i) {
+ if (right_xr[i]) {
+ max = bound[w] = sfbi;
+ break;
+ }
+ }
+
+ right_xr += n;
+ l += n;
+ w = (w + 1) % 3;
+ }
+
+ if (max)
+ lower = start;
+
+ /* long blocks */
+
+ for (i = 0; i < lower; ++i)
+ modes[i] = header->mode_extension & ~i_stereo;
+
+ /* short blocks */
+
+ w = 0;
+ for (i = start; i < max; ++i) {
+ if (i < bound[w])
+ modes[i] = header->mode_extension & ~i_stereo;
+
+ w = (w + 1) % 3;
+ }
+ }
+ else { /* right_ch->block_type != 2 */
+ unsigned int bound;
+
+ bound = 0;
+ for (sfbi = l = 0; l < 576; l += n) {
+ n = sfbwidth[sfbi++];
+
+ for (i = 0; i < n; ++i) {
+ if (right_xr[i]) {
+ bound = sfbi;
+ break;
+ }
+ }
+
+ right_xr += n;
+ }
+
+ for (i = 0; i < bound; ++i)
+ modes[i] = header->mode_extension & ~i_stereo;
+ }
+
+ /* now do the actual processing */
+
+ if (header->flags & MAD_FLAG_LSF_EXT) {
+ unsigned char const *illegal_pos = granule[1].ch[1].scalefac;
+ mad_fixed_t const *lsf_scale;
+
+ /* intensity_scale */
+ lsf_scale = is_lsf_table[right_ch->scalefac_compress & 0x1];
+
+ for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
+ n = sfbwidth[sfbi];
+
+ if (!(modes[sfbi] & i_stereo))
+ continue;
+
+ if (illegal_pos[sfbi]) {
+ modes[sfbi] &= ~i_stereo;
+ continue;
+ }
+
+ is_pos = right_ch->scalefac[sfbi];
+
+ for (i = 0; i < n; ++i) {
+ register mad_fixed_t left;
+
+ left = xr[0][l + i];
+
+ if (is_pos == 0)
+ xr[1][l + i] = left;
+ else {
+ register mad_fixed_t opposite;
+
+ opposite = mad_f_mul(left, lsf_scale[(is_pos - 1) / 2]);
+
+ if (is_pos & 1) {
+ xr[0][l + i] = opposite;
+ xr[1][l + i] = left;
+ }
+ else
+ xr[1][l + i] = opposite;
+ }
+ }
+ }
+ }
+ else { /* !(header->flags & MAD_FLAG_LSF_EXT) */
+ for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
+ n = sfbwidth[sfbi];
+
+ if (!(modes[sfbi] & i_stereo))
+ continue;
+
+ is_pos = right_ch->scalefac[sfbi];
+
+ if (is_pos >= 7) { /* illegal intensity position */
+ modes[sfbi] &= ~i_stereo;
+ continue;
+ }
+
+ for (i = 0; i < n; ++i) {
+ register mad_fixed_t left;
+
+ left = xr[0][l + i];
+
+ xr[0][l + i] = mad_f_mul(left, is_table[ is_pos]);
+ xr[1][l + i] = mad_f_mul(left, is_table[6 - is_pos]);
+ }
+ }
+ }
+ }
+
+ /* middle/side stereo */
+
+ if (header->mode_extension & ms_stereo) {
+ register mad_fixed_t invsqrt2;
+
+ header->flags |= MAD_FLAG_MS_STEREO;
+
+ invsqrt2 = root_table[3 + -2];
+
+ for (sfbi = l = 0; l < 576; ++sfbi, l += n) {
+ n = sfbwidth[sfbi];
+
+ if (modes[sfbi] != ms_stereo)
+ continue;
+
+ for (i = 0; i < n; ++i) {
+ register mad_fixed_t m, s;
+
+ m = xr[0][l + i];
+ s = xr[1][l + i];
+
+ xr[0][l + i] = mad_f_mul(m + s, invsqrt2); /* l = (m + s) / sqrt(2) */
+ xr[1][l + i] = mad_f_mul(m - s, invsqrt2); /* r = (m - s) / sqrt(2) */
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * NAME: III_aliasreduce()
+ * DESCRIPTION: perform frequency line alias reduction
+ */
+static
+void III_aliasreduce(mad_fixed_t xr[576], int lines)
+{
+ mad_fixed_t const *bound;
+ int i;
+
+ bound = &xr[lines];
+ for (xr += 18; xr < bound; xr += 18) {
+ for (i = 0; i < 8; ++i) {
+ register mad_fixed_t *aptr, *bptr, a, b;
+ register mad_fixed64hi_t hi;
+ register mad_fixed64lo_t lo;
+
+ aptr = &xr[-1 - i];
+ bptr = &xr[ i];
+
+ a = *aptr;
+ b = *bptr;
+
+# if defined(ASO_ZEROCHECK)
+ if (a | b) {
+# endif
+ MAD_F_ML0(hi, lo, a, cs[i]);
+ MAD_F_MLA(hi, lo, -b, ca[i]);
+
+ *aptr = MAD_F_MLZ(hi, lo);
+
+ MAD_F_ML0(hi, lo, b, cs[i]);
+ MAD_F_MLA(hi, lo, a, ca[i]);
+
+ *bptr = MAD_F_MLZ(hi, lo);
+# if defined(ASO_ZEROCHECK)
+ }
+# endif
+ }
+ }
+}
+
+# if defined(ASO_IMDCT)
+void III_imdct_l(mad_fixed_t const [18], mad_fixed_t [36], unsigned int);
+# else
+/*
+ * NAME: imdct36
+ * DESCRIPTION: perform X[18]->x[36] IMDCT
+ */
+static inline
+void imdct36(mad_fixed_t const X[18], mad_fixed_t x[36])
+{
+ mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7;
+ mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15;
+ register mad_fixed64hi_t hi;
+ register mad_fixed64lo_t lo;
+
+ MAD_F_ML0(hi, lo, X[4], MAD_F(0x0ec835e8));
+ MAD_F_MLA(hi, lo, X[13], MAD_F(0x061f78aa));
+
+ t6 = MAD_F_MLZ(hi, lo);
+
+ MAD_F_MLA(hi, lo, (t14 = X[1] - X[10]), -MAD_F(0x061f78aa));
+ MAD_F_MLA(hi, lo, (t15 = X[7] + X[16]), -MAD_F(0x0ec835e8));
+
+ t0 = MAD_F_MLZ(hi, lo);
+
+ MAD_F_MLA(hi, lo, (t8 = X[0] - X[11] - X[12]), MAD_F(0x0216a2a2));
+ MAD_F_MLA(hi, lo, (t9 = X[2] - X[9] - X[14]), MAD_F(0x09bd7ca0));
+ MAD_F_MLA(hi, lo, (t10 = X[3] - X[8] - X[15]), -MAD_F(0x0cb19346));
+ MAD_F_MLA(hi, lo, (t11 = X[5] - X[6] - X[17]), -MAD_F(0x0fdcf549));
+
+ x[7] = MAD_F_MLZ(hi, lo);
+ x[10] = -x[7];
+
+ MAD_F_ML0(hi, lo, t8, -MAD_F(0x0cb19346));
+ MAD_F_MLA(hi, lo, t9, MAD_F(0x0fdcf549));
+ MAD_F_MLA(hi, lo, t10, MAD_F(0x0216a2a2));
+ MAD_F_MLA(hi, lo, t11, -MAD_F(0x09bd7ca0));
+
+ x[19] = x[34] = MAD_F_MLZ(hi, lo) - t0;
+
+ t12 = X[0] - X[3] + X[8] - X[11] - X[12] + X[15];
+ t13 = X[2] + X[5] - X[6] - X[9] - X[14] - X[17];
+
+ MAD_F_ML0(hi, lo, t12, -MAD_F(0x0ec835e8));
+ MAD_F_MLA(hi, lo, t13, MAD_F(0x061f78aa));
+
+ x[22] = x[31] = MAD_F_MLZ(hi, lo) + t0;
+
+ MAD_F_ML0(hi, lo, X[1], -MAD_F(0x09bd7ca0));
+ MAD_F_MLA(hi, lo, X[7], MAD_F(0x0216a2a2));
+ MAD_F_MLA(hi, lo, X[10], -MAD_F(0x0fdcf549));
+ MAD_F_MLA(hi, lo, X[16], MAD_F(0x0cb19346));
+
+ t1 = MAD_F_MLZ(hi, lo) + t6;
+
+ MAD_F_ML0(hi, lo, X[0], MAD_F(0x03768962));
+ MAD_F_MLA(hi, lo, X[2], MAD_F(0x0e313245));
+ MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0ffc19fd));
+ MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0acf37ad));
+ MAD_F_MLA(hi, lo, X[6], MAD_F(0x04cfb0e2));
+ MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0898c779));
+ MAD_F_MLA(hi, lo, X[9], MAD_F(0x0d7e8807));
+ MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f426cb5));
+ MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0bcbe352));
+ MAD_F_MLA(hi, lo, X[14], MAD_F(0x00b2aa3e));
+ MAD_F_MLA(hi, lo, X[15], -MAD_F(0x07635284));
+ MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0f9ee890));
+
+ x[6] = MAD_F_MLZ(hi, lo) + t1;
+ x[11] = -x[6];
+
+ MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f426cb5));
+ MAD_F_MLA(hi, lo, X[2], -MAD_F(0x00b2aa3e));
+ MAD_F_MLA(hi, lo, X[3], MAD_F(0x0898c779));
+ MAD_F_MLA(hi, lo, X[5], MAD_F(0x0f9ee890));
+ MAD_F_MLA(hi, lo, X[6], MAD_F(0x0acf37ad));
+ MAD_F_MLA(hi, lo, X[8], -MAD_F(0x07635284));
+ MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0e313245));
+ MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0bcbe352));
+ MAD_F_MLA(hi, lo, X[12], -MAD_F(0x03768962));
+ MAD_F_MLA(hi, lo, X[14], MAD_F(0x0d7e8807));
+ MAD_F_MLA(hi, lo, X[15], MAD_F(0x0ffc19fd));
+ MAD_F_MLA(hi, lo, X[17], MAD_F(0x04cfb0e2));
+
+ x[23] = x[30] = MAD_F_MLZ(hi, lo) + t1;
+
+ MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0bcbe352));
+ MAD_F_MLA(hi, lo, X[2], MAD_F(0x0d7e8807));
+ MAD_F_MLA(hi, lo, X[3], -MAD_F(0x07635284));
+ MAD_F_MLA(hi, lo, X[5], MAD_F(0x04cfb0e2));
+ MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f9ee890));
+ MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0ffc19fd));
+ MAD_F_MLA(hi, lo, X[9], -MAD_F(0x00b2aa3e));
+ MAD_F_MLA(hi, lo, X[11], MAD_F(0x03768962));
+ MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0f426cb5));
+ MAD_F_MLA(hi, lo, X[14], MAD_F(0x0e313245));
+ MAD_F_MLA(hi, lo, X[15], MAD_F(0x0898c779));
+ MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0acf37ad));
+
+ x[18] = x[35] = MAD_F_MLZ(hi, lo) - t1;
+
+ MAD_F_ML0(hi, lo, X[4], MAD_F(0x061f78aa));
+ MAD_F_MLA(hi, lo, X[13], -MAD_F(0x0ec835e8));
+
+ t7 = MAD_F_MLZ(hi, lo);
+
+ MAD_F_MLA(hi, lo, X[1], -MAD_F(0x0cb19346));
+ MAD_F_MLA(hi, lo, X[7], MAD_F(0x0fdcf549));
+ MAD_F_MLA(hi, lo, X[10], MAD_F(0x0216a2a2));
+ MAD_F_MLA(hi, lo, X[16], -MAD_F(0x09bd7ca0));
+
+ t2 = MAD_F_MLZ(hi, lo);
+
+ MAD_F_MLA(hi, lo, X[0], MAD_F(0x04cfb0e2));
+ MAD_F_MLA(hi, lo, X[2], MAD_F(0x0ffc19fd));
+ MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0d7e8807));
+ MAD_F_MLA(hi, lo, X[5], MAD_F(0x03768962));
+ MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0bcbe352));
+ MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0e313245));
+ MAD_F_MLA(hi, lo, X[9], MAD_F(0x07635284));
+ MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0acf37ad));
+ MAD_F_MLA(hi, lo, X[12], MAD_F(0x0f9ee890));
+ MAD_F_MLA(hi, lo, X[14], MAD_F(0x0898c779));
+ MAD_F_MLA(hi, lo, X[15], MAD_F(0x00b2aa3e));
+ MAD_F_MLA(hi, lo, X[17], MAD_F(0x0f426cb5));
+
+ x[5] = MAD_F_MLZ(hi, lo);
+ x[12] = -x[5];
+
+ MAD_F_ML0(hi, lo, X[0], MAD_F(0x0acf37ad));
+ MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0898c779));
+ MAD_F_MLA(hi, lo, X[3], MAD_F(0x0e313245));
+ MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0f426cb5));
+ MAD_F_MLA(hi, lo, X[6], -MAD_F(0x03768962));
+ MAD_F_MLA(hi, lo, X[8], MAD_F(0x00b2aa3e));
+ MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0ffc19fd));
+ MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f9ee890));
+ MAD_F_MLA(hi, lo, X[12], -MAD_F(0x04cfb0e2));
+ MAD_F_MLA(hi, lo, X[14], MAD_F(0x07635284));
+ MAD_F_MLA(hi, lo, X[15], MAD_F(0x0d7e8807));
+ MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0bcbe352));
+
+ x[0] = MAD_F_MLZ(hi, lo) + t2;
+ x[17] = -x[0];
+
+ MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f9ee890));
+ MAD_F_MLA(hi, lo, X[2], -MAD_F(0x07635284));
+ MAD_F_MLA(hi, lo, X[3], -MAD_F(0x00b2aa3e));
+ MAD_F_MLA(hi, lo, X[5], MAD_F(0x0bcbe352));
+ MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f426cb5));
+ MAD_F_MLA(hi, lo, X[8], MAD_F(0x0d7e8807));
+ MAD_F_MLA(hi, lo, X[9], MAD_F(0x0898c779));
+ MAD_F_MLA(hi, lo, X[11], -MAD_F(0x04cfb0e2));
+ MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0acf37ad));
+ MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0ffc19fd));
+ MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0e313245));
+ MAD_F_MLA(hi, lo, X[17], -MAD_F(0x03768962));
+
+ x[24] = x[29] = MAD_F_MLZ(hi, lo) + t2;
+
+ MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0216a2a2));
+ MAD_F_MLA(hi, lo, X[7], -MAD_F(0x09bd7ca0));
+ MAD_F_MLA(hi, lo, X[10], MAD_F(0x0cb19346));
+ MAD_F_MLA(hi, lo, X[16], MAD_F(0x0fdcf549));
+
+ t3 = MAD_F_MLZ(hi, lo) + t7;
+
+ MAD_F_ML0(hi, lo, X[0], MAD_F(0x00b2aa3e));
+ MAD_F_MLA(hi, lo, X[2], MAD_F(0x03768962));
+ MAD_F_MLA(hi, lo, X[3], -MAD_F(0x04cfb0e2));
+ MAD_F_MLA(hi, lo, X[5], -MAD_F(0x07635284));
+ MAD_F_MLA(hi, lo, X[6], MAD_F(0x0898c779));
+ MAD_F_MLA(hi, lo, X[8], MAD_F(0x0acf37ad));
+ MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0bcbe352));
+ MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0d7e8807));
+ MAD_F_MLA(hi, lo, X[12], MAD_F(0x0e313245));
+ MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f426cb5));
+ MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0f9ee890));
+ MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0ffc19fd));
+
+ x[8] = MAD_F_MLZ(hi, lo) + t3;
+ x[9] = -x[8];
+
+ MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0e313245));
+ MAD_F_MLA(hi, lo, X[2], MAD_F(0x0bcbe352));
+ MAD_F_MLA(hi, lo, X[3], MAD_F(0x0f9ee890));
+ MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0898c779));
+ MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0ffc19fd));
+ MAD_F_MLA(hi, lo, X[8], MAD_F(0x04cfb0e2));
+ MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f426cb5));
+ MAD_F_MLA(hi, lo, X[11], -MAD_F(0x00b2aa3e));
+ MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0d7e8807));
+ MAD_F_MLA(hi, lo, X[14], -MAD_F(0x03768962));
+ MAD_F_MLA(hi, lo, X[15], MAD_F(0x0acf37ad));
+ MAD_F_MLA(hi, lo, X[17], MAD_F(0x07635284));
+
+ x[21] = x[32] = MAD_F_MLZ(hi, lo) + t3;
+
+ MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0d7e8807));
+ MAD_F_MLA(hi, lo, X[2], MAD_F(0x0f426cb5));
+ MAD_F_MLA(hi, lo, X[3], MAD_F(0x0acf37ad));
+ MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0ffc19fd));
+ MAD_F_MLA(hi, lo, X[6], -MAD_F(0x07635284));
+ MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f9ee890));
+ MAD_F_MLA(hi, lo, X[9], MAD_F(0x03768962));
+ MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0e313245));
+ MAD_F_MLA(hi, lo, X[12], MAD_F(0x00b2aa3e));
+ MAD_F_MLA(hi, lo, X[14], MAD_F(0x0bcbe352));
+ MAD_F_MLA(hi, lo, X[15], -MAD_F(0x04cfb0e2));
+ MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0898c779));
+
+ x[20] = x[33] = MAD_F_MLZ(hi, lo) - t3;
+
+ MAD_F_ML0(hi, lo, t14, -MAD_F(0x0ec835e8));
+ MAD_F_MLA(hi, lo, t15, MAD_F(0x061f78aa));
+
+ t4 = MAD_F_MLZ(hi, lo) - t7;
+
+ MAD_F_ML0(hi, lo, t12, MAD_F(0x061f78aa));
+ MAD_F_MLA(hi, lo, t13, MAD_F(0x0ec835e8));
+
+ x[4] = MAD_F_MLZ(hi, lo) + t4;
+ x[13] = -x[4];
+
+ MAD_F_ML0(hi, lo, t8, MAD_F(0x09bd7ca0));
+ MAD_F_MLA(hi, lo, t9, -MAD_F(0x0216a2a2));
+ MAD_F_MLA(hi, lo, t10, MAD_F(0x0fdcf549));
+ MAD_F_MLA(hi, lo, t11, -MAD_F(0x0cb19346));
+
+ x[1] = MAD_F_MLZ(hi, lo) + t4;
+ x[16] = -x[1];
+
+ MAD_F_ML0(hi, lo, t8, -MAD_F(0x0fdcf549));
+ MAD_F_MLA(hi, lo, t9, -MAD_F(0x0cb19346));
+ MAD_F_MLA(hi, lo, t10, -MAD_F(0x09bd7ca0));
+ MAD_F_MLA(hi, lo, t11, -MAD_F(0x0216a2a2));
+
+ x[25] = x[28] = MAD_F_MLZ(hi, lo) + t4;
+
+ MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0fdcf549));
+ MAD_F_MLA(hi, lo, X[7], -MAD_F(0x0cb19346));
+ MAD_F_MLA(hi, lo, X[10], -MAD_F(0x09bd7ca0));
+ MAD_F_MLA(hi, lo, X[16], -MAD_F(0x0216a2a2));
+
+ t5 = MAD_F_MLZ(hi, lo) - t6;
+
+ MAD_F_ML0(hi, lo, X[0], MAD_F(0x0898c779));
+ MAD_F_MLA(hi, lo, X[2], MAD_F(0x04cfb0e2));
+ MAD_F_MLA(hi, lo, X[3], MAD_F(0x0bcbe352));
+ MAD_F_MLA(hi, lo, X[5], MAD_F(0x00b2aa3e));
+ MAD_F_MLA(hi, lo, X[6], MAD_F(0x0e313245));
+ MAD_F_MLA(hi, lo, X[8], -MAD_F(0x03768962));
+ MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f9ee890));
+ MAD_F_MLA(hi, lo, X[11], -MAD_F(0x07635284));
+ MAD_F_MLA(hi, lo, X[12], MAD_F(0x0ffc19fd));
+ MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0acf37ad));
+ MAD_F_MLA(hi, lo, X[15], MAD_F(0x0f426cb5));
+ MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0d7e8807));
+
+ x[2] = MAD_F_MLZ(hi, lo) + t5;
+ x[15] = -x[2];
+
+ MAD_F_ML0(hi, lo, X[0], MAD_F(0x07635284));
+ MAD_F_MLA(hi, lo, X[2], MAD_F(0x0acf37ad));
+ MAD_F_MLA(hi, lo, X[3], MAD_F(0x03768962));
+ MAD_F_MLA(hi, lo, X[5], MAD_F(0x0d7e8807));
+ MAD_F_MLA(hi, lo, X[6], -MAD_F(0x00b2aa3e));
+ MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f426cb5));
+ MAD_F_MLA(hi, lo, X[9], -MAD_F(0x04cfb0e2));
+ MAD_F_MLA(hi, lo, X[11], MAD_F(0x0ffc19fd));
+ MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0898c779));
+ MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f9ee890));
+ MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0bcbe352));
+ MAD_F_MLA(hi, lo, X[17], MAD_F(0x0e313245));
+
+ x[3] = MAD_F_MLZ(hi, lo) + t5;
+ x[14] = -x[3];
+
+ MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0ffc19fd));
+ MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0f9ee890));
+ MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0f426cb5));
+ MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0e313245));
+ MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0d7e8807));
+ MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0bcbe352));
+ MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0acf37ad));
+ MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0898c779));
+ MAD_F_MLA(hi, lo, X[12], -MAD_F(0x07635284));
+ MAD_F_MLA(hi, lo, X[14], -MAD_F(0x04cfb0e2));
+ MAD_F_MLA(hi, lo, X[15], -MAD_F(0x03768962));
+ MAD_F_MLA(hi, lo, X[17], -MAD_F(0x00b2aa3e));
+
+ x[26] = x[27] = MAD_F_MLZ(hi, lo) + t5;
+}
+
+/*
+ * NAME: III_imdct_l()
+ * DESCRIPTION: perform IMDCT and windowing for long blocks
+ */
+static
+void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36],
+ unsigned int block_type)
+{
+ unsigned int i;
+
+ /* IMDCT */
+
+ imdct36(X, z);
+
+ /* windowing */
+
+ switch (block_type) {
+ case 0: /* normal window */
+# if defined(ASO_INTERLEAVE1)
+ {
+ register mad_fixed_t tmp1, tmp2;
+
+ tmp1 = window_l[0];
+ tmp2 = window_l[1];
+
+ for (i = 0; i < 34; i += 2) {
+ z[i + 0] = mad_f_mul(z[i + 0], tmp1);
+ tmp1 = window_l[i + 2];
+ z[i + 1] = mad_f_mul(z[i + 1], tmp2);
+ tmp2 = window_l[i + 3];
+ }
+
+ z[34] = mad_f_mul(z[34], tmp1);
+ z[35] = mad_f_mul(z[35], tmp2);
+ }
+# elif defined(ASO_INTERLEAVE2)
+ {
+ register mad_fixed_t tmp1, tmp2;
+
+ tmp1 = z[0];
+ tmp2 = window_l[0];
+
+ for (i = 0; i < 35; ++i) {
+ z[i] = mad_f_mul(tmp1, tmp2);
+ tmp1 = z[i + 1];
+ tmp2 = window_l[i + 1];
+ }
+
+ z[35] = mad_f_mul(tmp1, tmp2);
+ }
+# elif 1
+ for (i = 0; i < 36; i += 4) {
+ z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
+ z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
+ z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
+ z[i + 3] = mad_f_mul(z[i + 3], window_l[i + 3]);
+ }
+# else
+ for (i = 0; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]);
+# endif
+ break;
+
+ case 1: /* start block */
+ for (i = 0; i < 18; ++i) z[i] = mad_f_mul(z[i], window_l[i]);
+ /* (i = 18; i < 24; ++i) z[i] unchanged */
+ for (i = 24; i < 30; ++i) z[i] = mad_f_mul(z[i], window_s[i - 18]);
+ for (i = 30; i < 36; ++i) z[i] = 0;
+ break;
+
+ case 3: /* stop block */
+ for (i = 0; i < 6; ++i) z[i] = 0;
+ for (i = 6; i < 12; ++i) z[i] = mad_f_mul(z[i], window_s[i - 6]);
+ /* (i = 12; i < 18; ++i) z[i] unchanged */
+ for (i = 18; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]);
+ break;
+ }
+}
+# endif /* ASO_IMDCT */
+
+/*
+ * NAME: III_imdct_s()
+ * DESCRIPTION: perform IMDCT and windowing for short blocks
+ */
+static
+void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36])
+{
+ mad_fixed_t y[36], *yptr;
+ mad_fixed_t const *wptr;
+ int w, i;
+ register mad_fixed64hi_t hi;
+ register mad_fixed64lo_t lo;
+
+ /* IMDCT */
+
+ yptr = &y[0];
+
+ for (w = 0; w < 3; ++w) {
+ register mad_fixed_t const (*s)[6];
+
+ s = imdct_s;
+
+ for (i = 0; i < 3; ++i) {
+ MAD_F_ML0(hi, lo, X[0], (*s)[0]);
+ MAD_F_MLA(hi, lo, X[1], (*s)[1]);
+ MAD_F_MLA(hi, lo, X[2], (*s)[2]);
+ MAD_F_MLA(hi, lo, X[3], (*s)[3]);
+ MAD_F_MLA(hi, lo, X[4], (*s)[4]);
+ MAD_F_MLA(hi, lo, X[5], (*s)[5]);
+
+ yptr[i + 0] = MAD_F_MLZ(hi, lo);
+ yptr[5 - i] = -yptr[i + 0];
+
+ ++s;
+
+ MAD_F_ML0(hi, lo, X[0], (*s)[0]);
+ MAD_F_MLA(hi, lo, X[1], (*s)[1]);
+ MAD_F_MLA(hi, lo, X[2], (*s)[2]);
+ MAD_F_MLA(hi, lo, X[3], (*s)[3]);
+ MAD_F_MLA(hi, lo, X[4], (*s)[4]);
+ MAD_F_MLA(hi, lo, X[5], (*s)[5]);
+
+ yptr[ i + 6] = MAD_F_MLZ(hi, lo);
+ yptr[11 - i] = yptr[i + 6];
+
+ ++s;
+ }
+
+ yptr += 12;
+ X += 6;
+ }
+
+ /* windowing, overlapping and concatenation */
+
+ yptr = &y[0];
+ wptr = &window_s[0];
+
+ for (i = 0; i < 6; ++i) {
+ z[i + 0] = 0;
+ z[i + 6] = mad_f_mul(yptr[ 0 + 0], wptr[0]);
+
+ MAD_F_ML0(hi, lo, yptr[ 0 + 6], wptr[6]);
+ MAD_F_MLA(hi, lo, yptr[12 + 0], wptr[0]);
+
+ z[i + 12] = MAD_F_MLZ(hi, lo);
+
+ MAD_F_ML0(hi, lo, yptr[12 + 6], wptr[6]);
+ MAD_F_MLA(hi, lo, yptr[24 + 0], wptr[0]);
+
+ z[i + 18] = MAD_F_MLZ(hi, lo);
+
+ z[i + 24] = mad_f_mul(yptr[24 + 6], wptr[6]);
+ z[i + 30] = 0;
+
+ ++yptr;
+ ++wptr;
+ }
+}
+
+/*
+ * NAME: III_overlap()
+ * DESCRIPTION: perform overlap-add of windowed IMDCT outputs
+ */
+static
+void III_overlap(mad_fixed_t const output[36], mad_fixed_t overlap[18],
+ mad_fixed_t sample[18][32], unsigned int sb)
+{
+ unsigned int i;
+
+# if defined(ASO_INTERLEAVE2)
+ {
+ register mad_fixed_t tmp1, tmp2;
+
+ tmp1 = overlap[0];
+ tmp2 = overlap[1];
+
+ for (i = 0; i < 16; i += 2) {
+ sample[i + 0][sb] = output[i + 0] + tmp1;
+ overlap[i + 0] = output[i + 0 + 18];
+ tmp1 = overlap[i + 2];
+
+ sample[i + 1][sb] = output[i + 1] + tmp2;
+ overlap[i + 1] = output[i + 1 + 18];
+ tmp2 = overlap[i + 3];
+ }
+
+ sample[16][sb] = output[16] + tmp1;
+ overlap[16] = output[16 + 18];
+ sample[17][sb] = output[17] + tmp2;
+ overlap[17] = output[17 + 18];
+ }
+# elif 0
+ for (i = 0; i < 18; i += 2) {
+ sample[i + 0][sb] = output[i + 0] + overlap[i + 0];
+ overlap[i + 0] = output[i + 0 + 18];
+
+ sample[i + 1][sb] = output[i + 1] + overlap[i + 1];
+ overlap[i + 1] = output[i + 1 + 18];
+ }
+# else
+ for (i = 0; i < 18; ++i) {
+ sample[i][sb] = output[i] + overlap[i];
+ overlap[i] = output[i + 18];
+ }
+# endif
+}
+
+/*
+ * NAME: III_overlap_z()
+ * DESCRIPTION: perform "overlap-add" of zero IMDCT outputs
+ */
+static inline
+void III_overlap_z(mad_fixed_t overlap[18],
+ mad_fixed_t sample[18][32], unsigned int sb)
+{
+ unsigned int i;
+
+# if defined(ASO_INTERLEAVE2)
+ {
+ register mad_fixed_t tmp1, tmp2;
+
+ tmp1 = overlap[0];
+ tmp2 = overlap[1];
+
+ for (i = 0; i < 16; i += 2) {
+ sample[i + 0][sb] = tmp1;
+ overlap[i + 0] = 0;
+ tmp1 = overlap[i + 2];
+
+ sample[i + 1][sb] = tmp2;
+ overlap[i + 1] = 0;
+ tmp2 = overlap[i + 3];
+ }
+
+ sample[16][sb] = tmp1;
+ overlap[16] = 0;
+ sample[17][sb] = tmp2;
+ overlap[17] = 0;
+ }
+# else
+ for (i = 0; i < 18; ++i) {
+ sample[i][sb] = overlap[i];
+ overlap[i] = 0;
+ }
+# endif
+}
+
+/*
+ * NAME: III_freqinver()
+ * DESCRIPTION: perform subband frequency inversion for odd sample lines
+ */
+static
+void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb)
+{
+ unsigned int i;
+
+# if 1 || defined(ASO_INTERLEAVE1) || defined(ASO_INTERLEAVE2)
+ {
+ register mad_fixed_t tmp1, tmp2;
+
+ tmp1 = sample[1][sb];
+ tmp2 = sample[3][sb];
+
+ for (i = 1; i < 13; i += 4) {
+ sample[i + 0][sb] = -tmp1;
+ tmp1 = sample[i + 4][sb];
+ sample[i + 2][sb] = -tmp2;
+ tmp2 = sample[i + 6][sb];
+ }
+
+ sample[13][sb] = -tmp1;
+ tmp1 = sample[17][sb];
+ sample[15][sb] = -tmp2;
+ sample[17][sb] = -tmp1;
+ }
+# else
+ for (i = 1; i < 18; i += 2)
+ sample[i][sb] = -sample[i][sb];
+# endif
+}
+
+/*
+ * NAME: III_decode()
+ * DESCRIPTION: decode frame main_data
+ */
+static
+int III_decode(struct mad_bitptr *ptr, struct mad_frame *frame,
+ struct sideinfo *si, unsigned int nch)
+{
+ struct mad_header *header = &frame->header;
+ unsigned int sfreqi, ngr, gr;
+
+ {
+ unsigned int sfreq;
+
+ sfreq = header->samplerate;
+ if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
+ sfreq *= 2;
+
+ /* 48000 => 0, 44100 => 1, 32000 => 2,
+ 24000 => 3, 22050 => 4, 16000 => 5 */
+ sfreqi = ((sfreq >> 7) & 0x000f) +
+ ((sfreq >> 15) & 0x0001) - 8;
+
+ if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
+ sfreqi += 3;
+ }
+
+ /* scalefactors, Huffman decoding, requantization */
+
+ ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2;
+
+ for (gr = 0; gr < ngr; ++gr) {
+ struct granule *granule = &si->gr[gr];
+ unsigned char const *sfbwidth = 0;
+ mad_fixed_t xr[2][576];
+ unsigned int ch;
+ enum mad_error error;
+
+ for (ch = 0; ch < nch; ++ch) {
+ struct channel *channel = &granule->ch[ch];
+ unsigned int part2_length;
+
+ sfbwidth = sfbwidth_table[sfreqi].l;
+ if (channel->block_type == 2) {
+ sfbwidth = (channel->flags & mixed_block_flag) ?
+ sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s;
+ }
+
+ if (header->flags & MAD_FLAG_LSF_EXT) {
+ part2_length = III_scalefactors_lsf(ptr, channel,
+ ch == 0 ? 0 : &si->gr[1].ch[1],
+ header->mode_extension);
+ }
+ else {
+ part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch],
+ gr == 0 ? 0 : si->scfsi[ch]);
+ }
+
+ error = III_huffdecode(ptr, xr[ch], channel, sfbwidth, part2_length);
+ if (error)
+ return error;
+ }
+
+ /* joint stereo processing */
+
+ if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) {
+ error = III_stereo(xr, granule, header, sfbwidth);
+ if (error)
+ return error;
+ }
+
+ /* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */
+
+ for (ch = 0; ch < nch; ++ch) {
+ struct channel const *channel = &granule->ch[ch];
+ mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr];
+ unsigned int sb, l, i, sblimit;
+ mad_fixed_t output[36];
+
+ if (channel->block_type == 2) {
+ III_reorder(xr[ch], channel, sfbwidth_table[sfreqi].s);
+
+# if !defined(OPT_STRICT)
+ /*
+ * According to ISO/IEC 11172-3, "Alias reduction is not applied for
+ * granules with block_type == 2 (short block)." However, other
+ * sources suggest alias reduction should indeed be performed on the
+ * lower two subbands of mixed blocks. Most other implementations do
+ * this, so by default we will too.
+ */
+ if (channel->flags & mixed_block_flag)
+ III_aliasreduce(xr[ch], 36);
+# endif
+ }
+ else
+ III_aliasreduce(xr[ch], 576);
+
+ l = 0;
+
+ /* subbands 0-1 */
+
+ if (channel->block_type != 2 || (channel->flags & mixed_block_flag)) {
+ unsigned int block_type;
+
+ block_type = channel->block_type;
+ if (channel->flags & mixed_block_flag)
+ block_type = 0;
+
+ /* long blocks */
+ for (sb = 0; sb < 2; ++sb, l += 18) {
+ III_imdct_l(&xr[ch][l], output, block_type);
+ III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
+ }
+ }
+ else {
+ /* short blocks */
+ for (sb = 0; sb < 2; ++sb, l += 18) {
+ III_imdct_s(&xr[ch][l], output);
+ III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
+ }
+ }
+
+ III_freqinver(sample, 1);
+
+ /* (nonzero) subbands 2-31 */
+
+ i = 576;
+ while (i > 36 && xr[ch][i - 1] == 0)
+ --i;
+
+ sblimit = 32 - (576 - i) / 18;
+
+ if (channel->block_type != 2) {
+ /* long blocks */
+ for (sb = 2; sb < sblimit; ++sb, l += 18) {
+ III_imdct_l(&xr[ch][l], output, channel->block_type);
+ III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
+
+ if (sb & 1)
+ III_freqinver(sample, sb);
+ }
+ }
+ else {
+ /* short blocks */
+ for (sb = 2; sb < sblimit; ++sb, l += 18) {
+ III_imdct_s(&xr[ch][l], output);
+ III_overlap(output, (*frame->overlap)[ch][sb], sample, sb);
+
+ if (sb & 1)
+ III_freqinver(sample, sb);
+ }
+ }
+
+ /* remaining (zero) subbands */
+
+ for (sb = sblimit; sb < 32; ++sb) {
+ III_overlap_z((*frame->overlap)[ch][sb], sample, sb);
+
+ if (sb & 1)
+ III_freqinver(sample, sb);
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * NAME: layer->III()
+ * DESCRIPTION: decode a single Layer III frame
+ */
+int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame)
+{
+ struct mad_header *header = &frame->header;
+ unsigned int nch, priv_bitlen, next_md_begin = 0;
+ unsigned int si_len, data_bitlen, md_len;
+ unsigned int frame_space, frame_used, frame_free;
+ struct mad_bitptr ptr;
+ struct sideinfo si;
+ enum mad_error error;
+ int result = 0;
+
+ /* allocate Layer III dynamic structures */
+
+ if (stream->main_data == 0) {
+ stream->main_data = malloc(MAD_BUFFER_MDLEN);
+ if (stream->main_data == 0) {
+ stream->error = MAD_ERROR_NOMEM;
+ return -1;
+ }
+ }
+
+ if (frame->overlap == 0) {
+ frame->overlap = calloc(2 * 32 * 18, sizeof(mad_fixed_t));
+ if (frame->overlap == 0) {
+ stream->error = MAD_ERROR_NOMEM;
+ return -1;
+ }
+ }
+
+ nch = MAD_NCHANNELS(header);
+ si_len = (header->flags & MAD_FLAG_LSF_EXT) ?
+ (nch == 1 ? 9 : 17) : (nch == 1 ? 17 : 32);
+
+ /* check frame sanity */
+
+ if (stream->next_frame - mad_bit_nextbyte(&stream->ptr) <
+ (signed int) si_len) {
+ stream->error = MAD_ERROR_BADFRAMELEN;
+ stream->md_len = 0;
+ return -1;
+ }
+
+ /* check CRC word */
+
+ if (header->flags & MAD_FLAG_PROTECTION) {
+ header->crc_check =
+ mad_bit_crc(stream->ptr, si_len * CHAR_BIT, header->crc_check);
+
+ if (header->crc_check != header->crc_target &&
+ !(frame->options & MAD_OPTION_IGNORECRC)) {
+ stream->error = MAD_ERROR_BADCRC;
+ result = -1;
+ }
+ }
+
+ /* decode frame side information */
+
+ error = III_sideinfo(&stream->ptr, nch, header->flags & MAD_FLAG_LSF_EXT,
+ &si, &data_bitlen, &priv_bitlen);
+ if (error && result == 0) {
+ stream->error = error;
+ result = -1;
+ }
+
+ header->flags |= priv_bitlen;
+ header->private_bits |= si.private_bits;
+
+ /* find main_data of next frame */
+
+ {
+ struct mad_bitptr peek;
+ unsigned long header;
+
+ mad_bit_init(&peek, stream->next_frame);
+
+ header = mad_bit_read(&peek, 32);
+ if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) {
+ if (!(header & 0x00010000L)) /* protection_bit */
+ mad_bit_skip(&peek, 16); /* crc_check */
+
+ next_md_begin =
+ mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8);
+ }
+
+ mad_bit_finish(&peek);
+ }
+
+ /* find main_data of this frame */
+
+ frame_space = stream->next_frame - mad_bit_nextbyte(&stream->ptr);
+
+ if (next_md_begin > si.main_data_begin + frame_space)
+ next_md_begin = 0;
+
+ md_len = si.main_data_begin + frame_space - next_md_begin;
+
+ frame_used = 0;
+
+ if (si.main_data_begin == 0) {
+ ptr = stream->ptr;
+ stream->md_len = 0;
+
+ frame_used = md_len;
+ }
+ else {
+ if (si.main_data_begin > stream->md_len) {
+ if (result == 0) {
+ stream->error = MAD_ERROR_BADDATAPTR;
+ result = -1;
+ }
+ }
+ else {
+ mad_bit_init(&ptr,
+ *stream->main_data + stream->md_len - si.main_data_begin);
+
+ if (md_len > si.main_data_begin) {
+ assert(stream->md_len + md_len -
+ si.main_data_begin <= MAD_BUFFER_MDLEN);
+
+ memcpy(*stream->main_data + stream->md_len,
+ mad_bit_nextbyte(&stream->ptr),
+ frame_used = md_len - si.main_data_begin);
+ stream->md_len += frame_used;
+ }
+ }
+ }
+
+ frame_free = frame_space - frame_used;
+
+ /* decode main_data */
+
+ if (result == 0) {
+ error = III_decode(&ptr, frame, &si, nch);
+ if (error) {
+ stream->error = error;
+ result = -1;
+ }
+ }
+
+ /* designate ancillary bits */
+
+ stream->anc_ptr = ptr;
+ stream->anc_bitlen = md_len * CHAR_BIT - data_bitlen;
+
+# if 0 && defined(DEBUG)
+ fprintf(stderr,
+ "main_data_begin:%u, md_len:%u, frame_free:%u, "
+ "data_bitlen:%u, anc_bitlen: %u\n",
+ si.main_data_begin, md_len, frame_free,
+ data_bitlen, stream->anc_bitlen);
+# endif
+
+ /* preload main_data buffer with up to 511 bytes for next frame(s) */
+
+ if (frame_free >= next_md_begin) {
+ memcpy(*stream->main_data,
+ stream->next_frame - next_md_begin, next_md_begin);
+ stream->md_len = next_md_begin;
+ }
+ else {
+ if (md_len < si.main_data_begin) {
+ unsigned int extra;
+
+ extra = si.main_data_begin - md_len;
+ if (extra + frame_free > next_md_begin)
+ extra = next_md_begin - frame_free;
+
+ if (extra < stream->md_len) {
+ memmove(*stream->main_data,
+ *stream->main_data + stream->md_len - extra, extra);
+ stream->md_len = extra;
+ }
+ }
+ else
+ stream->md_len = 0;
+
+ memcpy(*stream->main_data + stream->md_len,
+ stream->next_frame - frame_free, frame_free);
+ stream->md_len += frame_free;
+ }
+
+ return result;
+}
diff --git a/core/multimedia/opieplayer/libmad/layer3.h b/core/multimedia/opieplayer/libmad/layer3.h
new file mode 100644
index 0000000..1fd83e2
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/layer3.h
@@ -0,0 +1,30 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifndef LIBMAD_LAYER3_H
+# define LIBMAD_LAYER3_H
+
+# include "stream.h"
+# include "frame.h"
+
+int mad_layer_III(struct mad_stream *, struct mad_frame *);
+
+# endif
diff --git a/core/multimedia/opieplayer/libmad/libmad.pro b/core/multimedia/opieplayer/libmad/libmad.pro
new file mode 100644
index 0000000..e3f75b7
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/libmad.pro
@@ -0,0 +1,12 @@
+TEMPLATE = lib
+CONFIG += qt warn_on release
+HEADERS = libmad_version.h fixed.h bit.h timer.h stream.h frame.h synth.h decoder.h \
+ layer12.h layer3.h huffman.h libmad_global.h mad.h libmadplugin.h libmadpluginimpl.h
+SOURCES = version.c fixed.c bit.c timer.c stream.c frame.c synth.c decoder.c \
+ layer12.c layer3.c huffman.c libmadplugin.cpp libmadpluginimpl.cpp
+TARGET = madplugin
+DESTDIR = ../../plugins/codecs
+INCLUDEPATH += $(QPEDIR)/include ..
+DEPENDPATH += ../$(QPEDIR)/include ..
+LIBS += -lqpe -lm
+VERSION = 1.0.0
diff --git a/core/multimedia/opieplayer/libmad/libmad_global.h b/core/multimedia/opieplayer/libmad/libmad_global.h
new file mode 100644
index 0000000..f2a2a71
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/libmad_global.h
@@ -0,0 +1,45 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifndef LIBMAD_GLOBAL_H
+# define LIBMAD_GLOBAL_H
+
+/* conditional debugging */
+
+# if defined(DEBUG) && defined(NDEBUG)
+# error "cannot define both DEBUG and NDEBUG"
+# endif
+
+# if defined(DEBUG)
+# include <stdio.h>
+# endif
+
+/* conditional features */
+
+# if defined(OPT_SPEED) && defined(OPT_ACCURACY)
+# error "cannot optimize for both speed and accuracy"
+# endif
+
+# if defined(OPT_SPEED) && !defined(OPT_SSO)
+# define OPT_SSO 1
+# endif
+
+# endif
diff --git a/core/multimedia/opieplayer/libmad/libmad_version.h b/core/multimedia/opieplayer/libmad/libmad_version.h
new file mode 100644
index 0000000..f8ee1fa
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/libmad_version.h
@@ -0,0 +1,47 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifndef LIBMAD_VERSION_H
+# define LIBMAD_VERSION_H
+
+# define MAD_VERSION_MAJOR 0
+# define MAD_VERSION_MINOR 13
+# define MAD_VERSION_PATCH 0
+# define MAD_VERSION_EXTRA " (beta)"
+
+# define MAD_VERSION_STRINGIZE(str) #str
+# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num)
+
+# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \
+ MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \
+ MAD_VERSION_STRING(MAD_VERSION_PATCH) \
+ MAD_VERSION_EXTRA
+
+# define MAD_PUBLISHYEAR "2000-2001"
+# define MAD_AUTHOR "Robert Leslie"
+# define MAD_EMAIL "rob@mars.org"
+
+extern char const mad_version[];
+extern char const mad_copyright[];
+extern char const mad_author[];
+extern char const mad_build[];
+
+# endif
diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.cpp b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
new file mode 100644
index 0000000..b2b876f
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
@@ -0,0 +1,578 @@
+/**********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <time.h>
+#include <locale.h>
+#include <math.h>
+#include <assert.h>
+#include <qapplication.h>
+
+//#define HAVE_MMAP
+
+#if defined(HAVE_MMAP)
+# include <sys/mman.h>
+#endif
+#include "libmadplugin.h"
+
+
+extern "C" {
+#include "mad.h"
+}
+
+
+#define MPEG_BUFFER_SIZE 65536
+//#define debugMsg(a) qDebug(a)
+#define debugMsg(a)
+
+
+class Input {
+public:
+ char const *path;
+ int fd;
+#if defined(HAVE_MMAP)
+ void *fdm;
+#endif
+ unsigned char *data;
+ unsigned long length;
+ int eof;
+};
+
+
+class Output {
+public:
+ mad_fixed_t attenuate;
+ struct filter *filters;
+ unsigned int channels_in;
+ unsigned int channels_out;
+ unsigned int speed_in;
+ unsigned int speed_out;
+ const char *path;
+};
+
+
+# if defined(HAVE_MMAP)
+static void *map_file(int fd, unsigned long *length)
+{
+ void *fdm;
+
+ *length += MAD_BUFFER_GUARD;
+
+ fdm = mmap(0, *length, PROT_READ, MAP_SHARED, fd, 0);
+ if (fdm == MAP_FAILED)
+ return 0;
+
+# if defined(HAVE_MADVISE)
+ madvise(fdm, *length, MADV_SEQUENTIAL);
+# endif
+
+ return fdm;
+}
+
+
+static int unmap_file(void *fdm, unsigned long length)
+{
+ if (munmap(fdm, length) == -1)
+ return -1;
+
+ return 0;
+}
+# endif
+
+
+static inline QString tr( const char *str ) {
+ // Apparently this is okay from a plugin as it runs in the process space of the owner of the plugin
+ return qApp->translate( "MediaPlayer", str, "libmad strings for mp3 file info" );
+}
+
+
+class LibMadPluginData {
+public:
+ Input input;
+ Output output;
+ int bad_last_frame;
+ struct mad_stream stream;
+ struct mad_frame frame;
+ struct mad_synth synth;
+ bool flush;
+};
+
+
+LibMadPlugin::LibMadPlugin() {
+ d = new LibMadPluginData;
+ d->input.fd = 0;
+#if defined(HAVE_MMAP)
+ d->input.fdm = 0;
+#endif
+ d->input.data = 0;
+ d->flush = TRUE;
+ info = tr( "No Song Open" );
+}
+
+
+LibMadPlugin::~LibMadPlugin() {
+ close();
+ delete d;
+}
+
+
+bool LibMadPlugin::isFileSupported( const QString& path ) {
+ debugMsg( "LibMadPlugin::isFileSupported" );
+
+ // Mpeg file extensions
+ // "mp2","mp3","m1v","m2v","m2s","mpg","vob","mpeg","ac3"
+ // Other media extensions
+ // "wav","mid","mod","s3m","ogg","avi","mov","sid"
+
+ char *ext = strrchr( path.latin1(), '.' );
+
+ // Test file extension
+ if ( ext ) {
+ if ( strncasecmp(ext, ".mp2", 4) == 0 )
+ return TRUE;
+ if ( strncasecmp(ext, ".mp3", 4) == 0 )
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+bool LibMadPlugin::open( const QString& path ) {
+ debugMsg( "LibMadPlugin::open" );
+
+ d->bad_last_frame = 0;
+ d->flush = TRUE;
+ info = QString( "" );
+
+ //qDebug( "Opening %s", path.latin1() );
+
+ d->input.path = path.latin1();
+ d->input.fd = ::open( d->input.path, O_RDONLY );
+ if (d->input.fd == -1) {
+ qDebug("error opening %s", d->input.path );
+ return FALSE;
+ }
+
+ printID3Tags();
+
+#if defined(HAVE_MMAP)
+ struct stat stat;
+ if (fstat(d->input.fd, &stat) == -1) {
+ qDebug("error calling fstat"); return FALSE;
+ }
+ if (S_ISREG(stat.st_mode) && stat.st_size > 0) {
+ d->input.length = stat.st_size;
+ d->input.fdm = map_file(d->input.fd, &d->input.length);
+ if (d->input.fdm == 0) {
+ qDebug("error mmapping file"); return FALSE;
+ }
+ d->input.data = (unsigned char *)d->input.fdm;
+ }
+#endif
+
+ if (d->input.data == 0) {
+ d->input.data = (unsigned char *)malloc(MPEG_BUFFER_SIZE);
+ if (d->input.data == 0) {
+ qDebug("error allocating input buffer");
+ return FALSE;
+ }
+ d->input.length = 0;
+ }
+
+ d->input.eof = 0;
+
+ mad_stream_init(&d->stream);
+ mad_frame_init(&d->frame);
+ mad_synth_init(&d->synth);
+
+ return TRUE;
+}
+
+
+bool LibMadPlugin::close() {
+ debugMsg( "LibMadPlugin::close" );
+
+ int result = TRUE;
+
+ mad_synth_finish(&d->synth);
+ mad_frame_finish(&d->frame);
+ mad_stream_finish(&d->stream);
+
+#if defined(HAVE_MMAP)
+ if (d->input.fdm) {
+ if (unmap_file(d->input.fdm, d->input.length) == -1) {
+ qDebug("error munmapping file");
+ result = FALSE;
+ }
+ d->input.fdm = 0;
+ d->input.data = 0;
+ }
+#endif
+
+ if (d->input.data) {
+ free(d->input.data);
+ d->input.data = 0;
+ }
+
+ if (::close(d->input.fd) == -1) {
+ qDebug("error closing file %s", d->input.path);
+ result = FALSE;
+ }
+
+ d->input.fd = 0;
+
+ return result;
+}
+
+
+bool LibMadPlugin::isOpen() {
+ debugMsg( "LibMadPlugin::isOpen" );
+ return ( d->input.fd != 0 );
+}
+
+
+int LibMadPlugin::audioStreams() {
+ debugMsg( "LibMadPlugin::audioStreams" );
+ return 1;
+}
+
+
+int LibMadPlugin::audioChannels( int ) {
+ debugMsg( "LibMadPlugin::audioChannels" );
+/*
+ long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
+ qDebug( "LibMadPlugin::audioChannels: %i", d->frame.header.mode > 0 ? 2 : 1 );
+ return d->frame.header.mode > 0 ? 2 : 1;
+*/
+ return 2;
+}
+
+
+int LibMadPlugin::audioFrequency( int ) {
+ debugMsg( "LibMadPlugin::audioFrequency" );
+ long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
+ qDebug( "LibMadPlugin::audioFrequency: %i", d->frame.header.samplerate );
+ return d->frame.header.samplerate;
+}
+
+
+int LibMadPlugin::audioSamples( int ) {
+ debugMsg( "LibMadPlugin::audioSamples" );
+/*
+ long t; short t1[5]; audioReadSamples( t1, 2, 1, t, 0 );
+ mad_header_decode( (struct mad_header *)&d->frame.header, &d->stream );
+ qDebug( "LibMadPlugin::audioSamples: %i*%i", d->frame.header.duration.seconds, d->frame.header.samplerate );
+ return d->frame.header.duration.seconds * d->frame.header.samplerate;
+*/
+ return 10000000;
+}
+
+
+bool LibMadPlugin::audioSetSample( long, int ) {
+ debugMsg( "LibMadPlugin::audioSetSample" );
+ return FALSE;
+}
+
+
+long LibMadPlugin::audioGetSample( int ) {
+ debugMsg( "LibMadPlugin::audioGetSample" );
+ return 0;
+}
+
+/*
+bool LibMadPlugin::audioReadSamples( short *, int, long, int ) {
+ debugMsg( "LibMadPlugin::audioReadSamples" );
+ return FALSE;
+}
+
+
+bool LibMadPlugin::audioReReadSamples( short *, int, long, int ) {
+ debugMsg( "LibMadPlugin::audioReReadSamples" );
+ return FALSE;
+}
+*/
+
+bool LibMadPlugin::read() {
+ debugMsg( "LibMadPlugin::read" );
+ int len;
+
+ if (d->input.eof)
+ return FALSE;
+
+#if defined(HAVE_MMAP)
+ if (d->input.fdm) {
+ unsigned long skip = 0;
+
+ if (d->stream.next_frame) {
+ struct stat stat;
+
+ if (fstat(d->input.fd, &stat) == -1)
+ return FALSE;
+
+ if (stat.st_size + MAD_BUFFER_GUARD <= (signed)d->input.length)
+ return FALSE;
+
+ // file size changed; update memory map
+ skip = d->stream.next_frame - d->input.data;
+
+ if (unmap_file(d->input.fdm, d->input.length) == -1) {
+ d->input.fdm = 0;
+ d->input.data = 0;
+ return FALSE;
+ }
+
+ d->input.length = stat.st_size;
+
+ d->input.fdm = map_file(d->input.fd, &d->input.length);
+ if (d->input.fdm == 0) {
+ d->input.data = 0;
+ return FALSE;
+ }
+
+ d->input.data = (unsigned char *)d->input.fdm;
+ }
+
+ mad_stream_buffer(&d->stream, d->input.data + skip, d->input.length - skip);
+
+ } else
+#endif
+ {
+ if (d->stream.next_frame) {
+ memmove(d->input.data, d->stream.next_frame,
+ d->input.length = &d->input.data[d->input.length] - d->stream.next_frame);
+ }
+
+ do {
+ len = ::read(d->input.fd, d->input.data + d->input.length, MPEG_BUFFER_SIZE - d->input.length);
+ }
+ while (len == -1 && errno == EINTR);
+
+ if (len == -1) {
+ qDebug("error reading audio");
+ return FALSE;
+ }
+ else if (len == 0) {
+ d->input.eof = 1;
+
+ assert(MPEG_BUFFER_SIZE - d->input.length >= MAD_BUFFER_GUARD);
+
+ while (len < MAD_BUFFER_GUARD)
+ d->input.data[d->input.length + len++] = 0;
+ }
+
+ mad_stream_buffer(&d->stream, d->input.data, d->input.length += len);
+ }
+
+ return TRUE;
+}
+
+
+static mad_fixed_t left_err, right_err;
+static const int bits = 16;
+static const int shift = MAD_F_FRACBITS + 1 - bits;
+
+
+inline long audio_linear_dither( mad_fixed_t sample, mad_fixed_t& error )
+{
+ sample += error;
+ mad_fixed_t quantized = (sample >= MAD_F_ONE) ? MAD_F_ONE - 1 : ( (sample < -MAD_F_ONE) ? -MAD_F_ONE : sample );
+ quantized &= ~((1L << shift) - 1);
+ error = sample - quantized;
+ return quantized >> shift;
+}
+
+
+inline void audio_pcm( short *data, unsigned int nsamples, mad_fixed_t *left, mad_fixed_t *right )
+{
+ if ( right ) {
+ while (nsamples--) {
+ data[0] = audio_linear_dither( *left++, left_err );
+ data[1] = audio_linear_dither( *right++, right_err );
+ data += 2;
+ }
+ } else {
+ while (nsamples--) {
+ data[0] = data[1] = audio_linear_dither( *left++, left_err );
+ data += 2;
+ }
+ }
+}
+
+
+bool LibMadPlugin::decode( short *output, long samples, long& samplesMade ) {
+ debugMsg( "LibMadPlugin::decode" );
+
+ static int buffered = 0;
+ static mad_fixed_t buffer[2][65536 * 2];
+ int offset = buffered;
+ samplesMade = 0;
+
+ static int maxBuffered = 8000; // 65536;
+
+ if ( samples > maxBuffered )
+ samples = maxBuffered;
+
+ if ( d->flush ) {
+ buffered = 0;
+ offset = 0;
+ d->flush = FALSE;
+ }
+
+ while ( buffered < maxBuffered ) {
+
+ while (mad_frame_decode(&d->frame, &d->stream) == -1) {
+ if (!MAD_RECOVERABLE(d->stream.error)) {
+ debugMsg( "feed me" );
+ return FALSE; // Feed me
+ }
+ if ( d->stream.error == MAD_ERROR_BADCRC ) {
+ mad_frame_mute(&d->frame);
+ qDebug( "error decoding, bad crc" );
+ }
+ }
+
+ mad_synth_frame(&d->synth, &d->frame);
+ int decodedSamples = d->synth.pcm.length;
+ memcpy( &(buffer[0][offset]), d->synth.pcm.samples[0], decodedSamples * sizeof(mad_fixed_t) );
+ if ( d->synth.pcm.channels == 2 )
+ memcpy( &(buffer[1][offset]), d->synth.pcm.samples[1], decodedSamples * sizeof(mad_fixed_t) );
+ offset += decodedSamples;
+ buffered += decodedSamples;
+ }
+
+ audio_pcm( output, samples, buffer[0], (d->synth.pcm.channels == 2) ? buffer[1] : 0 );
+// audio_pcm( output, samples, buffer[1], buffer[0] );
+// audio_pcm( output, samples, buffer[0], buffer[1] );
+ samplesMade = samples;
+ memmove( buffer[0], &(buffer[0][samples]), (buffered - samples) * sizeof(mad_fixed_t) );
+ if ( d->synth.pcm.channels == 2 )
+ memmove( buffer[1], &(buffer[1][samples]), (buffered - samples) * sizeof(mad_fixed_t) );
+ buffered -= samples;
+
+ return TRUE;
+}
+
+/*
+bool LibMadPlugin::audioReadMonoSamples( short *, long, long&, int ) {
+ debugMsg( "LibMadPlugin::audioReadMonoSamples" );
+ return FALSE;
+}
+
+
+bool LibMadPlugin::audioReadStereoSamples( short *output, long samples, long& samplesMade, int ) {
+*/
+bool LibMadPlugin::audioReadSamples( short *output, int /*channels*/, long samples, long& samplesMade, int ) {
+ debugMsg( "LibMadPlugin::audioReadStereoSamples" );
+
+ static bool needInput = TRUE;
+
+ if ( samples == 0 )
+ return TRUE;
+
+ do {
+ if ( needInput )
+ if ( !read() ) {
+// if ( d->input.eof )
+// needInput = FALSE;
+// else
+ return TRUE;
+ }
+
+ needInput = FALSE;
+
+ if ( decode( output, samples, samplesMade ) )
+ return FALSE;
+ else
+ needInput = TRUE;
+ }
+ while ( ( samplesMade < samples ) && ( !d->input.eof ) );
+/*
+ static bool firstTimeThru = TRUE;
+
+ if ( firstTimeThru ) {
+ firstTimeThru = FALSE;
+ decode( output, samples, samplesMade );
+ return FALSE;
+ } else
+*/
+ return TRUE;
+}
+
+
+double LibMadPlugin::getTime() {
+ debugMsg( "LibMadPlugin::getTime" );
+ return 0.0;
+}
+
+
+void LibMadPlugin::printID3Tags() {
+ debugMsg( "LibMadPlugin::printID3Tags" );
+
+ char id3v1[128 + 1];
+
+ if ( ::lseek( d->input.fd, -128, SEEK_END ) == -1 ) {
+ qDebug( "error seeking to id3 tags" );
+ return;
+ }
+
+ if ( ::read( d->input.fd, id3v1, 128 ) != 128 ) {
+ qDebug( "error reading in id3 tags" );
+ return;
+ }
+
+ if ( ::strncmp( (const char *)id3v1, "TAG", 3 ) != 0 ) {
+ debugMsg( "sorry, no id3 tags" );
+ } else {
+ int len[5] = { 30, 30, 30, 4, 30 };
+ QString label[5] = { tr( "Title" ), tr( "Artist" ), tr( "Album" ), tr( "Year" ), tr( "Comment" ) };
+ char *ptr = id3v1 + 3, *ptr2 = ptr + len[0];
+ qDebug( "ID3 tags in file:" );
+ info = "";
+ for ( int i = 0; i < 5; ptr += len[i], i++, ptr2 += len[i] ) {
+ char push = *ptr2;
+ *ptr2 = '\0';
+ char *ptr3 = ptr2;
+ while ( ptr3-1 >= ptr && isspace(ptr3[-1]) ) ptr3--;
+ char push2 = *ptr3; *ptr3 = '\0';
+ if ( strcmp( ptr, "" ) )
+ info += ( i != 0 ? ", " : "" ) + label[i] + ": " + ptr;
+ //qDebug( info.latin1() );
+ *ptr3 = push2;
+ *ptr2 = push;
+ }
+ if (id3v1[126] == 0 && id3v1[127] != 0)
+ info += tr( ", Track: " ) + id3v1[127];
+ }
+
+ if ( ::lseek(d->input.fd, 0, SEEK_SET) == -1 ) {
+ qDebug( "error seeking back to beginning" );
+ return;
+ }
+}
+
diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.h b/core/multimedia/opieplayer/libmad/libmadplugin.h
new file mode 100644
index 0000000..88647ae
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/libmadplugin.h
@@ -0,0 +1,101 @@
+/**********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef LIBMAD_PLUGIN_H
+#define LIBMAD_PLUGIN_H
+
+
+#include <qstring.h>
+#include "mediaplayerplugininterface.h"
+
+
+class LibMadPluginData;
+
+
+class LibMadPlugin : public MediaPlayerDecoder {
+
+public:
+ LibMadPlugin();
+ ~LibMadPlugin();
+
+ const char *pluginName() { return "LibMadPlugin"; }
+ const char *pluginComment() { return "This is the libmad library that has been wrapped as a plugin"; }
+ double pluginVersion() { return 1.0; }
+
+ bool isFileSupported( const QString& );
+ bool open( const QString& );
+ bool close();
+ bool isOpen();
+ const QString &fileInfo() { return info; }
+
+ // If decoder doesn't support audio then return 0 here
+ int audioStreams();
+ int audioChannels( int stream );
+ int audioFrequency( int stream );
+ int audioSamples( int stream );
+ bool audioSetSample( long sample, int stream );
+ long audioGetSample( int stream );
+// bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream );
+// bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream );
+ bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream );
+// bool audioReadSamples( short *output, int channel, long samples, int stream );
+// bool audioReReadSamples( short *output, int channel, long samples, int stream );
+
+
+ bool read();
+ bool decode( short *output, long samples, long& samplesRead );
+ void printID3Tags();
+
+
+ // If decoder doesn't support video then return 0 here
+ int videoStreams() { return 0; }
+ int videoWidth( int ) { return 0; }
+ int videoHeight( int ) { return 0; }
+ double videoFrameRate( int ) { return 0.0; }
+ int videoFrames( int ) { return 0; }
+ bool videoSetFrame( long, int ) { return FALSE; }
+ long videoGetFrame( int ) { return 0; }
+ bool videoReadFrame( unsigned char **, int, int, int, int, ColorFormat, int ) { return FALSE; }
+ bool videoReadScaledFrame( unsigned char **, int, int, int, int, int, int, ColorFormat, int ) { return FALSE; }
+ bool videoReadYUVFrame( char *, char *, char *, int, int, int, int, int ) { return FALSE; }
+
+ // Profiling
+ double getTime();
+
+ // Ignore if these aren't supported
+ bool setSMP( int ) { return FALSE; }
+ bool setMMX( bool ) { return FALSE; }
+
+ // Capabilities
+ bool supportsAudio() { return TRUE; }
+ bool supportsVideo() { return FALSE; }
+ bool supportsYUV() { return FALSE; }
+ bool supportsMMX() { return TRUE; }
+ bool supportsSMP() { return FALSE; }
+ bool supportsStereo() { return TRUE; }
+ bool supportsScaling() { return FALSE; }
+
+private:
+ LibMadPluginData *d;
+ QString info;
+
+};
+
+
+#endif
diff --git a/core/multimedia/opieplayer/libmad/libmadpluginimpl.cpp b/core/multimedia/opieplayer/libmad/libmadpluginimpl.cpp
new file mode 100644
index 0000000..028c658
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/libmadpluginimpl.cpp
@@ -0,0 +1,70 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "libmadplugin.h"
+#include "libmadpluginimpl.h"
+
+
+LibMadPluginImpl::LibMadPluginImpl()
+ : libmadplugin(0), ref(0)
+{
+}
+
+
+LibMadPluginImpl::~LibMadPluginImpl()
+{
+ if ( libmadplugin )
+ delete libmadplugin;
+}
+
+
+MediaPlayerDecoder *LibMadPluginImpl::decoder()
+{
+ if ( !libmadplugin )
+ libmadplugin = new LibMadPlugin;
+ return libmadplugin;
+}
+
+
+MediaPlayerEncoder *LibMadPluginImpl::encoder()
+{
+ return NULL;
+}
+
+
+#ifndef QT_NO_COMPONENT
+
+
+QRESULT LibMadPluginImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
+{
+ *iface = 0;
+ if ( ( uuid == IID_QUnknown ) || ( uuid == IID_MediaPlayerPlugin ) )
+ *iface = this, (*iface)->addRef();
+ return QS_OK;
+}
+
+
+Q_EXPORT_INTERFACE()
+{
+ Q_CREATE_INSTANCE( LibMadPluginImpl )
+}
+
+
+#endif
+
diff --git a/core/multimedia/opieplayer/libmad/libmadpluginimpl.h b/core/multimedia/opieplayer/libmad/libmadpluginimpl.h
new file mode 100644
index 0000000..a26b421
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/libmadpluginimpl.h
@@ -0,0 +1,53 @@
+/**********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef LIBMAD_PLUGIN_IMPL_H
+#define LIBMAD_PLUGIN_IMPL_H
+
+
+#include "../mediaplayerplugininterface.h"
+
+
+class LibMadPlugin;
+
+
+class LibMadPluginImpl : public MediaPlayerPluginInterface
+{
+public:
+ LibMadPluginImpl();
+ virtual ~LibMadPluginImpl();
+
+#ifndef QT_NO_COMPONENT
+
+ QRESULT queryInterface( const QUuid&, QUnknownInterface** );
+ Q_REFCOUNT
+
+#endif
+
+ virtual MediaPlayerDecoder *decoder();
+ virtual MediaPlayerEncoder *encoder();
+
+private:
+ LibMadPlugin *libmadplugin;
+ ulong ref;
+};
+
+
+#endif
+
diff --git a/core/multimedia/opieplayer/libmad/mad.h b/core/multimedia/opieplayer/libmad/mad.h
new file mode 100644
index 0000000..9db9da3
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/mad.h
@@ -0,0 +1,830 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * If you would like to negotiate alternate licensing terms, you may do
+ * so by contacting the author: Robert Leslie <rob@mars.org>
+ */
+
+# define SIZEOF_INT 4
+# define SIZEOF_LONG 4
+# define SIZEOF_LONG_LONG 8
+
+/* Id: version.h,v 1.16 2001/04/05 04:57:11 rob Exp */
+
+# ifndef LIBMAD_VERSION_H
+# define LIBMAD_VERSION_H
+
+# define MAD_VERSION_MAJOR 0
+# define MAD_VERSION_MINOR 13
+# define MAD_VERSION_PATCH 0
+# define MAD_VERSION_EXTRA " (beta)"
+
+# define MAD_VERSION_STRINGIZE(str) #str
+# define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num)
+
+# define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \
+ MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \
+ MAD_VERSION_STRING(MAD_VERSION_PATCH) \
+ MAD_VERSION_EXTRA
+
+# define MAD_PUBLISHYEAR "2000-2001"
+# define MAD_AUTHOR "Robert Leslie"
+# define MAD_EMAIL "rob@mars.org"
+
+extern char const mad_version[];
+extern char const mad_copyright[];
+extern char const mad_author[];
+extern char const mad_build[];
+
+# endif
+
+/* Id: fixed.h,v 1.23 2001/04/05 04:57:11 rob Exp */
+
+# ifndef LIBMAD_FIXED_H
+# define LIBMAD_FIXED_H
+
+# if SIZEOF_INT >= 4
+typedef signed int mad_fixed_t;
+
+typedef signed int mad_fixed64hi_t;
+typedef unsigned int mad_fixed64lo_t;
+# else
+typedef signed long mad_fixed_t;
+
+typedef signed long mad_fixed64hi_t;
+typedef unsigned long mad_fixed64lo_t;
+# endif
+
+/*
+ * Fixed-point format: 0xABBBBBBB
+ * A == whole part (sign + 3 bits)
+ * B == fractional part (28 bits)
+ *
+ * Values are signed two's complement, so the effective range is:
+ * 0x80000000 to 0x7fffffff
+ * -8.0 to +7.9999999962747097015380859375
+ *
+ * The smallest representable value is:
+ * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9)
+ *
+ * 28 bits of fractional accuracy represent about
+ * 8.6 digits of decimal accuracy.
+ *
+ * Fixed-point numbers can be added or subtracted as normal
+ * integers, but multiplication requires shifting the 64-bit result
+ * from 56 fractional bits back to 28 (and rounding.)
+ *
+ * Changing the definition of MAD_F_FRACBITS is only partially
+ * supported, and must be done with care.
+ */
+
+# define MAD_F_FRACBITS 28
+
+# if MAD_F_FRACBITS == 28
+# define MAD_F(x) ((mad_fixed_t) (x##L))
+# else
+# if MAD_F_FRACBITS < 28
+# warning "MAD_F_FRACBITS < 28"
+# define MAD_F(x) ((mad_fixed_t) \
+ (((x##L) + \
+ (1L << (28 - MAD_F_FRACBITS - 1))) >> \
+ (28 - MAD_F_FRACBITS)))
+# elif MAD_F_FRACBITS > 28
+# error "MAD_F_FRACBITS > 28 not currently supported"
+# define MAD_F(x) ((mad_fixed_t) \
+ ((x##L) << (MAD_F_FRACBITS - 28)))
+# endif
+# endif
+
+# define MAD_F_MIN ((mad_fixed_t) -0x80000000L)
+# define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL)
+
+# define MAD_F_ONE MAD_F(0x10000000)
+
+# define mad_f_tofixed(x) ((mad_fixed_t) \
+ ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5))
+# define mad_f_todouble(x) ((double) \
+ ((x) / (double) (1L << MAD_F_FRACBITS)))
+
+# define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS)
+# define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1))
+ /* (x should be positive) */
+
+# define mad_f_fromint(x) ((x) << MAD_F_FRACBITS)
+
+# define mad_f_add(x, y) ((x) + (y))
+# define mad_f_sub(x, y) ((x) - (y))
+
+# if defined(FPM_64BIT)
+
+/*
+ * This version should be the most accurate if 64-bit (long long) types are
+ * supported by the compiler, although it may not be the most efficient.
+ */
+# if defined(OPT_ACCURACY)
+# define mad_f_mul(x, y) \
+ ((mad_fixed_t) \
+ ((((signed long long) (x) * (y)) + \
+ (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS))
+# else
+# define mad_f_mul(x, y) \
+ ((mad_fixed_t) (((signed long long) (x) * (y)) >> MAD_F_SCALEBITS))
+# endif
+
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+
+/* --- Intel --------------------------------------------------------------- */
+
+# elif defined(FPM_INTEL)
+
+/*
+ * This Intel version is fast and accurate; the disposition of the least
+ * significant bit depends on OPT_ACCURACY via mad_f_scale64().
+ */
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("imull %3" \
+ : "=a" (lo), "=d" (hi) \
+ : "%a" (x), "rm" (y) \
+ : "cc")
+
+# if defined(OPT_ACCURACY)
+/*
+ * This gives best accuracy but is not very fast.
+ */
+# define MAD_F_MLA(hi, lo, x, y) \
+ ({ mad_fixed64hi_t __hi; \
+ mad_fixed64lo_t __lo; \
+ MAD_F_MLX(__hi, __lo, (x), (y)); \
+ asm ("addl %2,%0\n\t" \
+ "adcl %3,%1" \
+ : "=rm" (lo), "=rm" (hi) \
+ : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \
+ : "cc"); \
+ })
+# endif /* OPT_ACCURACY */
+
+# if defined(OPT_ACCURACY)
+/*
+ * Surprisingly, this is faster than SHRD followed by ADC.
+ */
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed64hi_t __hi_; \
+ mad_fixed64lo_t __lo_; \
+ mad_fixed_t __result; \
+ asm ("addl %4,%2\n\t" \
+ "adcl %5,%3" \
+ : "=rm" (__lo_), "=rm" (__hi_) \
+ : "0" (lo), "1" (hi), \
+ "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \
+ : "cc"); \
+ asm ("shrdl %3,%2,%1" \
+ : "=rm" (__result) \
+ : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \
+ : "cc"); \
+ __result; \
+ })
+# else
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed_t __result; \
+ asm ("shrdl %3,%2,%1" \
+ : "=rm" (__result) \
+ : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \
+ : "cc"); \
+ __result; \
+ })
+# endif /* OPT_ACCURACY */
+
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+
+/* --- ARM ----------------------------------------------------------------- */
+
+# elif defined(FPM_ARM)
+
+/*
+ * This ARM V4 version is as accurate as FPM_64BIT but much faster. The
+ * least significant bit is properly rounded at no CPU cycle cost!
+ */
+# if 1
+/*
+ * There's a bug somewhere, possibly in the compiler, that sometimes makes
+ * this necessary instead of the default implementation via MAD_F_MLX and
+ * mad_f_scale64. It may be related to the use (or lack) of
+ * -finline-functions and/or -fstrength-reduce.
+ *
+ * This is also apparently faster than MAD_F_MLX/mad_f_scale64.
+ */
+# define mad_f_mul(x, y) \
+ ({ mad_fixed64hi_t __hi; \
+ mad_fixed64lo_t __lo; \
+ mad_fixed_t __result; \
+ asm ("smull %0, %1, %3, %4\n\t" \
+ "movs %0, %0, lsr %5\n\t" \
+ "adc %2, %0, %1, lsl %6" \
+ : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \
+ : "%r" (x), "r" (y), \
+ "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
+ : "cc"); \
+ __result; \
+ })
+# endif
+
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("smull %0, %1, %2, %3" \
+ : "=&r" (lo), "=&r" (hi) \
+ : "%r" (x), "r" (y))
+
+# define MAD_F_MLA(hi, lo, x, y) \
+ asm ("smlal %0, %1, %2, %3" \
+ : "+r" (lo), "+r" (hi) \
+ : "%r" (x), "r" (y))
+
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed_t __result; \
+ asm ("movs %0, %1, lsr %3\n\t" \
+ "adc %0, %0, %2, lsl %4" \
+ : "=r" (__result) \
+ : "r" (lo), "r" (hi), \
+ "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \
+ : "cc"); \
+ __result; \
+ })
+
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+
+/* --- MIPS ---------------------------------------------------------------- */
+
+# elif defined(FPM_MIPS)
+
+/*
+ * This MIPS version is fast and accurate; the disposition of the least
+ * significant bit depends on OPT_ACCURACY via mad_f_scale64().
+ */
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("mult %2,%3" \
+ : "=l" (lo), "=h" (hi) \
+ : "%r" (x), "r" (y))
+
+# if defined(HAVE_MADD_ASM)
+# define MAD_F_MLA(hi, lo, x, y) \
+ asm ("madd %2,%3" \
+ : "+l" (lo), "+h" (hi) \
+ : "%r" (x), "r" (y))
+# elif defined(HAVE_MADD16_ASM)
+/*
+ * This loses significant accuracy due to the 16-bit integer limit in the
+ * multiply/accumulate instruction.
+ */
+# define MAD_F_ML0(hi, lo, x, y) \
+ asm ("mult %2,%3" \
+ : "=l" (lo), "=h" (hi) \
+ : "%r" ((x) >> 12), "r" ((y) >> 16))
+# define MAD_F_MLA(hi, lo, x, y) \
+ asm ("madd16 %2,%3" \
+ : "+l" (lo), "+h" (hi) \
+ : "%r" ((x) >> 12), "r" ((y) >> 16))
+# define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo))
+# endif
+
+# if defined(OPT_SPEED)
+# define mad_f_scale64(hi, lo) \
+ ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS)))
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+# endif
+
+/* --- SPARC --------------------------------------------------------------- */
+
+# elif defined(FPM_SPARC)
+
+/*
+ * This SPARC V8 version is fast and accurate; the disposition of the least
+ * significant bit depends on OPT_ACCURACY via mad_f_scale64().
+ */
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("smul %2, %3, %0\n\t" \
+ "rd %%y, %1" \
+ : "=r" (lo), "=r" (hi) \
+ : "%r" (x), "rI" (y))
+
+/* --- PowerPC ------------------------------------------------------------- */
+
+# elif defined(FPM_PPC)
+
+/*
+ * This PowerPC version is tuned for the 4xx embedded processors. It is
+ * effectively a tuned version of FPM_64BIT. It is a little faster and just
+ * as accurate. The disposition of the least significant bit depends on
+ * OPT_ACCURACY via mad_f_scale64().
+ */
+# define MAD_F_MLX(hi, lo, x, y) \
+ asm ("mulhw %1, %2, %3\n\t" \
+ "mullw %0, %2, %3" \
+ : "=&r" (lo), "=&r" (hi) \
+ : "%r" (x), "r" (y))
+
+# define MAD_F_MLA(hi, lo, x, y) \
+ ({ mad_fixed64hi_t __hi; \
+ mad_fixed64lo_t __lo; \
+ MAD_F_MLX(__hi, __lo, (x), (y)); \
+ asm ("addc %0, %2, %3\n\t" \
+ "adde %1, %4, %5" \
+ : "=r" (lo), "=r" (hi) \
+ : "%r" (__lo), "0" (lo), "%r" (__hi), "1" (hi)); \
+ })
+
+# if defined(OPT_ACCURACY)
+/*
+ * This is accurate and ~2 - 2.5 times slower than the unrounded version.
+ *
+ * The __volatile__ improves the generated code by another 5% (fewer spills
+ * to memory); eventually they should be removed.
+ */
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed_t __result; \
+ mad_fixed64hi_t __hi_; \
+ mad_fixed64lo_t __lo_; \
+ asm __volatile__ ("addc %0, %2, %4\n\t" \
+ "addze %1, %3" \
+ : "=r" (__lo_), "=r" (__hi_) \
+ : "r" (lo), "r" (hi), "r" (1 << (MAD_F_SCALEBITS - 1))); \
+ asm __volatile__ ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \
+ "rlwimi %0, %1,32-%3,%3,31" \
+ : "=&r" (__result) \
+ : "r" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS)); \
+ __result; \
+ })
+# else
+# define mad_f_scale64(hi, lo) \
+ ({ mad_fixed_t __result; \
+ asm ("rlwinm %0, %2,32-%3,0,%3-1\n\t" \
+ "rlwimi %0, %1,32-%3,%3,31" \
+ : "=r" (__result) \
+ : "r" (lo), "r" (hi), "I" (MAD_F_SCALEBITS)); \
+ __result; \
+ })
+# endif /* OPT_ACCURACY */
+
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+
+/* --- Default ------------------------------------------------------------- */
+
+# elif defined(FPM_DEFAULT)
+
+/*
+ * This version is the most portable but it loses significant accuracy.
+ * Furthermore, accuracy is biased against the second argument, so care
+ * should be taken when ordering operands.
+ *
+ * The scale factors are constant as this is not used with SSO.
+ *
+ * Pre-rounding is required to stay within the limits of compliance.
+ */
+# define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \
+ (((y) + (1L << 15)) >> 16))
+
+/* ------------------------------------------------------------------------- */
+
+# else
+# error "no FPM selected"
+# endif
+
+/* default implementations */
+
+# if !defined(mad_f_mul)
+# define mad_f_mul(x, y) \
+ ({ mad_fixed64hi_t __hi; \
+ mad_fixed64lo_t __lo; \
+ MAD_F_MLX(__hi, __lo, (x), (y)); \
+ mad_f_scale64(__hi, __lo); \
+ })
+# endif
+
+# if !defined(MAD_F_MLA)
+# define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y)))
+# define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y)))
+# define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
+# endif
+
+# if !defined(MAD_F_ML0)
+# define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y))
+# endif
+
+# if !defined(MAD_F_MLZ)
+# define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo))
+# endif
+
+# if !defined(mad_f_scale64)
+# if defined(OPT_ACCURACY)
+# define mad_f_scale64(hi, lo) \
+ ((((mad_fixed_t) \
+ (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \
+ ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1)
+# else
+# define mad_f_scale64(hi, lo) \
+ ((mad_fixed_t) \
+ (((hi) << (32 - MAD_F_SCALEBITS)) | \
+ ((lo) >> MAD_F_SCALEBITS)))
+# endif
+# define MAD_F_SCALEBITS MAD_F_FRACBITS
+# endif
+
+/* miscellaneous C routines */
+
+mad_fixed_t mad_f_abs(mad_fixed_t);
+
+# endif
+
+/* Id: bit.h,v 1.7 2001/04/05 04:57:11 rob Exp */
+
+# ifndef LIBMAD_BIT_H
+# define LIBMAD_BIT_H
+
+struct mad_bitptr {
+ unsigned char const *byte;
+ unsigned short cache;
+ unsigned short left;
+};
+
+void mad_bit_init(struct mad_bitptr *, unsigned char const *);
+
+# define mad_bit_finish(bitptr) /* nothing */
+
+unsigned int mad_bit_length(struct mad_bitptr const *,
+ struct mad_bitptr const *);
+
+# define mad_bit_bitsleft(bitptr) ((bitptr)->left)
+unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *);
+
+void mad_bit_skip(struct mad_bitptr *, unsigned int);
+unsigned long mad_bit_read(struct mad_bitptr *, unsigned int);
+void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long);
+
+unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short);
+
+# endif
+
+/* Id: timer.h,v 1.10 2001/04/05 04:57:11 rob Exp */
+
+# ifndef LIBMAD_TIMER_H
+# define LIBMAD_TIMER_H
+
+typedef struct {
+ signed long seconds; /* whole seconds */
+ unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */
+} mad_timer_t;
+
+extern mad_timer_t const mad_timer_zero;
+
+# define MAD_TIMER_RESOLUTION 352800000UL
+
+enum mad_units {
+ MAD_UNITS_HOURS = -2,
+ MAD_UNITS_MINUTES = -1,
+ MAD_UNITS_SECONDS = 0,
+
+ /* metric units */
+
+ MAD_UNITS_DECISECONDS = 10,
+ MAD_UNITS_CENTISECONDS = 100,
+ MAD_UNITS_MILLISECONDS = 1000,
+
+ /* audio sample units */
+
+ MAD_UNITS_8000_HZ = 8000,
+ MAD_UNITS_11025_HZ = 11025,
+ MAD_UNITS_12000_HZ = 12000,
+
+ MAD_UNITS_16000_HZ = 16000,
+ MAD_UNITS_22050_HZ = 22050,
+ MAD_UNITS_24000_HZ = 24000,
+
+ MAD_UNITS_32000_HZ = 32000,
+ MAD_UNITS_44100_HZ = 44100,
+ MAD_UNITS_48000_HZ = 48000,
+
+ /* video frame/field units */
+
+ MAD_UNITS_24_FPS = 24,
+ MAD_UNITS_25_FPS = 25,
+ MAD_UNITS_30_FPS = 30,
+ MAD_UNITS_48_FPS = 48,
+ MAD_UNITS_50_FPS = 50,
+ MAD_UNITS_60_FPS = 60,
+
+ /* CD audio frames */
+
+ MAD_UNITS_75_FPS = 75,
+
+ /* video drop-frame units */
+
+ MAD_UNITS_23_976_FPS = -24,
+ MAD_UNITS_24_975_FPS = -25,
+ MAD_UNITS_29_97_FPS = -30,
+ MAD_UNITS_47_952_FPS = -48,
+ MAD_UNITS_49_95_FPS = -50,
+ MAD_UNITS_59_94_FPS = -60
+};
+
+# define mad_timer_reset(timer) (*(timer) = mad_timer_zero)
+
+int mad_timer_compare(mad_timer_t, mad_timer_t);
+
+# define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero)
+
+void mad_timer_negate(mad_timer_t *);
+mad_timer_t mad_timer_abs(mad_timer_t);
+
+void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long);
+void mad_timer_add(mad_timer_t *, mad_timer_t);
+void mad_timer_multiply(mad_timer_t *, signed long);
+
+signed long mad_timer_count(mad_timer_t, enum mad_units);
+unsigned long mad_timer_fraction(mad_timer_t, unsigned long);
+void mad_timer_string(mad_timer_t, char *, char const *,
+ enum mad_units, enum mad_units, unsigned long);
+
+# endif
+
+/* Id: stream.h,v 1.12 2001/04/10 05:18:21 rob Exp */
+
+# ifndef LIBMAD_STREAM_H
+# define LIBMAD_STREAM_H
+
+# define MAD_BUFFER_GUARD 8
+# define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD)
+
+enum mad_error {
+ MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */
+ MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */
+
+ MAD_ERROR_NOMEM = 0x0031, /* not enough memory */
+
+ MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */
+ MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */
+ MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */
+ MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */
+ MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */
+
+ MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */
+ MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */
+ MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */
+ MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */
+ MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */
+ MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */
+ MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */
+ MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */
+ MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */
+ MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */
+ MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */
+ MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */
+};
+
+# define MAD_RECOVERABLE(error) ((error) & 0xff00)
+
+struct mad_stream {
+ unsigned char const *buffer; /* input bitstream buffer */
+ unsigned char const *bufend; /* end of buffer */
+ unsigned long skiplen; /* bytes to skip before next frame */
+
+ int sync; /* stream sync found */
+ unsigned long freerate; /* free bitrate (fixed) */
+
+ unsigned char const *this_frame; /* start of current frame */
+ unsigned char const *next_frame; /* start of next frame */
+ struct mad_bitptr ptr; /* current processing bit pointer */
+
+ struct mad_bitptr anc_ptr; /* ancillary bits pointer */
+ unsigned int anc_bitlen; /* number of ancillary bits */
+
+ unsigned char (*main_data)[MAD_BUFFER_MDLEN];
+ /* Layer III main_data() */
+ unsigned int md_len; /* bytes in main_data */
+
+ int options; /* decoding options (see below) */
+ enum mad_error error; /* error code (see above) */
+};
+
+enum {
+ MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */
+ MAD_OPTION_HALFSAMPLERATE = 0x0002, /* generate PCM at 1/2 sample rate */
+# if 0 /* not yet implemented */
+ MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */
+ MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */
+ MAD_OPTION_SINGLECHANNEL = 0x0030, /* combine channels */
+# endif
+};
+
+void mad_stream_init(struct mad_stream *);
+void mad_stream_finish(struct mad_stream *);
+
+# define mad_stream_options(stream, opts) ((stream)->options = (opts))
+
+void mad_stream_buffer(struct mad_stream *,
+ unsigned char const *, unsigned long);
+void mad_stream_skip(struct mad_stream *, unsigned long);
+
+int mad_stream_sync(struct mad_stream *);
+
+# endif
+
+/* Id: frame.h,v 1.13 2001/04/05 04:57:11 rob Exp */
+
+# ifndef LIBMAD_FRAME_H
+# define LIBMAD_FRAME_H
+
+enum mad_layer {
+ MAD_LAYER_I = 1, /* Layer I */
+ MAD_LAYER_II = 2, /* Layer II */
+ MAD_LAYER_III = 3 /* Layer III */
+};
+
+enum mad_mode {
+ MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */
+ MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */
+ MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */
+ MAD_MODE_STEREO = 3 /* normal LR stereo */
+};
+
+enum mad_emphasis {
+ MAD_EMPHASIS_NONE = 0, /* no emphasis */
+ MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */
+ MAD_EMPHASIS_CCITT_J_17 = 3 /* CCITT J.17 emphasis */
+};
+
+struct mad_frame {
+ struct mad_header {
+ enum mad_layer layer; /* audio layer (1, 2, or 3) */
+ enum mad_mode mode; /* channel mode (see above) */
+ int mode_extension; /* additional mode info */
+ enum mad_emphasis emphasis; /* de-emphasis to use (see above) */
+
+ unsigned long bitrate; /* stream bitrate (bps) */
+ unsigned int samplerate; /* sampling frequency (Hz) */
+
+ unsigned short crc_check; /* frame CRC accumulator */
+ unsigned short crc_target; /* final target CRC checksum */
+
+ int flags; /* flags (see below) */
+ int private_bits; /* private bits (see below) */
+
+ mad_timer_t duration; /* audio playing time of frame */
+ } header;
+
+ int options; /* decoding options (from stream) */
+
+ mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */
+ mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */
+};
+
+# define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1)
+# define MAD_NSBSAMPLES(header) \
+ ((header)->layer == MAD_LAYER_I ? 12 : \
+ (((header)->layer == MAD_LAYER_III && \
+ ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36))
+
+enum {
+ MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */
+ MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */
+
+ MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */
+ MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */
+ MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */
+ MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */
+
+ MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */
+ MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */
+ MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */
+
+ MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */
+ MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */
+ MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */
+};
+
+enum {
+ MAD_PRIVATE_HEADER = 0x0100, /* header private bit */
+ MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */
+};
+
+void mad_header_init(struct mad_header *);
+
+# define mad_header_finish(header) /* nothing */
+
+int mad_header_decode(struct mad_header *, struct mad_stream *);
+
+void mad_frame_init(struct mad_frame *);
+void mad_frame_finish(struct mad_frame *);
+
+int mad_frame_decode(struct mad_frame *, struct mad_stream *);
+
+void mad_frame_mute(struct mad_frame *);
+
+# endif
+
+/* Id: synth.h,v 1.8 2001/04/05 04:57:11 rob Exp */
+
+# ifndef LIBMAD_SYNTH_H
+# define LIBMAD_SYNTH_H
+
+struct mad_synth {
+ mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */
+ /* [ch][eo][peo][s][v] */
+
+ unsigned int phase; /* current processing phase */
+
+ struct mad_pcm {
+ unsigned int samplerate; /* sampling frequency (Hz) */
+ unsigned short channels; /* number of channels */
+ unsigned short length; /* number of samples per channel */
+ mad_fixed_t samples[2][1152]; /* PCM output samples */
+ } pcm;
+};
+
+void mad_synth_init(struct mad_synth *);
+
+# define mad_synth_finish(synth) /* nothing */
+
+void mad_synth_mute(struct mad_synth *);
+
+void mad_synth_frame(struct mad_synth *, struct mad_frame const *);
+
+# endif
+
+/* Id: decoder.h,v 1.9 2001/04/05 04:57:11 rob Exp */
+
+# ifndef LIBMAD_DECODER_H
+# define LIBMAD_DECODER_H
+
+enum mad_decoder_mode {
+ MAD_DECODER_MODE_SYNC = 0,
+ MAD_DECODER_MODE_ASYNC
+};
+
+enum mad_flow {
+ MAD_FLOW_CONTINUE = 0x0000,
+ MAD_FLOW_STOP = 0x0010,
+ MAD_FLOW_BREAK = 0x0011,
+ MAD_FLOW_IGNORE = 0x0020
+};
+
+struct mad_decoder {
+ enum mad_decoder_mode mode;
+
+ int options;
+
+ struct {
+ long pid;
+ int in;
+ int out;
+ } async;
+
+ struct {
+ struct mad_stream stream;
+ struct mad_frame frame;
+ struct mad_synth synth;
+ } *sync;
+
+ void *cb_data;
+
+ enum mad_flow (*input_func)(void *, struct mad_stream *);
+ enum mad_flow (*header_func)(void *, struct mad_header const *);
+ enum mad_flow (*filter_func)(void *, struct mad_frame *);
+ enum mad_flow (*output_func)(void *,
+ struct mad_header const *, struct mad_pcm *);
+ enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
+ enum mad_flow (*message_func)(void *, void *, unsigned int *);
+};
+
+void mad_decoder_init(struct mad_decoder *, void *,
+ enum mad_flow (*)(void *, struct mad_stream *),
+ enum mad_flow (*)(void *, struct mad_header const *),
+ enum mad_flow (*)(void *, struct mad_frame *),
+ enum mad_flow (*)(void *,
+ struct mad_header const *,
+ struct mad_pcm *),
+ enum mad_flow (*)(void *,
+ struct mad_stream *,
+ struct mad_frame *),
+ enum mad_flow (*)(void *, void *, unsigned int *));
+int mad_decoder_finish(struct mad_decoder *);
+
+# define mad_decoder_options(decoder, opts) ((decoder)->options = (opts))
+
+int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode);
+int mad_decoder_message(struct mad_decoder *, void *, unsigned int *);
+
+# endif
+
diff --git a/core/multimedia/opieplayer/libmad/qc_table.dat b/core/multimedia/opieplayer/libmad/qc_table.dat
new file mode 100644
index 0000000..92b7f38
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/qc_table.dat
@@ -0,0 +1,77 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+/*
+ * These are the Layer II classes of quantization.
+ * The table is derived from Table B.4 of ISO/IEC 11172-3.
+ */
+
+ { 3, 2, 5,
+ MAD_F(0x15555555) /* 1.33333333333 => 1.33333333209, e 0.00000000124 */,
+ MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ },
+ { 5, 3, 7,
+ MAD_F(0x1999999a) /* 1.60000000000 => 1.60000000149, e -0.00000000149 */,
+ MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ },
+ { 7, 0, 3,
+ MAD_F(0x12492492) /* 1.14285714286 => 1.14285714179, e 0.00000000107 */,
+ MAD_F(0x04000000) /* 0.25000000000 => 0.25000000000, e 0.00000000000 */ },
+ { 9, 4, 10,
+ MAD_F(0x1c71c71c) /* 1.77777777777 => 1.77777777612, e 0.00000000165 */,
+ MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ },
+ { 15, 0, 4,
+ MAD_F(0x11111111) /* 1.06666666666 => 1.06666666642, e 0.00000000024 */,
+ MAD_F(0x02000000) /* 0.12500000000 => 0.12500000000, e 0.00000000000 */ },
+ { 31, 0, 5,
+ MAD_F(0x10842108) /* 1.03225806452 => 1.03225806355, e 0.00000000097 */,
+ MAD_F(0x01000000) /* 0.06250000000 => 0.06250000000, e 0.00000000000 */ },
+ { 63, 0, 6,
+ MAD_F(0x10410410) /* 1.01587301587 => 1.01587301493, e 0.00000000094 */,
+ MAD_F(0x00800000) /* 0.03125000000 => 0.03125000000, e 0.00000000000 */ },
+ { 127, 0, 7,
+ MAD_F(0x10204081) /* 1.00787401575 => 1.00787401572, e 0.00000000003 */,
+ MAD_F(0x00400000) /* 0.01562500000 => 0.01562500000, e 0.00000000000 */ },
+ { 255, 0, 8,
+ MAD_F(0x10101010) /* 1.00392156863 => 1.00392156839, e 0.00000000024 */,
+ MAD_F(0x00200000) /* 0.00781250000 => 0.00781250000, e 0.00000000000 */ },
+ { 511, 0, 9,
+ MAD_F(0x10080402) /* 1.00195694716 => 1.00195694715, e 0.00000000001 */,
+ MAD_F(0x00100000) /* 0.00390625000 => 0.00390625000, e 0.00000000000 */ },
+ { 1023, 0, 10,
+ MAD_F(0x10040100) /* 1.00097751711 => 1.00097751617, e 0.00000000094 */,
+ MAD_F(0x00080000) /* 0.00195312500 => 0.00195312500, e 0.00000000000 */ },
+ { 2047, 0, 11,
+ MAD_F(0x10020040) /* 1.00048851979 => 1.00048851967, e 0.00000000012 */,
+ MAD_F(0x00040000) /* 0.00097656250 => 0.00097656250, e 0.00000000000 */ },
+ { 4095, 0, 12,
+ MAD_F(0x10010010) /* 1.00024420024 => 1.00024420023, e 0.00000000001 */,
+ MAD_F(0x00020000) /* 0.00048828125 => 0.00048828125, e 0.00000000000 */ },
+ { 8191, 0, 13,
+ MAD_F(0x10008004) /* 1.00012208522 => 1.00012208521, e 0.00000000001 */,
+ MAD_F(0x00010000) /* 0.00024414063 => 0.00024414062, e 0.00000000000 */ },
+ { 16383, 0, 14,
+ MAD_F(0x10004001) /* 1.00006103888 => 1.00006103888, e -0.00000000000 */,
+ MAD_F(0x00008000) /* 0.00012207031 => 0.00012207031, e -0.00000000000 */ },
+ { 32767, 0, 15,
+ MAD_F(0x10002000) /* 1.00003051851 => 1.00003051758, e 0.00000000093 */,
+ MAD_F(0x00004000) /* 0.00006103516 => 0.00006103516, e 0.00000000000 */ },
+ { 65535, 0, 16,
+ MAD_F(0x10001000) /* 1.00001525902 => 1.00001525879, e 0.00000000023 */,
+ MAD_F(0x00002000) /* 0.00003051758 => 0.00003051758, e 0.00000000000 */ }
diff --git a/core/multimedia/opieplayer/libmad/qpe-libmadplugin.control b/core/multimedia/opieplayer/libmad/qpe-libmadplugin.control
new file mode 100644
index 0000000..077350c
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/qpe-libmadplugin.control
@@ -0,0 +1,9 @@
+Files: plugins/codecs/libmadplugin.so.1.0.0 plugins/codecs/libmadplugin.so.1.0 plugins/codecs/libmadplugin.so.1 plugins/codecs/libmadplugin.so
+Priority: optional
+Section: qpe/plugins
+Maintainer: John Ryland <jryland@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: MP3 file plugin using libmad
+ Plugin to play MP3 files with the mediaplayer in the Qtopia environment.
diff --git a/core/multimedia/opieplayer/libmad/rq_table.dat b/core/multimedia/opieplayer/libmad/rq_table.dat
new file mode 100644
index 0000000..b6d1634
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/rq_table.dat
@@ -0,0 +1,8747 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+/*
+ * This is the lookup table used to compute x^(4/3) for Layer III
+ * requantization. To maintain the best possible accuracy, the value is
+ * stored as a normalized mantissa with exponent. The requantization
+ * algorithm recombines these parts with appropriate scaling.
+ */
+
+ /* 0 */ { MAD_F(0x00000000) /* 0.000000000 */, 0 },
+ /* 1 */ { MAD_F(0x04000000) /* 0.250000000 */, 2 },
+ /* 2 */ { MAD_F(0x050a28be) /* 0.314980262 */, 3 },
+ /* 3 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 4 },
+ /* 4 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 4 },
+ /* 5 */ { MAD_F(0x04466275) /* 0.267183742 */, 5 },
+ /* 6 */ { MAD_F(0x05738c72) /* 0.340710111 */, 5 },
+ /* 7 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 5 },
+ /* 8 */ { MAD_F(0x04000000) /* 0.250000000 */, 6 },
+ /* 9 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 6 },
+ /* 10 */ { MAD_F(0x0562d694) /* 0.336630420 */, 6 },
+ /* 11 */ { MAD_F(0x061dae96) /* 0.382246578 */, 6 },
+ /* 12 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 6 },
+ /* 13 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 6 },
+ /* 14 */ { MAD_F(0x0437be65) /* 0.263609310 */, 7 },
+ /* 15 */ { MAD_F(0x049fc824) /* 0.289009227 */, 7 },
+
+ /* 16 */ { MAD_F(0x050a28be) /* 0.314980262 */, 7 },
+ /* 17 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 7 },
+ /* 18 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 7 },
+ /* 19 */ { MAD_F(0x06566361) /* 0.396090870 */, 7 },
+ /* 20 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 7 },
+ /* 21 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 7 },
+ /* 22 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 7 },
+ /* 23 */ { MAD_F(0x04168b05) /* 0.255503674 */, 8 },
+ /* 24 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 8 },
+ /* 25 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 8 },
+ /* 26 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 8 },
+ /* 27 */ { MAD_F(0x05100000) /* 0.316406250 */, 8 },
+ /* 28 */ { MAD_F(0x05506451) /* 0.332126919 */, 8 },
+ /* 29 */ { MAD_F(0x05918e15) /* 0.348035890 */, 8 },
+ /* 30 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 8 },
+ /* 31 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 8 },
+
+ /* 32 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 8 },
+ /* 33 */ { MAD_F(0x069d9400) /* 0.413471222 */, 8 },
+ /* 34 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 8 },
+ /* 35 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 8 },
+ /* 36 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 8 },
+ /* 37 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 8 },
+ /* 38 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 8 },
+ /* 39 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 9 },
+ /* 40 */ { MAD_F(0x04466275) /* 0.267183742 */, 9 },
+ /* 41 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 9 },
+ /* 42 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 9 },
+ /* 43 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 9 },
+ /* 44 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 9 },
+ /* 45 */ { MAD_F(0x05007b49) /* 0.312617576 */, 9 },
+ /* 46 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 9 },
+ /* 47 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 9 },
+
+ /* 48 */ { MAD_F(0x05738c72) /* 0.340710111 */, 9 },
+ /* 49 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 9 },
+ /* 50 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 9 },
+ /* 51 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 9 },
+ /* 52 */ { MAD_F(0x0610b982) /* 0.379083164 */, 9 },
+ /* 53 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 9 },
+ /* 54 */ { MAD_F(0x0660db91) /* 0.398646895 */, 9 },
+ /* 55 */ { MAD_F(0x06894c90) /* 0.408520284 */, 9 },
+ /* 56 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 9 },
+ /* 57 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 9 },
+ /* 58 */ { MAD_F(0x07041636) /* 0.438497744 */, 9 },
+ /* 59 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 9 },
+ /* 60 */ { MAD_F(0x075722ef) /* 0.458773552 */, 9 },
+ /* 61 */ { MAD_F(0x078102b8) /* 0.468996735 */, 9 },
+ /* 62 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 9 },
+ /* 63 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 9 },
+
+ /* 64 */ { MAD_F(0x04000000) /* 0.250000000 */, 10 },
+ /* 65 */ { MAD_F(0x04156381) /* 0.255221850 */, 10 },
+ /* 66 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 10 },
+ /* 67 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 10 },
+ /* 68 */ { MAD_F(0x045635cf) /* 0.271047409 */, 10 },
+ /* 69 */ { MAD_F(0x046c083e) /* 0.276375048 */, 10 },
+ /* 70 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 10 },
+ /* 71 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 10 },
+ /* 72 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 10 },
+ /* 73 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 10 },
+ /* 74 */ { MAD_F(0x04dab524) /* 0.303395408 */, 10 },
+ /* 75 */ { MAD_F(0x04f12624) /* 0.308874267 */, 10 },
+ /* 76 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 10 },
+ /* 77 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 10 },
+ /* 78 */ { MAD_F(0x053511cb) /* 0.325456423 */, 10 },
+ /* 79 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 10 },
+
+ /* 80 */ { MAD_F(0x0562d694) /* 0.336630420 */, 10 },
+ /* 81 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 10 },
+ /* 82 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 10 },
+ /* 83 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 10 },
+ /* 84 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 10 },
+ /* 85 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 10 },
+ /* 86 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 10 },
+ /* 87 */ { MAD_F(0x0606012b) /* 0.376465960 */, 10 },
+ /* 88 */ { MAD_F(0x061dae96) /* 0.382246578 */, 10 },
+ /* 89 */ { MAD_F(0x06357302) /* 0.388049134 */, 10 },
+ /* 90 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 10 },
+ /* 91 */ { MAD_F(0x0665402d) /* 0.399719406 */, 10 },
+ /* 92 */ { MAD_F(0x067d4896) /* 0.405586801 */, 10 },
+ /* 93 */ { MAD_F(0x06956753) /* 0.411475493 */, 10 },
+ /* 94 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 10 },
+ /* 95 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 10 },
+
+ /* 96 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 10 },
+ /* 97 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 10 },
+ /* 98 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 10 },
+ /* 99 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 10 },
+ /* 100 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 10 },
+ /* 101 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 10 },
+ /* 102 */ { MAD_F(0x07724f64) /* 0.465407744 */, 10 },
+ /* 103 */ { MAD_F(0x078b4514) /* 0.471501425 */, 10 },
+ /* 104 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 10 },
+ /* 105 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 10 },
+ /* 106 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 10 },
+ /* 107 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 10 },
+ /* 108 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 11 },
+ /* 109 */ { MAD_F(0x04115aca) /* 0.254236974 */, 11 },
+ /* 110 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 11 },
+ /* 111 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 11 },
+
+ /* 112 */ { MAD_F(0x0437be65) /* 0.263609310 */, 11 },
+ /* 113 */ { MAD_F(0x04449dee) /* 0.266752177 */, 11 },
+ /* 114 */ { MAD_F(0x04518733) /* 0.269904329 */, 11 },
+ /* 115 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 11 },
+ /* 116 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 11 },
+ /* 117 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 11 },
+ /* 118 */ { MAD_F(0x04858c83) /* 0.282604707 */, 11 },
+ /* 119 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 11 },
+ /* 120 */ { MAD_F(0x049fc824) /* 0.289009227 */, 11 },
+ /* 121 */ { MAD_F(0x04acf402) /* 0.292224893 */, 11 },
+ /* 122 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 11 },
+ /* 123 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 11 },
+ /* 124 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 11 },
+ /* 125 */ { MAD_F(0x04e20000) /* 0.305175781 */, 11 },
+ /* 126 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 11 },
+ /* 127 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 11 },
+
+ /* 128 */ { MAD_F(0x050a28be) /* 0.314980262 */, 11 },
+ /* 129 */ { MAD_F(0x05179da4) /* 0.318265572 */, 11 },
+ /* 130 */ { MAD_F(0x05251b73) /* 0.321559381 */, 11 },
+ /* 131 */ { MAD_F(0x0532a220) /* 0.324861647 */, 11 },
+ /* 132 */ { MAD_F(0x054031a0) /* 0.328172327 */, 11 },
+ /* 133 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 11 },
+ /* 134 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 11 },
+ /* 135 */ { MAD_F(0x0569149c) /* 0.338154423 */, 11 },
+ /* 136 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 11 },
+ /* 137 */ { MAD_F(0x058481e9) /* 0.344850455 */, 11 },
+ /* 138 */ { MAD_F(0x0592456d) /* 0.348210741 */, 11 },
+ /* 139 */ { MAD_F(0x05a01176) /* 0.351579152 */, 11 },
+ /* 140 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 11 },
+ /* 141 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 11 },
+ /* 142 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 11 },
+ /* 143 */ { MAD_F(0x05d79601) /* 0.365133291 */, 11 },
+
+ /* 144 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 11 },
+ /* 145 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 11 },
+ /* 146 */ { MAD_F(0x060190ee) /* 0.375382356 */, 11 },
+ /* 147 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 11 },
+ /* 148 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 11 },
+ /* 149 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 11 },
+ /* 150 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 11 },
+ /* 151 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 11 },
+ /* 152 */ { MAD_F(0x06566361) /* 0.396090870 */, 11 },
+ /* 153 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 11 },
+ /* 154 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 11 },
+ /* 155 */ { MAD_F(0x068138f3) /* 0.406548452 */, 11 },
+ /* 156 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 11 },
+ /* 157 */ { MAD_F(0x069deed1) /* 0.413557833 */, 11 },
+ /* 158 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 11 },
+ /* 159 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 11 },
+
+ /* 160 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 11 },
+ /* 161 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 11 },
+ /* 162 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 11 },
+ /* 163 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 11 },
+ /* 164 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 11 },
+ /* 165 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 11 },
+ /* 166 */ { MAD_F(0x0720a087) /* 0.445465593 */, 11 },
+ /* 167 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 11 },
+ /* 168 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 11 },
+ /* 169 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 11 },
+ /* 170 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 11 },
+ /* 171 */ { MAD_F(0x076a454c) /* 0.463444993 */, 11 },
+ /* 172 */ { MAD_F(0x07791620) /* 0.467062117 */, 11 },
+ /* 173 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 11 },
+ /* 174 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 11 },
+ /* 175 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 11 },
+
+ /* 176 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 11 },
+ /* 177 */ { MAD_F(0x07c39812) /* 0.485252449 */, 11 },
+ /* 178 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 11 },
+ /* 179 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 11 },
+ /* 180 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 11 },
+ /* 181 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 11 },
+ /* 182 */ { MAD_F(0x0407673f) /* 0.251807447 */, 12 },
+ /* 183 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 12 },
+ /* 184 */ { MAD_F(0x04168b05) /* 0.255503674 */, 12 },
+ /* 185 */ { MAD_F(0x041e2230) /* 0.257356825 */, 12 },
+ /* 186 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 12 },
+ /* 187 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 12 },
+ /* 188 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 12 },
+ /* 189 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 12 },
+ /* 190 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 12 },
+ /* 191 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 12 },
+
+ /* 192 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 12 },
+ /* 193 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 12 },
+ /* 194 */ { MAD_F(0x04630eed) /* 0.274184158 */, 12 },
+ /* 195 */ { MAD_F(0x046ac896) /* 0.276070203 */, 12 },
+ /* 196 */ { MAD_F(0x047285a2) /* 0.277959474 */, 12 },
+ /* 197 */ { MAD_F(0x047a460c) /* 0.279851960 */, 12 },
+ /* 198 */ { MAD_F(0x048209d3) /* 0.281747652 */, 12 },
+ /* 199 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 12 },
+ /* 200 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 12 },
+ /* 201 */ { MAD_F(0x04996935) /* 0.287453849 */, 12 },
+ /* 202 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 12 },
+ /* 203 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 12 },
+ /* 204 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 12 },
+ /* 205 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 12 },
+ /* 206 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 12 },
+ /* 207 */ { MAD_F(0x04c88135) /* 0.298951346 */, 12 },
+
+ /* 208 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 12 },
+ /* 209 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 12 },
+ /* 210 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 12 },
+ /* 211 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 12 },
+ /* 212 */ { MAD_F(0x04f01963) /* 0.308617963 */, 12 },
+ /* 213 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 12 },
+ /* 214 */ { MAD_F(0x05000655) /* 0.312506041 */, 12 },
+ /* 215 */ { MAD_F(0x05080195) /* 0.314454634 */, 12 },
+ /* 216 */ { MAD_F(0x05100000) /* 0.316406250 */, 12 },
+ /* 217 */ { MAD_F(0x05180194) /* 0.318360880 */, 12 },
+ /* 218 */ { MAD_F(0x0520064f) /* 0.320318516 */, 12 },
+ /* 219 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 12 },
+ /* 220 */ { MAD_F(0x0530192e) /* 0.324242764 */, 12 },
+ /* 221 */ { MAD_F(0x0538274e) /* 0.326209359 */, 12 },
+ /* 222 */ { MAD_F(0x0540388a) /* 0.328178922 */, 12 },
+ /* 223 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 12 },
+
+ /* 224 */ { MAD_F(0x05506451) /* 0.332126919 */, 12 },
+ /* 225 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 12 },
+ /* 226 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 12 },
+ /* 227 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 12 },
+ /* 228 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 12 },
+ /* 229 */ { MAD_F(0x05790793) /* 0.342048241 */, 12 },
+ /* 230 */ { MAD_F(0x05813162) /* 0.344041237 */, 12 },
+ /* 231 */ { MAD_F(0x05895e39) /* 0.346037122 */, 12 },
+ /* 232 */ { MAD_F(0x05918e15) /* 0.348035890 */, 12 },
+ /* 233 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 12 },
+ /* 234 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 12 },
+ /* 235 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 12 },
+ /* 236 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 12 },
+ /* 237 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 12 },
+ /* 238 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 12 },
+ /* 239 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 12 },
+
+ /* 240 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 12 },
+ /* 241 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 12 },
+ /* 242 */ { MAD_F(0x05e41105) /* 0.368180294 */, 12 },
+ /* 243 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 12 },
+ /* 244 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 12 },
+ /* 245 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 12 },
+ /* 246 */ { MAD_F(0x060564b1) /* 0.376316732 */, 12 },
+ /* 247 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 12 },
+ /* 248 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 12 },
+ /* 249 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 12 },
+ /* 250 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 12 },
+ /* 251 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 12 },
+ /* 252 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 12 },
+ /* 253 */ { MAD_F(0x06402666) /* 0.390661620 */, 12 },
+ /* 254 */ { MAD_F(0x064896a7) /* 0.392721798 */, 12 },
+ /* 255 */ { MAD_F(0x065109be) /* 0.394784681 */, 12 },
+
+ /* 256 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 12 },
+ /* 257 */ { MAD_F(0x0661f867) /* 0.398918536 */, 12 },
+ /* 258 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 12 },
+ /* 259 */ { MAD_F(0x0672f252) /* 0.403063128 */, 12 },
+ /* 260 */ { MAD_F(0x067b737c) /* 0.405139433 */, 12 },
+ /* 261 */ { MAD_F(0x0683f771) /* 0.407218402 */, 12 },
+ /* 262 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 12 },
+ /* 263 */ { MAD_F(0x069507b5) /* 0.411384303 */, 12 },
+ /* 264 */ { MAD_F(0x069d9400) /* 0.413471222 */, 12 },
+ /* 265 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 12 },
+ /* 266 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 12 },
+ /* 267 */ { MAD_F(0x06b74971) /* 0.419747773 */, 12 },
+ /* 268 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 12 },
+ /* 269 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 12 },
+ /* 270 */ { MAD_F(0x06d11794) /* 0.426047876 */, 12 },
+ /* 271 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 12 },
+
+ /* 272 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 12 },
+ /* 273 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 12 },
+ /* 274 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 12 },
+ /* 275 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 12 },
+ /* 276 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 12 },
+ /* 277 */ { MAD_F(0x070dacea) /* 0.440838732 */, 12 },
+ /* 278 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 12 },
+ /* 279 */ { MAD_F(0x071f1459) /* 0.445087765 */, 12 },
+ /* 280 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 12 },
+ /* 281 */ { MAD_F(0x07308671) /* 0.449346964 */, 12 },
+ /* 282 */ { MAD_F(0x07394378) /* 0.451480360 */, 12 },
+ /* 283 */ { MAD_F(0x07420325) /* 0.453616280 */, 12 },
+ /* 284 */ { MAD_F(0x074ac575) /* 0.455754717 */, 12 },
+ /* 285 */ { MAD_F(0x07538a67) /* 0.457895665 */, 12 },
+ /* 286 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 12 },
+ /* 287 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 12 },
+
+ /* 288 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 12 },
+ /* 289 */ { MAD_F(0x0776b867) /* 0.466484455 */, 12 },
+ /* 290 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 12 },
+ /* 291 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 12 },
+ /* 292 */ { MAD_F(0x07913641) /* 0.472952132 */, 12 },
+ /* 293 */ { MAD_F(0x079a100c) /* 0.475112962 */, 12 },
+ /* 294 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 12 },
+ /* 295 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 12 },
+ /* 296 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 12 },
+ /* 297 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 12 },
+ /* 298 */ { MAD_F(0x07c67798) /* 0.485953899 */, 12 },
+ /* 299 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 12 },
+ /* 300 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 12 },
+ /* 301 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 12 },
+ /* 302 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 12 },
+ /* 303 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 12 },
+
+ /* 304 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 12 },
+ /* 305 */ { MAD_F(0x0402868e) /* 0.250616605 */, 13 },
+ /* 306 */ { MAD_F(0x040703ff) /* 0.251712795 */, 13 },
+ /* 307 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 13 },
+ /* 308 */ { MAD_F(0x041002a1) /* 0.253908756 */, 13 },
+ /* 309 */ { MAD_F(0x041483d1) /* 0.255008523 */, 13 },
+ /* 310 */ { MAD_F(0x04190640) /* 0.256109476 */, 13 },
+ /* 311 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 13 },
+ /* 312 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 13 },
+ /* 313 */ { MAD_F(0x042694fe) /* 0.259419433 */, 13 },
+ /* 314 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 13 },
+ /* 315 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 13 },
+ /* 316 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 13 },
+ /* 317 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 13 },
+ /* 318 */ { MAD_F(0x043d4635) /* 0.264959533 */, 13 },
+ /* 319 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 13 },
+
+ /* 320 */ { MAD_F(0x04466275) /* 0.267183742 */, 13 },
+ /* 321 */ { MAD_F(0x044af269) /* 0.268297587 */, 13 },
+ /* 322 */ { MAD_F(0x044f8393) /* 0.269412589 */, 13 },
+ /* 323 */ { MAD_F(0x045415f3) /* 0.270528746 */, 13 },
+ /* 324 */ { MAD_F(0x0458a989) /* 0.271646056 */, 13 },
+ /* 325 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 13 },
+ /* 326 */ { MAD_F(0x0461d451) /* 0.273884123 */, 13 },
+ /* 327 */ { MAD_F(0x04666b83) /* 0.275004875 */, 13 },
+ /* 328 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 13 },
+ /* 329 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 13 },
+ /* 330 */ { MAD_F(0x04743847) /* 0.278373983 */, 13 },
+ /* 331 */ { MAD_F(0x0478d440) /* 0.279499294 */, 13 },
+ /* 332 */ { MAD_F(0x047d716a) /* 0.280625739 */, 13 },
+ /* 333 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 13 },
+ /* 334 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 13 },
+ /* 335 */ { MAD_F(0x048b5003) /* 0.284011853 */, 13 },
+
+ /* 336 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 13 },
+ /* 337 */ { MAD_F(0x049494fb) /* 0.286274891 */, 13 },
+ /* 338 */ { MAD_F(0x0499393a) /* 0.287408091 */, 13 },
+ /* 339 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 13 },
+ /* 340 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 13 },
+ /* 341 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 13 },
+ /* 342 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 13 },
+ /* 343 */ { MAD_F(0x04b08000) /* 0.293090820 */, 13 },
+ /* 344 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 13 },
+ /* 345 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 13 },
+ /* 346 */ { MAD_F(0x04be8537) /* 0.296513762 */, 13 },
+ /* 347 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 13 },
+ /* 348 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 13 },
+ /* 349 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 13 },
+ /* 350 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 13 },
+ /* 351 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 13 },
+
+ /* 352 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 13 },
+ /* 353 */ { MAD_F(0x04df6458) /* 0.304539056 */, 13 },
+ /* 354 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 13 },
+ /* 355 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 13 },
+ /* 356 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 13 },
+ /* 357 */ { MAD_F(0x04f24618) /* 0.309148880 */, 13 },
+ /* 358 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 13 },
+ /* 359 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 13 },
+ /* 360 */ { MAD_F(0x05007b49) /* 0.312617576 */, 13 },
+ /* 361 */ { MAD_F(0x050539ef) /* 0.313775954 */, 13 },
+ /* 362 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 13 },
+ /* 363 */ { MAD_F(0x050eba98) /* 0.316095920 */, 13 },
+ /* 364 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 13 },
+ /* 365 */ { MAD_F(0x05183fba) /* 0.318420150 */, 13 },
+ /* 366 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 13 },
+ /* 367 */ { MAD_F(0x0521c950) /* 0.320748629 */, 13 },
+
+ /* 368 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 13 },
+ /* 369 */ { MAD_F(0x052b5757) /* 0.323081342 */, 13 },
+ /* 370 */ { MAD_F(0x05302003) /* 0.324249281 */, 13 },
+ /* 371 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 13 },
+ /* 372 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 13 },
+ /* 373 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 13 },
+ /* 374 */ { MAD_F(0x05434db9) /* 0.328931546 */, 13 },
+ /* 375 */ { MAD_F(0x05481be5) /* 0.330104730 */, 13 },
+ /* 376 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 13 },
+ /* 377 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 13 },
+ /* 378 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 13 },
+ /* 379 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 13 },
+ /* 380 */ { MAD_F(0x05603321) /* 0.335986261 */, 13 },
+ /* 381 */ { MAD_F(0x056507d6) /* 0.337165677 */, 13 },
+ /* 382 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 13 },
+ /* 383 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 13 },
+
+ /* 384 */ { MAD_F(0x05738c72) /* 0.340710111 */, 13 },
+ /* 385 */ { MAD_F(0x05786578) /* 0.341893646 */, 13 },
+ /* 386 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 13 },
+ /* 387 */ { MAD_F(0x05821abf) /* 0.344263788 */, 13 },
+ /* 388 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 13 },
+ /* 389 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 13 },
+ /* 390 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 13 },
+ /* 391 */ { MAD_F(0x05959222) /* 0.349016318 */, 13 },
+ /* 392 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 13 },
+ /* 393 */ { MAD_F(0x059f5438) /* 0.351398678 */, 13 },
+ /* 394 */ { MAD_F(0x05a436da) /* 0.352591376 */, 13 },
+ /* 395 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 13 },
+ /* 396 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 13 },
+ /* 397 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 13 },
+ /* 398 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 13 },
+ /* 399 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 13 },
+
+ /* 400 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 13 },
+ /* 401 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 13 },
+ /* 402 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 13 },
+ /* 403 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 13 },
+ /* 404 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 13 },
+ /* 405 */ { MAD_F(0x05da394d) /* 0.365777304 */, 13 },
+ /* 406 */ { MAD_F(0x05df2885) /* 0.366982004 */, 13 },
+ /* 407 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 13 },
+ /* 408 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 13 },
+ /* 409 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 13 },
+ /* 410 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 13 },
+ /* 411 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 13 },
+ /* 412 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 13 },
+ /* 413 */ { MAD_F(0x0601d004) /* 0.375442522 */, 13 },
+ /* 414 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 13 },
+ /* 415 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 13 },
+
+ /* 416 */ { MAD_F(0x0610b982) /* 0.379083164 */, 13 },
+ /* 417 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 13 },
+ /* 418 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 13 },
+ /* 419 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 13 },
+ /* 420 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 13 },
+ /* 421 */ { MAD_F(0x0629a863) /* 0.385170352 */, 13 },
+ /* 422 */ { MAD_F(0x062ea802) /* 0.386390694 */, 13 },
+ /* 423 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 13 },
+ /* 424 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 13 },
+ /* 425 */ { MAD_F(0x063dacee) /* 0.390057497 */, 13 },
+ /* 426 */ { MAD_F(0x0642b096) /* 0.391281687 */, 13 },
+ /* 427 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 13 },
+ /* 428 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 13 },
+ /* 429 */ { MAD_F(0x0651c193) /* 0.394959999 */, 13 },
+ /* 430 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 13 },
+ /* 431 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 13 },
+
+ /* 432 */ { MAD_F(0x0660db91) /* 0.398646895 */, 13 },
+ /* 433 */ { MAD_F(0x0665e639) /* 0.399877761 */, 13 },
+ /* 434 */ { MAD_F(0x066af1df) /* 0.401109575 */, 13 },
+ /* 435 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 13 },
+ /* 436 */ { MAD_F(0x06750c26) /* 0.403576041 */, 13 },
+ /* 437 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 13 },
+ /* 438 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 13 },
+ /* 439 */ { MAD_F(0x06843afb) /* 0.407282813 */, 13 },
+ /* 440 */ { MAD_F(0x06894c90) /* 0.408520284 */, 13 },
+ /* 441 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 13 },
+ /* 442 */ { MAD_F(0x069372ae) /* 0.410998038 */, 13 },
+ /* 443 */ { MAD_F(0x06988735) /* 0.412238319 */, 13 },
+ /* 444 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 13 },
+ /* 445 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 13 },
+ /* 446 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 13 },
+ /* 447 */ { MAD_F(0x06ace318) /* 0.417208762 */, 13 },
+
+ /* 448 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 13 },
+ /* 449 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 13 },
+ /* 450 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 13 },
+ /* 451 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 13 },
+ /* 452 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 13 },
+ /* 453 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 13 },
+ /* 454 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 13 },
+ /* 455 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 13 },
+ /* 456 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 13 },
+ /* 457 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 13 },
+ /* 458 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 13 },
+ /* 459 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 13 },
+ /* 460 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 13 },
+ /* 461 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 13 },
+ /* 462 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 13 },
+ /* 463 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 13 },
+
+ /* 464 */ { MAD_F(0x07041636) /* 0.438497744 */, 13 },
+ /* 465 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 13 },
+ /* 466 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 13 },
+ /* 467 */ { MAD_F(0x07139641) /* 0.442281965 */, 13 },
+ /* 468 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 13 },
+ /* 469 */ { MAD_F(0x071df058) /* 0.444809288 */, 13 },
+ /* 470 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 13 },
+ /* 471 */ { MAD_F(0x07284e34) /* 0.447340205 */, 13 },
+ /* 472 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 13 },
+ /* 473 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 13 },
+ /* 474 */ { MAD_F(0x0737e209) /* 0.451143300 */, 13 },
+ /* 475 */ { MAD_F(0x073d1530) /* 0.452412785 */, 13 },
+ /* 476 */ { MAD_F(0x07424946) /* 0.453683161 */, 13 },
+ /* 477 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 13 },
+ /* 478 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 13 },
+ /* 479 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 13 },
+
+ /* 480 */ { MAD_F(0x075722ef) /* 0.458773552 */, 13 },
+ /* 481 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 13 },
+ /* 482 */ { MAD_F(0x07619557) /* 0.461324062 */, 13 },
+ /* 483 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 13 },
+ /* 484 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 13 },
+ /* 485 */ { MAD_F(0x077147e2) /* 0.465156443 */, 13 },
+ /* 486 */ { MAD_F(0x0776853e) /* 0.466435663 */, 13 },
+ /* 487 */ { MAD_F(0x077bc385) /* 0.467715761 */, 13 },
+ /* 488 */ { MAD_F(0x078102b8) /* 0.468996735 */, 13 },
+ /* 489 */ { MAD_F(0x078642d6) /* 0.470278584 */, 13 },
+ /* 490 */ { MAD_F(0x078b83de) /* 0.471561307 */, 13 },
+ /* 491 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 13 },
+ /* 492 */ { MAD_F(0x079608ae) /* 0.474129372 */, 13 },
+ /* 493 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 13 },
+ /* 494 */ { MAD_F(0x07a09124) /* 0.476700918 */, 13 },
+ /* 495 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 13 },
+
+ /* 496 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 13 },
+ /* 497 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 13 },
+ /* 498 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 13 },
+ /* 499 */ { MAD_F(0x07baf635) /* 0.483144957 */, 13 },
+ /* 500 */ { MAD_F(0x07c04056) /* 0.484436356 */, 13 },
+ /* 501 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 13 },
+ /* 502 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 13 },
+ /* 503 */ { MAD_F(0x07d02424) /* 0.488315717 */, 13 },
+ /* 504 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 13 },
+ /* 505 */ { MAD_F(0x07dac083) /* 0.490906249 */, 13 },
+ /* 506 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 13 },
+ /* 507 */ { MAD_F(0x07e56078) /* 0.493500203 */, 13 },
+ /* 508 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 13 },
+ /* 509 */ { MAD_F(0x07f00401) /* 0.496097570 */, 13 },
+ /* 510 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 13 },
+ /* 511 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 13 },
+
+ /* 512 */ { MAD_F(0x04000000) /* 0.250000000 */, 14 },
+ /* 513 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 14 },
+ /* 514 */ { MAD_F(0x04055638) /* 0.251302930 */, 14 },
+ /* 515 */ { MAD_F(0x040801ff) /* 0.251955030 */, 14 },
+ /* 516 */ { MAD_F(0x040aae37) /* 0.252607552 */, 14 },
+ /* 517 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 14 },
+ /* 518 */ { MAD_F(0x041007fa) /* 0.253913860 */, 14 },
+ /* 519 */ { MAD_F(0x0412b586) /* 0.254567645 */, 14 },
+ /* 520 */ { MAD_F(0x04156381) /* 0.255221850 */, 14 },
+ /* 521 */ { MAD_F(0x041811ee) /* 0.255876475 */, 14 },
+ /* 522 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 14 },
+ /* 523 */ { MAD_F(0x041d7018) /* 0.257186980 */, 14 },
+ /* 524 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 14 },
+ /* 525 */ { MAD_F(0x0422d003) /* 0.258499157 */, 14 },
+ /* 526 */ { MAD_F(0x042580a0) /* 0.259155872 */, 14 },
+ /* 527 */ { MAD_F(0x042831ad) /* 0.259813002 */, 14 },
+
+ /* 528 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 14 },
+ /* 529 */ { MAD_F(0x042d9516) /* 0.261128510 */, 14 },
+ /* 530 */ { MAD_F(0x04304772) /* 0.261786886 */, 14 },
+ /* 531 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 14 },
+ /* 532 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 14 },
+ /* 533 */ { MAD_F(0x0438611f) /* 0.263764497 */, 14 },
+ /* 534 */ { MAD_F(0x043b1536) /* 0.264424527 */, 14 },
+ /* 535 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 14 },
+ /* 536 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 14 },
+ /* 537 */ { MAD_F(0x04433414) /* 0.266407088 */, 14 },
+ /* 538 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 14 },
+ /* 539 */ { MAD_F(0x0448a024) /* 0.267730848 */, 14 },
+ /* 540 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 14 },
+ /* 541 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 14 },
+ /* 542 */ { MAD_F(0x0450c575) /* 0.269719560 */, 14 },
+ /* 543 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 14 },
+
+ /* 544 */ { MAD_F(0x045635cf) /* 0.271047409 */, 14 },
+ /* 545 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 14 },
+ /* 546 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 14 },
+ /* 547 */ { MAD_F(0x045e6188) /* 0.273042234 */, 14 },
+ /* 548 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 14 },
+ /* 549 */ { MAD_F(0x0463d625) /* 0.274374147 */, 14 },
+ /* 550 */ { MAD_F(0x04669116) /* 0.275040710 */, 14 },
+ /* 551 */ { MAD_F(0x04694c74) /* 0.275707677 */, 14 },
+ /* 552 */ { MAD_F(0x046c083e) /* 0.276375048 */, 14 },
+ /* 553 */ { MAD_F(0x046ec474) /* 0.277042822 */, 14 },
+ /* 554 */ { MAD_F(0x04718116) /* 0.277710999 */, 14 },
+ /* 555 */ { MAD_F(0x04743e25) /* 0.278379578 */, 14 },
+ /* 556 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 14 },
+ /* 557 */ { MAD_F(0x0479b984) /* 0.279717940 */, 14 },
+ /* 558 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 14 },
+ /* 559 */ { MAD_F(0x047f3693) /* 0.281057905 */, 14 },
+
+ /* 560 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 14 },
+ /* 561 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 14 },
+ /* 562 */ { MAD_F(0x0487754c) /* 0.283070849 */, 14 },
+ /* 563 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 14 },
+ /* 564 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 14 },
+ /* 565 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 14 },
+ /* 566 */ { MAD_F(0x04927972) /* 0.285760350 */, 14 },
+ /* 567 */ { MAD_F(0x04953b85) /* 0.286433717 */, 14 },
+ /* 568 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 14 },
+ /* 569 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 14 },
+ /* 570 */ { MAD_F(0x049d843e) /* 0.288456194 */, 14 },
+ /* 571 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 14 },
+ /* 572 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 14 },
+ /* 573 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 14 },
+ /* 574 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 14 },
+ /* 575 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 14 },
+
+ /* 576 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 14 },
+ /* 577 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 14 },
+ /* 578 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 14 },
+ /* 579 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 14 },
+ /* 580 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 14 },
+ /* 581 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 14 },
+ /* 582 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 14 },
+ /* 583 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 14 },
+ /* 584 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 14 },
+ /* 585 */ { MAD_F(0x04c72771) /* 0.298621598 */, 14 },
+ /* 586 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 14 },
+ /* 587 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 14 },
+ /* 588 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 14 },
+ /* 589 */ { MAD_F(0x04d25169) /* 0.301347172 */, 14 },
+ /* 590 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 14 },
+ /* 591 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 14 },
+
+ /* 592 */ { MAD_F(0x04dab524) /* 0.303395408 */, 14 },
+ /* 593 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 14 },
+ /* 594 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 14 },
+ /* 595 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 14 },
+ /* 596 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 14 },
+ /* 597 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 14 },
+ /* 598 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 14 },
+ /* 599 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 14 },
+ /* 600 */ { MAD_F(0x04f12624) /* 0.308874267 */, 14 },
+ /* 601 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 14 },
+ /* 602 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 14 },
+ /* 603 */ { MAD_F(0x04f99721) /* 0.310935143 */, 14 },
+ /* 604 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 14 },
+ /* 605 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 14 },
+ /* 606 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 14 },
+ /* 607 */ { MAD_F(0x0504de05) /* 0.313688296 */, 14 },
+
+ /* 608 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 14 },
+ /* 609 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 14 },
+ /* 610 */ { MAD_F(0x050d575b) /* 0.315757136 */, 14 },
+ /* 611 */ { MAD_F(0x05102b42) /* 0.316447504 */, 14 },
+ /* 612 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 14 },
+ /* 613 */ { MAD_F(0x0515d440) /* 0.317829370 */, 14 },
+ /* 614 */ { MAD_F(0x0518a956) /* 0.318520867 */, 14 },
+ /* 615 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 14 },
+ /* 616 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 14 },
+ /* 617 */ { MAD_F(0x05212af5) /* 0.320597609 */, 14 },
+ /* 618 */ { MAD_F(0x0524019e) /* 0.321290606 */, 14 },
+ /* 619 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 14 },
+ /* 620 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 14 },
+ /* 621 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 14 },
+ /* 622 */ { MAD_F(0x052f602c) /* 0.324066327 */, 14 },
+ /* 623 */ { MAD_F(0x053238ca) /* 0.324761189 */, 14 },
+
+ /* 624 */ { MAD_F(0x053511cb) /* 0.325456423 */, 14 },
+ /* 625 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 14 },
+ /* 626 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 14 },
+ /* 627 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 14 },
+ /* 628 */ { MAD_F(0x054079b5) /* 0.328241070 */, 14 },
+ /* 629 */ { MAD_F(0x054354a8) /* 0.328938157 */, 14 },
+ /* 630 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 14 },
+ /* 631 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 14 },
+ /* 632 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 14 },
+ /* 633 */ { MAD_F(0x054ec453) /* 0.331730198 */, 14 },
+ /* 634 */ { MAD_F(0x0551a134) /* 0.332429129 */, 14 },
+ /* 635 */ { MAD_F(0x05547e79) /* 0.333128427 */, 14 },
+ /* 636 */ { MAD_F(0x05575c20) /* 0.333828093 */, 14 },
+ /* 637 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 14 },
+ /* 638 */ { MAD_F(0x055d1896) /* 0.335228525 */, 14 },
+ /* 639 */ { MAD_F(0x055ff764) /* 0.335929290 */, 14 },
+
+ /* 640 */ { MAD_F(0x0562d694) /* 0.336630420 */, 14 },
+ /* 641 */ { MAD_F(0x0565b627) /* 0.337331916 */, 14 },
+ /* 642 */ { MAD_F(0x0568961b) /* 0.338033777 */, 14 },
+ /* 643 */ { MAD_F(0x056b7671) /* 0.338736002 */, 14 },
+ /* 644 */ { MAD_F(0x056e5729) /* 0.339438592 */, 14 },
+ /* 645 */ { MAD_F(0x05713843) /* 0.340141545 */, 14 },
+ /* 646 */ { MAD_F(0x057419be) /* 0.340844862 */, 14 },
+ /* 647 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 14 },
+ /* 648 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 14 },
+ /* 649 */ { MAD_F(0x057cc077) /* 0.342956988 */, 14 },
+ /* 650 */ { MAD_F(0x057fa378) /* 0.343661754 */, 14 },
+ /* 651 */ { MAD_F(0x058286d9) /* 0.344366882 */, 14 },
+ /* 652 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 14 },
+ /* 653 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 14 },
+ /* 654 */ { MAD_F(0x058b3342) /* 0.346484431 */, 14 },
+ /* 655 */ { MAD_F(0x058e1827) /* 0.347191002 */, 14 },
+
+ /* 656 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 14 },
+ /* 657 */ { MAD_F(0x0593e311) /* 0.348605221 */, 14 },
+ /* 658 */ { MAD_F(0x0596c917) /* 0.349312869 */, 14 },
+ /* 659 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 14 },
+ /* 660 */ { MAD_F(0x059c9643) /* 0.350729240 */, 14 },
+ /* 661 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 14 },
+ /* 662 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 14 },
+ /* 663 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 14 },
+ /* 664 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 14 },
+ /* 665 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 14 },
+ /* 666 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 14 },
+ /* 667 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 14 },
+ /* 668 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 14 },
+ /* 669 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 14 },
+ /* 670 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 14 },
+ /* 671 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 14 },
+
+ /* 672 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 14 },
+ /* 673 */ { MAD_F(0x05c27057) /* 0.359970419 */, 14 },
+ /* 674 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 14 },
+ /* 675 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 14 },
+ /* 676 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 14 },
+ /* 677 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 14 },
+ /* 678 */ { MAD_F(0x05d11001) /* 0.363540655 */, 14 },
+ /* 679 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 14 },
+ /* 680 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 14 },
+ /* 681 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 14 },
+ /* 682 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 14 },
+ /* 683 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 14 },
+ /* 684 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 14 },
+ /* 685 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 14 },
+ /* 686 */ { MAD_F(0x05e88904) /* 0.369271294 */, 14 },
+ /* 687 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 14 },
+
+ /* 688 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 14 },
+ /* 689 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 14 },
+ /* 690 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 14 },
+ /* 691 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 14 },
+ /* 692 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 14 },
+ /* 693 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 14 },
+ /* 694 */ { MAD_F(0x0600196e) /* 0.375024253 */, 14 },
+ /* 695 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 14 },
+ /* 696 */ { MAD_F(0x0606012b) /* 0.376465960 */, 14 },
+ /* 697 */ { MAD_F(0x0608f595) /* 0.377187332 */, 14 },
+ /* 698 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 14 },
+ /* 699 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 14 },
+ /* 700 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 14 },
+ /* 701 */ { MAD_F(0x0614cada) /* 0.380076266 */, 14 },
+ /* 702 */ { MAD_F(0x0617c112) /* 0.380799360 */, 14 },
+ /* 703 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 14 },
+
+ /* 704 */ { MAD_F(0x061dae96) /* 0.382246578 */, 14 },
+ /* 705 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 14 },
+ /* 706 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 14 },
+ /* 707 */ { MAD_F(0x0626958f) /* 0.384419975 */, 14 },
+ /* 708 */ { MAD_F(0x06298def) /* 0.385145124 */, 14 },
+ /* 709 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 14 },
+ /* 710 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 14 },
+ /* 711 */ { MAD_F(0x06327934) /* 0.387322621 */, 14 },
+ /* 712 */ { MAD_F(0x06357302) /* 0.388049134 */, 14 },
+ /* 713 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 14 },
+ /* 714 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 14 },
+ /* 715 */ { MAD_F(0x063e6290) /* 0.390230715 */, 14 },
+ /* 716 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 14 },
+ /* 717 */ { MAD_F(0x06445960) /* 0.391686799 */, 14 },
+ /* 718 */ { MAD_F(0x06475551) /* 0.392415349 */, 14 },
+ /* 719 */ { MAD_F(0x064a519c) /* 0.393144238 */, 14 },
+
+ /* 720 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 14 },
+ /* 721 */ { MAD_F(0x06504b44) /* 0.394603028 */, 14 },
+ /* 722 */ { MAD_F(0x0653489f) /* 0.395332930 */, 14 },
+ /* 723 */ { MAD_F(0x06564655) /* 0.396063168 */, 14 },
+ /* 724 */ { MAD_F(0x06594465) /* 0.396793743 */, 14 },
+ /* 725 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 14 },
+ /* 726 */ { MAD_F(0x065f4195) /* 0.398255903 */, 14 },
+ /* 727 */ { MAD_F(0x066240b4) /* 0.398987487 */, 14 },
+ /* 728 */ { MAD_F(0x0665402d) /* 0.399719406 */, 14 },
+ /* 729 */ { MAD_F(0x06684000) /* 0.400451660 */, 14 },
+ /* 730 */ { MAD_F(0x066b402d) /* 0.401184249 */, 14 },
+ /* 731 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 14 },
+ /* 732 */ { MAD_F(0x06714194) /* 0.402650431 */, 14 },
+ /* 733 */ { MAD_F(0x067442ce) /* 0.403384024 */, 14 },
+ /* 734 */ { MAD_F(0x06774462) /* 0.404117949 */, 14 },
+ /* 735 */ { MAD_F(0x067a464f) /* 0.404852209 */, 14 },
+
+ /* 736 */ { MAD_F(0x067d4896) /* 0.405586801 */, 14 },
+ /* 737 */ { MAD_F(0x06804b36) /* 0.406321726 */, 14 },
+ /* 738 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 14 },
+ /* 739 */ { MAD_F(0x06865181) /* 0.407792573 */, 14 },
+ /* 740 */ { MAD_F(0x0689552c) /* 0.408528495 */, 14 },
+ /* 741 */ { MAD_F(0x068c5931) /* 0.409264748 */, 14 },
+ /* 742 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 14 },
+ /* 743 */ { MAD_F(0x06926245) /* 0.410738247 */, 14 },
+ /* 744 */ { MAD_F(0x06956753) /* 0.411475493 */, 14 },
+ /* 745 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 14 },
+ /* 746 */ { MAD_F(0x069b727b) /* 0.412950976 */, 14 },
+ /* 747 */ { MAD_F(0x069e7894) /* 0.413689213 */, 14 },
+ /* 748 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 14 },
+ /* 749 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 14 },
+ /* 750 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 14 },
+ /* 751 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 14 },
+
+ /* 752 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 14 },
+ /* 753 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 14 },
+ /* 754 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 14 },
+ /* 755 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 14 },
+ /* 756 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 14 },
+ /* 757 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 14 },
+ /* 758 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 14 },
+ /* 759 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 14 },
+ /* 760 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 14 },
+ /* 761 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 14 },
+ /* 762 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 14 },
+ /* 763 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 14 },
+ /* 764 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 14 },
+ /* 765 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 14 },
+ /* 766 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 14 },
+ /* 767 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 14 },
+
+ /* 768 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 14 },
+ /* 769 */ { MAD_F(0x06e15595) /* 0.430013259 */, 14 },
+ /* 770 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 14 },
+ /* 771 */ { MAD_F(0x06e771db) /* 0.431505065 */, 14 },
+ /* 772 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 14 },
+ /* 773 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 14 },
+ /* 774 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 14 },
+ /* 775 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 14 },
+ /* 776 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 14 },
+ /* 777 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 14 },
+ /* 778 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 14 },
+ /* 779 */ { MAD_F(0x06fff073) /* 0.437485172 */, 14 },
+ /* 780 */ { MAD_F(0x070301ca) /* 0.438234130 */, 14 },
+ /* 781 */ { MAD_F(0x07061377) /* 0.438983408 */, 14 },
+ /* 782 */ { MAD_F(0x0709257a) /* 0.439733006 */, 14 },
+ /* 783 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 14 },
+
+ /* 784 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 14 },
+ /* 785 */ { MAD_F(0x07125d84) /* 0.441983717 */, 14 },
+ /* 786 */ { MAD_F(0x071570de) /* 0.442734592 */, 14 },
+ /* 787 */ { MAD_F(0x0718848d) /* 0.443485785 */, 14 },
+ /* 788 */ { MAD_F(0x071b9891) /* 0.444237296 */, 14 },
+ /* 789 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 14 },
+ /* 790 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 14 },
+ /* 791 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 14 },
+ /* 792 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 14 },
+ /* 793 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 14 },
+ /* 794 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 14 },
+ /* 795 */ { MAD_F(0x07312e01) /* 0.449506765 */, 14 },
+ /* 796 */ { MAD_F(0x073444ae) /* 0.450260813 */, 14 },
+ /* 797 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 14 },
+ /* 798 */ { MAD_F(0x073a7307) /* 0.451769856 */, 14 },
+ /* 799 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 14 },
+
+ /* 800 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 14 },
+ /* 801 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 14 },
+ /* 802 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 14 },
+ /* 803 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 14 },
+ /* 804 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 14 },
+ /* 805 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 14 },
+ /* 806 */ { MAD_F(0x0753399d) /* 0.457818618 */, 14 },
+ /* 807 */ { MAD_F(0x075653eb) /* 0.458576125 */, 14 },
+ /* 808 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 14 },
+ /* 809 */ { MAD_F(0x075c8983) /* 0.460092079 */, 14 },
+ /* 810 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 14 },
+ /* 811 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 14 },
+ /* 812 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 14 },
+ /* 813 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 14 },
+ /* 814 */ { MAD_F(0x076c1538) /* 0.463887426 */, 14 },
+ /* 815 */ { MAD_F(0x076f3224) /* 0.464647430 */, 14 },
+
+ /* 816 */ { MAD_F(0x07724f64) /* 0.465407744 */, 14 },
+ /* 817 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 14 },
+ /* 818 */ { MAD_F(0x07788add) /* 0.466929306 */, 14 },
+ /* 819 */ { MAD_F(0x077ba916) /* 0.467690552 */, 14 },
+ /* 820 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 14 },
+ /* 821 */ { MAD_F(0x0781e683) /* 0.469213973 */, 14 },
+ /* 822 */ { MAD_F(0x078505b5) /* 0.469976148 */, 14 },
+ /* 823 */ { MAD_F(0x0788253b) /* 0.470738632 */, 14 },
+ /* 824 */ { MAD_F(0x078b4514) /* 0.471501425 */, 14 },
+ /* 825 */ { MAD_F(0x078e653f) /* 0.472264527 */, 14 },
+ /* 826 */ { MAD_F(0x079185be) /* 0.473027937 */, 14 },
+ /* 827 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 14 },
+ /* 828 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 14 },
+ /* 829 */ { MAD_F(0x079ae929) /* 0.475320014 */, 14 },
+ /* 830 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 14 },
+ /* 831 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 14 },
+
+ /* 832 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 14 },
+ /* 833 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 14 },
+ /* 834 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 14 },
+ /* 835 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 14 },
+ /* 836 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 14 },
+ /* 837 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 14 },
+ /* 838 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 14 },
+ /* 839 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 14 },
+ /* 840 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 14 },
+ /* 841 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 14 },
+ /* 842 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 14 },
+ /* 843 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 14 },
+ /* 844 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 14 },
+ /* 845 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 14 },
+ /* 846 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 14 },
+ /* 847 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 14 },
+
+ /* 848 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 14 },
+ /* 849 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 14 },
+ /* 850 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 14 },
+ /* 851 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 14 },
+ /* 852 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 14 },
+ /* 853 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 14 },
+ /* 854 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 14 },
+ /* 855 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 14 },
+ /* 856 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 14 },
+ /* 857 */ { MAD_F(0x07f31405) /* 0.496845266 */, 14 },
+ /* 858 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 14 },
+ /* 859 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 14 },
+ /* 860 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 14 },
+ /* 861 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 14 },
+ /* 862 */ { MAD_F(0x04017659) /* 0.250357008 */, 15 },
+ /* 863 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 15 },
+
+ /* 864 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 15 },
+ /* 865 */ { MAD_F(0x0406393d) /* 0.251519431 */, 15 },
+ /* 866 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 15 },
+ /* 867 */ { MAD_F(0x0409669d) /* 0.252295127 */, 15 },
+ /* 868 */ { MAD_F(0x040afd89) /* 0.252683198 */, 15 },
+ /* 869 */ { MAD_F(0x040c949e) /* 0.253071419 */, 15 },
+ /* 870 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 15 },
+ /* 871 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 15 },
+ /* 872 */ { MAD_F(0x04115aca) /* 0.254236974 */, 15 },
+ /* 873 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 15 },
+ /* 874 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 15 },
+ /* 875 */ { MAD_F(0x0416225d) /* 0.255403867 */, 15 },
+ /* 876 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 15 },
+ /* 877 */ { MAD_F(0x041952dc) /* 0.256182537 */, 15 },
+ /* 878 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 15 },
+ /* 879 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 15 },
+
+ /* 880 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 15 },
+ /* 881 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 15 },
+ /* 882 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 15 },
+ /* 883 */ { MAD_F(0x0422e811) /* 0.258522097 */, 15 },
+ /* 884 */ { MAD_F(0x04248179) /* 0.258912540 */, 15 },
+ /* 885 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 15 },
+ /* 886 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 15 },
+ /* 887 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 15 },
+ /* 888 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 15 },
+ /* 889 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 15 },
+ /* 890 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 15 },
+ /* 891 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 15 },
+ /* 892 */ { MAD_F(0x0431524c) /* 0.262041376 */, 15 },
+ /* 893 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 15 },
+ /* 894 */ { MAD_F(0x0434880a) /* 0.262825051 */, 15 },
+ /* 895 */ { MAD_F(0x04362324) /* 0.263217107 */, 15 },
+
+ /* 896 */ { MAD_F(0x0437be65) /* 0.263609310 */, 15 },
+ /* 897 */ { MAD_F(0x043959cd) /* 0.264001659 */, 15 },
+ /* 898 */ { MAD_F(0x043af55d) /* 0.264394153 */, 15 },
+ /* 899 */ { MAD_F(0x043c9113) /* 0.264786794 */, 15 },
+ /* 900 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 15 },
+ /* 901 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 15 },
+ /* 902 */ { MAD_F(0x04416522) /* 0.265965588 */, 15 },
+ /* 903 */ { MAD_F(0x04430174) /* 0.266358810 */, 15 },
+ /* 904 */ { MAD_F(0x04449dee) /* 0.266752177 */, 15 },
+ /* 905 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 15 },
+ /* 906 */ { MAD_F(0x0447d756) /* 0.267539347 */, 15 },
+ /* 907 */ { MAD_F(0x04497445) /* 0.267933149 */, 15 },
+ /* 908 */ { MAD_F(0x044b115a) /* 0.268327096 */, 15 },
+ /* 909 */ { MAD_F(0x044cae96) /* 0.268721187 */, 15 },
+ /* 910 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 15 },
+ /* 911 */ { MAD_F(0x044fe983) /* 0.269509804 */, 15 },
+
+ /* 912 */ { MAD_F(0x04518733) /* 0.269904329 */, 15 },
+ /* 913 */ { MAD_F(0x0453250a) /* 0.270298998 */, 15 },
+ /* 914 */ { MAD_F(0x0454c308) /* 0.270693811 */, 15 },
+ /* 915 */ { MAD_F(0x0456612d) /* 0.271088768 */, 15 },
+ /* 916 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 15 },
+ /* 917 */ { MAD_F(0x04599dea) /* 0.271879114 */, 15 },
+ /* 918 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 15 },
+ /* 919 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 15 },
+ /* 920 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 15 },
+ /* 921 */ { MAD_F(0x04601932) /* 0.273461530 */, 15 },
+ /* 922 */ { MAD_F(0x0461b864) /* 0.273857492 */, 15 },
+ /* 923 */ { MAD_F(0x046357bd) /* 0.274253597 */, 15 },
+ /* 924 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 15 },
+ /* 925 */ { MAD_F(0x046696e2) /* 0.275046238 */, 15 },
+ /* 926 */ { MAD_F(0x046836ae) /* 0.275442772 */, 15 },
+ /* 927 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 15 },
+
+ /* 928 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 15 },
+ /* 929 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 15 },
+ /* 930 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 15 },
+ /* 931 */ { MAD_F(0x047057e8) /* 0.277427584 */, 15 },
+ /* 932 */ { MAD_F(0x0471f899) /* 0.277824973 */, 15 },
+ /* 933 */ { MAD_F(0x04739971) /* 0.278222505 */, 15 },
+ /* 934 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 15 },
+ /* 935 */ { MAD_F(0x0476db92) /* 0.279017995 */, 15 },
+ /* 936 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 15 },
+ /* 937 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 15 },
+ /* 938 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 15 },
+ /* 939 */ { MAD_F(0x047d619e) /* 0.280610675 */, 15 },
+ /* 940 */ { MAD_F(0x047f0380) /* 0.281009199 */, 15 },
+ /* 941 */ { MAD_F(0x0480a588) /* 0.281407864 */, 15 },
+ /* 942 */ { MAD_F(0x048247b6) /* 0.281806670 */, 15 },
+ /* 943 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 15 },
+
+ /* 944 */ { MAD_F(0x04858c83) /* 0.282604707 */, 15 },
+ /* 945 */ { MAD_F(0x04872f22) /* 0.283003936 */, 15 },
+ /* 946 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 15 },
+ /* 947 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 15 },
+ /* 948 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 15 },
+ /* 949 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 15 },
+ /* 950 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 15 },
+ /* 951 */ { MAD_F(0x049101f8) /* 0.285402269 */, 15 },
+ /* 952 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 15 },
+ /* 953 */ { MAD_F(0x0494496c) /* 0.286202836 */, 15 },
+ /* 954 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 15 },
+ /* 955 */ { MAD_F(0x04979177) /* 0.287003963 */, 15 },
+ /* 956 */ { MAD_F(0x049935b5) /* 0.287404737 */, 15 },
+ /* 957 */ { MAD_F(0x049ada19) /* 0.287805650 */, 15 },
+ /* 958 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 15 },
+ /* 959 */ { MAD_F(0x049e2350) /* 0.288607895 */, 15 },
+
+ /* 960 */ { MAD_F(0x049fc824) /* 0.289009227 */, 15 },
+ /* 961 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 15 },
+ /* 962 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 15 },
+ /* 963 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 15 },
+ /* 964 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 15 },
+ /* 965 */ { MAD_F(0x04a80277) /* 0.291017976 */, 15 },
+ /* 966 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 15 },
+ /* 967 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 15 },
+ /* 968 */ { MAD_F(0x04acf402) /* 0.292224893 */, 15 },
+ /* 969 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 15 },
+ /* 970 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 15 },
+ /* 971 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 15 },
+ /* 972 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 15 },
+ /* 973 */ { MAD_F(0x04b53427) /* 0.294239192 */, 15 },
+ /* 974 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 15 },
+ /* 975 */ { MAD_F(0x04b88207) /* 0.295045879 */, 15 },
+
+ /* 976 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 15 },
+ /* 977 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 15 },
+ /* 978 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 15 },
+ /* 979 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 15 },
+ /* 980 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 15 },
+ /* 981 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 15 },
+ /* 982 */ { MAD_F(0x04c41722) /* 0.297873624 */, 15 },
+ /* 983 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 15 },
+ /* 984 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 15 },
+ /* 985 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 15 },
+ /* 986 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 15 },
+ /* 987 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 15 },
+ /* 988 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 15 },
+ /* 989 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 15 },
+ /* 990 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 15 },
+ /* 991 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 15 },
+
+ /* 992 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 15 },
+ /* 993 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 15 },
+ /* 994 */ { MAD_F(0x04d80290) /* 0.302736820 */, 15 },
+ /* 995 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 15 },
+ /* 996 */ { MAD_F(0x04db5679) /* 0.303549263 */, 15 },
+ /* 997 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 15 },
+ /* 998 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 15 },
+ /* 999 */ { MAD_F(0x04e05567) /* 0.304768948 */, 15 },
+ /* 1000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 15 },
+ /* 1001 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 15 },
+ /* 1002 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 15 },
+ /* 1003 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 15 },
+ /* 1004 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 15 },
+ /* 1005 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 15 },
+ /* 1006 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 15 },
+ /* 1007 */ { MAD_F(0x04edae25) /* 0.308027406 */, 15 },
+
+ /* 1008 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 15 },
+ /* 1009 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 15 },
+ /* 1010 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 15 },
+ /* 1011 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 15 },
+ /* 1012 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 15 },
+ /* 1013 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 15 },
+ /* 1014 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 15 },
+ /* 1015 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 15 },
+ /* 1016 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 15 },
+ /* 1017 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 15 },
+ /* 1018 */ { MAD_F(0x050016f3) /* 0.312521885 */, 15 },
+ /* 1019 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 15 },
+ /* 1020 */ { MAD_F(0x050371a7) /* 0.313340809 */, 15 },
+ /* 1021 */ { MAD_F(0x05051f37) /* 0.313750472 */, 15 },
+ /* 1022 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 15 },
+ /* 1023 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 15 },
+
+ /* 1024 */ { MAD_F(0x050a28be) /* 0.314980262 */, 15 },
+ /* 1025 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 15 },
+ /* 1026 */ { MAD_F(0x050d8521) /* 0.315800790 */, 15 },
+ /* 1027 */ { MAD_F(0x050f3388) /* 0.316211255 */, 15 },
+ /* 1028 */ { MAD_F(0x0510e213) /* 0.316621852 */, 15 },
+ /* 1029 */ { MAD_F(0x051290c2) /* 0.317032582 */, 15 },
+ /* 1030 */ { MAD_F(0x05143f94) /* 0.317443446 */, 15 },
+ /* 1031 */ { MAD_F(0x0515ee8a) /* 0.317854442 */, 15 },
+ /* 1032 */ { MAD_F(0x05179da4) /* 0.318265572 */, 15 },
+ /* 1033 */ { MAD_F(0x05194ce1) /* 0.318676834 */, 15 },
+ /* 1034 */ { MAD_F(0x051afc42) /* 0.319088229 */, 15 },
+ /* 1035 */ { MAD_F(0x051cabc7) /* 0.319499756 */, 15 },
+ /* 1036 */ { MAD_F(0x051e5b6f) /* 0.319911417 */, 15 },
+ /* 1037 */ { MAD_F(0x05200b3a) /* 0.320323209 */, 15 },
+ /* 1038 */ { MAD_F(0x0521bb2a) /* 0.320735134 */, 15 },
+ /* 1039 */ { MAD_F(0x05236b3d) /* 0.321147192 */, 15 },
+
+ /* 1040 */ { MAD_F(0x05251b73) /* 0.321559381 */, 15 },
+ /* 1041 */ { MAD_F(0x0526cbcd) /* 0.321971703 */, 15 },
+ /* 1042 */ { MAD_F(0x05287c4a) /* 0.322384156 */, 15 },
+ /* 1043 */ { MAD_F(0x052a2cea) /* 0.322796742 */, 15 },
+ /* 1044 */ { MAD_F(0x052bddae) /* 0.323209460 */, 15 },
+ /* 1045 */ { MAD_F(0x052d8e96) /* 0.323622309 */, 15 },
+ /* 1046 */ { MAD_F(0x052f3fa1) /* 0.324035290 */, 15 },
+ /* 1047 */ { MAD_F(0x0530f0cf) /* 0.324448403 */, 15 },
+ /* 1048 */ { MAD_F(0x0532a220) /* 0.324861647 */, 15 },
+ /* 1049 */ { MAD_F(0x05345395) /* 0.325275023 */, 15 },
+ /* 1050 */ { MAD_F(0x0536052d) /* 0.325688530 */, 15 },
+ /* 1051 */ { MAD_F(0x0537b6e8) /* 0.326102168 */, 15 },
+ /* 1052 */ { MAD_F(0x053968c6) /* 0.326515938 */, 15 },
+ /* 1053 */ { MAD_F(0x053b1ac8) /* 0.326929839 */, 15 },
+ /* 1054 */ { MAD_F(0x053ccced) /* 0.327343870 */, 15 },
+ /* 1055 */ { MAD_F(0x053e7f35) /* 0.327758033 */, 15 },
+
+ /* 1056 */ { MAD_F(0x054031a0) /* 0.328172327 */, 15 },
+ /* 1057 */ { MAD_F(0x0541e42e) /* 0.328586751 */, 15 },
+ /* 1058 */ { MAD_F(0x054396df) /* 0.329001306 */, 15 },
+ /* 1059 */ { MAD_F(0x054549b4) /* 0.329415992 */, 15 },
+ /* 1060 */ { MAD_F(0x0546fcab) /* 0.329830808 */, 15 },
+ /* 1061 */ { MAD_F(0x0548afc6) /* 0.330245755 */, 15 },
+ /* 1062 */ { MAD_F(0x054a6303) /* 0.330660832 */, 15 },
+ /* 1063 */ { MAD_F(0x054c1663) /* 0.331076039 */, 15 },
+ /* 1064 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 15 },
+ /* 1065 */ { MAD_F(0x054f7d8d) /* 0.331906845 */, 15 },
+ /* 1066 */ { MAD_F(0x05513156) /* 0.332322443 */, 15 },
+ /* 1067 */ { MAD_F(0x0552e542) /* 0.332738170 */, 15 },
+ /* 1068 */ { MAD_F(0x05549951) /* 0.333154028 */, 15 },
+ /* 1069 */ { MAD_F(0x05564d83) /* 0.333570016 */, 15 },
+ /* 1070 */ { MAD_F(0x055801d8) /* 0.333986133 */, 15 },
+ /* 1071 */ { MAD_F(0x0559b64f) /* 0.334402380 */, 15 },
+
+ /* 1072 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 15 },
+ /* 1073 */ { MAD_F(0x055d1fa6) /* 0.335235262 */, 15 },
+ /* 1074 */ { MAD_F(0x055ed486) /* 0.335651898 */, 15 },
+ /* 1075 */ { MAD_F(0x05608988) /* 0.336068662 */, 15 },
+ /* 1076 */ { MAD_F(0x05623ead) /* 0.336485556 */, 15 },
+ /* 1077 */ { MAD_F(0x0563f3f5) /* 0.336902579 */, 15 },
+ /* 1078 */ { MAD_F(0x0565a960) /* 0.337319732 */, 15 },
+ /* 1079 */ { MAD_F(0x05675eed) /* 0.337737013 */, 15 },
+ /* 1080 */ { MAD_F(0x0569149c) /* 0.338154423 */, 15 },
+ /* 1081 */ { MAD_F(0x056aca6f) /* 0.338571962 */, 15 },
+ /* 1082 */ { MAD_F(0x056c8064) /* 0.338989630 */, 15 },
+ /* 1083 */ { MAD_F(0x056e367b) /* 0.339407426 */, 15 },
+ /* 1084 */ { MAD_F(0x056fecb5) /* 0.339825351 */, 15 },
+ /* 1085 */ { MAD_F(0x0571a311) /* 0.340243405 */, 15 },
+ /* 1086 */ { MAD_F(0x05735990) /* 0.340661587 */, 15 },
+ /* 1087 */ { MAD_F(0x05751032) /* 0.341079898 */, 15 },
+
+ /* 1088 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 15 },
+ /* 1089 */ { MAD_F(0x05787ddc) /* 0.341916903 */, 15 },
+ /* 1090 */ { MAD_F(0x057a34e4) /* 0.342335598 */, 15 },
+ /* 1091 */ { MAD_F(0x057bec0f) /* 0.342754421 */, 15 },
+ /* 1092 */ { MAD_F(0x057da35d) /* 0.343173373 */, 15 },
+ /* 1093 */ { MAD_F(0x057f5acc) /* 0.343592452 */, 15 },
+ /* 1094 */ { MAD_F(0x0581125e) /* 0.344011659 */, 15 },
+ /* 1095 */ { MAD_F(0x0582ca12) /* 0.344430993 */, 15 },
+ /* 1096 */ { MAD_F(0x058481e9) /* 0.344850455 */, 15 },
+ /* 1097 */ { MAD_F(0x058639e2) /* 0.345270045 */, 15 },
+ /* 1098 */ { MAD_F(0x0587f1fd) /* 0.345689763 */, 15 },
+ /* 1099 */ { MAD_F(0x0589aa3a) /* 0.346109608 */, 15 },
+ /* 1100 */ { MAD_F(0x058b629a) /* 0.346529580 */, 15 },
+ /* 1101 */ { MAD_F(0x058d1b1b) /* 0.346949679 */, 15 },
+ /* 1102 */ { MAD_F(0x058ed3bf) /* 0.347369906 */, 15 },
+ /* 1103 */ { MAD_F(0x05908c85) /* 0.347790260 */, 15 },
+
+ /* 1104 */ { MAD_F(0x0592456d) /* 0.348210741 */, 15 },
+ /* 1105 */ { MAD_F(0x0593fe77) /* 0.348631348 */, 15 },
+ /* 1106 */ { MAD_F(0x0595b7a3) /* 0.349052083 */, 15 },
+ /* 1107 */ { MAD_F(0x059770f1) /* 0.349472945 */, 15 },
+ /* 1108 */ { MAD_F(0x05992a61) /* 0.349893933 */, 15 },
+ /* 1109 */ { MAD_F(0x059ae3f3) /* 0.350315048 */, 15 },
+ /* 1110 */ { MAD_F(0x059c9da8) /* 0.350736290 */, 15 },
+ /* 1111 */ { MAD_F(0x059e577e) /* 0.351157658 */, 15 },
+ /* 1112 */ { MAD_F(0x05a01176) /* 0.351579152 */, 15 },
+ /* 1113 */ { MAD_F(0x05a1cb90) /* 0.352000773 */, 15 },
+ /* 1114 */ { MAD_F(0x05a385cc) /* 0.352422520 */, 15 },
+ /* 1115 */ { MAD_F(0x05a5402a) /* 0.352844394 */, 15 },
+ /* 1116 */ { MAD_F(0x05a6faa9) /* 0.353266393 */, 15 },
+ /* 1117 */ { MAD_F(0x05a8b54b) /* 0.353688519 */, 15 },
+ /* 1118 */ { MAD_F(0x05aa700e) /* 0.354110771 */, 15 },
+ /* 1119 */ { MAD_F(0x05ac2af3) /* 0.354533148 */, 15 },
+
+ /* 1120 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 15 },
+ /* 1121 */ { MAD_F(0x05afa123) /* 0.355378281 */, 15 },
+ /* 1122 */ { MAD_F(0x05b15c6d) /* 0.355801035 */, 15 },
+ /* 1123 */ { MAD_F(0x05b317d9) /* 0.356223916 */, 15 },
+ /* 1124 */ { MAD_F(0x05b4d367) /* 0.356646922 */, 15 },
+ /* 1125 */ { MAD_F(0x05b68f16) /* 0.357070053 */, 15 },
+ /* 1126 */ { MAD_F(0x05b84ae7) /* 0.357493310 */, 15 },
+ /* 1127 */ { MAD_F(0x05ba06da) /* 0.357916692 */, 15 },
+ /* 1128 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 15 },
+ /* 1129 */ { MAD_F(0x05bd7f25) /* 0.358763832 */, 15 },
+ /* 1130 */ { MAD_F(0x05bf3b7c) /* 0.359187590 */, 15 },
+ /* 1131 */ { MAD_F(0x05c0f7f5) /* 0.359611472 */, 15 },
+ /* 1132 */ { MAD_F(0x05c2b490) /* 0.360035480 */, 15 },
+ /* 1133 */ { MAD_F(0x05c4714c) /* 0.360459613 */, 15 },
+ /* 1134 */ { MAD_F(0x05c62e2a) /* 0.360883870 */, 15 },
+ /* 1135 */ { MAD_F(0x05c7eb29) /* 0.361308252 */, 15 },
+
+ /* 1136 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 15 },
+ /* 1137 */ { MAD_F(0x05cb658c) /* 0.362157390 */, 15 },
+ /* 1138 */ { MAD_F(0x05cd22ef) /* 0.362582145 */, 15 },
+ /* 1139 */ { MAD_F(0x05cee074) /* 0.363007026 */, 15 },
+ /* 1140 */ { MAD_F(0x05d09e1b) /* 0.363432030 */, 15 },
+ /* 1141 */ { MAD_F(0x05d25be2) /* 0.363857159 */, 15 },
+ /* 1142 */ { MAD_F(0x05d419cb) /* 0.364282412 */, 15 },
+ /* 1143 */ { MAD_F(0x05d5d7d5) /* 0.364707789 */, 15 },
+ /* 1144 */ { MAD_F(0x05d79601) /* 0.365133291 */, 15 },
+ /* 1145 */ { MAD_F(0x05d9544e) /* 0.365558916 */, 15 },
+ /* 1146 */ { MAD_F(0x05db12bc) /* 0.365984665 */, 15 },
+ /* 1147 */ { MAD_F(0x05dcd14c) /* 0.366410538 */, 15 },
+ /* 1148 */ { MAD_F(0x05de8ffc) /* 0.366836535 */, 15 },
+ /* 1149 */ { MAD_F(0x05e04ece) /* 0.367262655 */, 15 },
+ /* 1150 */ { MAD_F(0x05e20dc1) /* 0.367688900 */, 15 },
+ /* 1151 */ { MAD_F(0x05e3ccd5) /* 0.368115267 */, 15 },
+
+ /* 1152 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 15 },
+ /* 1153 */ { MAD_F(0x05e74b61) /* 0.368968373 */, 15 },
+ /* 1154 */ { MAD_F(0x05e90ad9) /* 0.369395111 */, 15 },
+ /* 1155 */ { MAD_F(0x05eaca72) /* 0.369821973 */, 15 },
+ /* 1156 */ { MAD_F(0x05ec8a2b) /* 0.370248957 */, 15 },
+ /* 1157 */ { MAD_F(0x05ee4a06) /* 0.370676065 */, 15 },
+ /* 1158 */ { MAD_F(0x05f00a02) /* 0.371103295 */, 15 },
+ /* 1159 */ { MAD_F(0x05f1ca1f) /* 0.371530649 */, 15 },
+ /* 1160 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 15 },
+ /* 1161 */ { MAD_F(0x05f54abc) /* 0.372385725 */, 15 },
+ /* 1162 */ { MAD_F(0x05f70b3c) /* 0.372813448 */, 15 },
+ /* 1163 */ { MAD_F(0x05f8cbdc) /* 0.373241292 */, 15 },
+ /* 1164 */ { MAD_F(0x05fa8c9e) /* 0.373669260 */, 15 },
+ /* 1165 */ { MAD_F(0x05fc4d81) /* 0.374097350 */, 15 },
+ /* 1166 */ { MAD_F(0x05fe0e84) /* 0.374525563 */, 15 },
+ /* 1167 */ { MAD_F(0x05ffcfa8) /* 0.374953898 */, 15 },
+
+ /* 1168 */ { MAD_F(0x060190ee) /* 0.375382356 */, 15 },
+ /* 1169 */ { MAD_F(0x06035254) /* 0.375810936 */, 15 },
+ /* 1170 */ { MAD_F(0x060513da) /* 0.376239638 */, 15 },
+ /* 1171 */ { MAD_F(0x0606d582) /* 0.376668462 */, 15 },
+ /* 1172 */ { MAD_F(0x0608974a) /* 0.377097408 */, 15 },
+ /* 1173 */ { MAD_F(0x060a5934) /* 0.377526476 */, 15 },
+ /* 1174 */ { MAD_F(0x060c1b3d) /* 0.377955667 */, 15 },
+ /* 1175 */ { MAD_F(0x060ddd68) /* 0.378384979 */, 15 },
+ /* 1176 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 15 },
+ /* 1177 */ { MAD_F(0x0611621f) /* 0.379243968 */, 15 },
+ /* 1178 */ { MAD_F(0x061324ac) /* 0.379673646 */, 15 },
+ /* 1179 */ { MAD_F(0x0614e759) /* 0.380103444 */, 15 },
+ /* 1180 */ { MAD_F(0x0616aa27) /* 0.380533365 */, 15 },
+ /* 1181 */ { MAD_F(0x06186d16) /* 0.380963407 */, 15 },
+ /* 1182 */ { MAD_F(0x061a3025) /* 0.381393570 */, 15 },
+ /* 1183 */ { MAD_F(0x061bf354) /* 0.381823855 */, 15 },
+
+ /* 1184 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 15 },
+ /* 1185 */ { MAD_F(0x061f7a15) /* 0.382684788 */, 15 },
+ /* 1186 */ { MAD_F(0x06213da7) /* 0.383115436 */, 15 },
+ /* 1187 */ { MAD_F(0x06230158) /* 0.383546205 */, 15 },
+ /* 1188 */ { MAD_F(0x0624c52a) /* 0.383977096 */, 15 },
+ /* 1189 */ { MAD_F(0x0626891d) /* 0.384408107 */, 15 },
+ /* 1190 */ { MAD_F(0x06284d30) /* 0.384839239 */, 15 },
+ /* 1191 */ { MAD_F(0x062a1164) /* 0.385270492 */, 15 },
+ /* 1192 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 15 },
+ /* 1193 */ { MAD_F(0x062d9a2c) /* 0.386133359 */, 15 },
+ /* 1194 */ { MAD_F(0x062f5ec1) /* 0.386564974 */, 15 },
+ /* 1195 */ { MAD_F(0x06312376) /* 0.386996709 */, 15 },
+ /* 1196 */ { MAD_F(0x0632e84b) /* 0.387428565 */, 15 },
+ /* 1197 */ { MAD_F(0x0634ad41) /* 0.387860541 */, 15 },
+ /* 1198 */ { MAD_F(0x06367257) /* 0.388292637 */, 15 },
+ /* 1199 */ { MAD_F(0x0638378d) /* 0.388724854 */, 15 },
+
+ /* 1200 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 15 },
+ /* 1201 */ { MAD_F(0x063bc25b) /* 0.389589648 */, 15 },
+ /* 1202 */ { MAD_F(0x063d87f2) /* 0.390022225 */, 15 },
+ /* 1203 */ { MAD_F(0x063f4da9) /* 0.390454922 */, 15 },
+ /* 1204 */ { MAD_F(0x06411380) /* 0.390887739 */, 15 },
+ /* 1205 */ { MAD_F(0x0642d978) /* 0.391320675 */, 15 },
+ /* 1206 */ { MAD_F(0x06449f8f) /* 0.391753732 */, 15 },
+ /* 1207 */ { MAD_F(0x064665c7) /* 0.392186908 */, 15 },
+ /* 1208 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 15 },
+ /* 1209 */ { MAD_F(0x0649f297) /* 0.393053619 */, 15 },
+ /* 1210 */ { MAD_F(0x064bb92f) /* 0.393487154 */, 15 },
+ /* 1211 */ { MAD_F(0x064d7fe8) /* 0.393920808 */, 15 },
+ /* 1212 */ { MAD_F(0x064f46c0) /* 0.394354582 */, 15 },
+ /* 1213 */ { MAD_F(0x06510db8) /* 0.394788475 */, 15 },
+ /* 1214 */ { MAD_F(0x0652d4d0) /* 0.395222488 */, 15 },
+ /* 1215 */ { MAD_F(0x06549c09) /* 0.395656619 */, 15 },
+
+ /* 1216 */ { MAD_F(0x06566361) /* 0.396090870 */, 15 },
+ /* 1217 */ { MAD_F(0x06582ad9) /* 0.396525239 */, 15 },
+ /* 1218 */ { MAD_F(0x0659f271) /* 0.396959728 */, 15 },
+ /* 1219 */ { MAD_F(0x065bba29) /* 0.397394336 */, 15 },
+ /* 1220 */ { MAD_F(0x065d8201) /* 0.397829062 */, 15 },
+ /* 1221 */ { MAD_F(0x065f49f9) /* 0.398263907 */, 15 },
+ /* 1222 */ { MAD_F(0x06611211) /* 0.398698871 */, 15 },
+ /* 1223 */ { MAD_F(0x0662da49) /* 0.399133954 */, 15 },
+ /* 1224 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 15 },
+ /* 1225 */ { MAD_F(0x06666b17) /* 0.400004475 */, 15 },
+ /* 1226 */ { MAD_F(0x066833ae) /* 0.400439913 */, 15 },
+ /* 1227 */ { MAD_F(0x0669fc65) /* 0.400875470 */, 15 },
+ /* 1228 */ { MAD_F(0x066bc53c) /* 0.401311145 */, 15 },
+ /* 1229 */ { MAD_F(0x066d8e32) /* 0.401746938 */, 15 },
+ /* 1230 */ { MAD_F(0x066f5748) /* 0.402182850 */, 15 },
+ /* 1231 */ { MAD_F(0x0671207e) /* 0.402618879 */, 15 },
+
+ /* 1232 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 15 },
+ /* 1233 */ { MAD_F(0x0674b349) /* 0.403491293 */, 15 },
+ /* 1234 */ { MAD_F(0x06767cde) /* 0.403927676 */, 15 },
+ /* 1235 */ { MAD_F(0x06784692) /* 0.404364178 */, 15 },
+ /* 1236 */ { MAD_F(0x067a1066) /* 0.404800797 */, 15 },
+ /* 1237 */ { MAD_F(0x067bda5a) /* 0.405237535 */, 15 },
+ /* 1238 */ { MAD_F(0x067da46d) /* 0.405674390 */, 15 },
+ /* 1239 */ { MAD_F(0x067f6ea0) /* 0.406111362 */, 15 },
+ /* 1240 */ { MAD_F(0x068138f3) /* 0.406548452 */, 15 },
+ /* 1241 */ { MAD_F(0x06830365) /* 0.406985660 */, 15 },
+ /* 1242 */ { MAD_F(0x0684cdf6) /* 0.407422985 */, 15 },
+ /* 1243 */ { MAD_F(0x068698a8) /* 0.407860427 */, 15 },
+ /* 1244 */ { MAD_F(0x06886378) /* 0.408297987 */, 15 },
+ /* 1245 */ { MAD_F(0x068a2e68) /* 0.408735664 */, 15 },
+ /* 1246 */ { MAD_F(0x068bf978) /* 0.409173458 */, 15 },
+ /* 1247 */ { MAD_F(0x068dc4a7) /* 0.409611370 */, 15 },
+
+ /* 1248 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 15 },
+ /* 1249 */ { MAD_F(0x06915b63) /* 0.410487544 */, 15 },
+ /* 1250 */ { MAD_F(0x069326f0) /* 0.410925806 */, 15 },
+ /* 1251 */ { MAD_F(0x0694f29c) /* 0.411364185 */, 15 },
+ /* 1252 */ { MAD_F(0x0696be68) /* 0.411802681 */, 15 },
+ /* 1253 */ { MAD_F(0x06988a54) /* 0.412241294 */, 15 },
+ /* 1254 */ { MAD_F(0x069a565e) /* 0.412680024 */, 15 },
+ /* 1255 */ { MAD_F(0x069c2288) /* 0.413118870 */, 15 },
+ /* 1256 */ { MAD_F(0x069deed1) /* 0.413557833 */, 15 },
+ /* 1257 */ { MAD_F(0x069fbb3a) /* 0.413996912 */, 15 },
+ /* 1258 */ { MAD_F(0x06a187c1) /* 0.414436108 */, 15 },
+ /* 1259 */ { MAD_F(0x06a35468) /* 0.414875420 */, 15 },
+ /* 1260 */ { MAD_F(0x06a5212f) /* 0.415314849 */, 15 },
+ /* 1261 */ { MAD_F(0x06a6ee14) /* 0.415754393 */, 15 },
+ /* 1262 */ { MAD_F(0x06a8bb18) /* 0.416194054 */, 15 },
+ /* 1263 */ { MAD_F(0x06aa883c) /* 0.416633831 */, 15 },
+
+ /* 1264 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 15 },
+ /* 1265 */ { MAD_F(0x06ae22e1) /* 0.417513734 */, 15 },
+ /* 1266 */ { MAD_F(0x06aff062) /* 0.417953859 */, 15 },
+ /* 1267 */ { MAD_F(0x06b1be03) /* 0.418394100 */, 15 },
+ /* 1268 */ { MAD_F(0x06b38bc2) /* 0.418834457 */, 15 },
+ /* 1269 */ { MAD_F(0x06b559a1) /* 0.419274929 */, 15 },
+ /* 1270 */ { MAD_F(0x06b7279e) /* 0.419715518 */, 15 },
+ /* 1271 */ { MAD_F(0x06b8f5bb) /* 0.420156222 */, 15 },
+ /* 1272 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 15 },
+ /* 1273 */ { MAD_F(0x06bc9251) /* 0.421037977 */, 15 },
+ /* 1274 */ { MAD_F(0x06be60cb) /* 0.421479027 */, 15 },
+ /* 1275 */ { MAD_F(0x06c02f63) /* 0.421920193 */, 15 },
+ /* 1276 */ { MAD_F(0x06c1fe1b) /* 0.422361475 */, 15 },
+ /* 1277 */ { MAD_F(0x06c3ccf1) /* 0.422802871 */, 15 },
+ /* 1278 */ { MAD_F(0x06c59be7) /* 0.423244383 */, 15 },
+ /* 1279 */ { MAD_F(0x06c76afb) /* 0.423686010 */, 15 },
+
+ /* 1280 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 15 },
+ /* 1281 */ { MAD_F(0x06cb0981) /* 0.424569610 */, 15 },
+ /* 1282 */ { MAD_F(0x06ccd8f2) /* 0.425011582 */, 15 },
+ /* 1283 */ { MAD_F(0x06cea881) /* 0.425453669 */, 15 },
+ /* 1284 */ { MAD_F(0x06d07830) /* 0.425895871 */, 15 },
+ /* 1285 */ { MAD_F(0x06d247fe) /* 0.426338188 */, 15 },
+ /* 1286 */ { MAD_F(0x06d417ea) /* 0.426780620 */, 15 },
+ /* 1287 */ { MAD_F(0x06d5e7f5) /* 0.427223166 */, 15 },
+ /* 1288 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 15 },
+ /* 1289 */ { MAD_F(0x06d98868) /* 0.428108603 */, 15 },
+ /* 1290 */ { MAD_F(0x06db58cf) /* 0.428551493 */, 15 },
+ /* 1291 */ { MAD_F(0x06dd2955) /* 0.428994497 */, 15 },
+ /* 1292 */ { MAD_F(0x06def9fa) /* 0.429437616 */, 15 },
+ /* 1293 */ { MAD_F(0x06e0cabe) /* 0.429880849 */, 15 },
+ /* 1294 */ { MAD_F(0x06e29ba0) /* 0.430324197 */, 15 },
+ /* 1295 */ { MAD_F(0x06e46ca1) /* 0.430767659 */, 15 },
+
+ /* 1296 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 15 },
+ /* 1297 */ { MAD_F(0x06e80efe) /* 0.431654924 */, 15 },
+ /* 1298 */ { MAD_F(0x06e9e05b) /* 0.432098728 */, 15 },
+ /* 1299 */ { MAD_F(0x06ebb1d6) /* 0.432542647 */, 15 },
+ /* 1300 */ { MAD_F(0x06ed8370) /* 0.432986678 */, 15 },
+ /* 1301 */ { MAD_F(0x06ef5529) /* 0.433430824 */, 15 },
+ /* 1302 */ { MAD_F(0x06f12700) /* 0.433875084 */, 15 },
+ /* 1303 */ { MAD_F(0x06f2f8f5) /* 0.434319457 */, 15 },
+ /* 1304 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 15 },
+ /* 1305 */ { MAD_F(0x06f69d3c) /* 0.435208545 */, 15 },
+ /* 1306 */ { MAD_F(0x06f86f8d) /* 0.435653259 */, 15 },
+ /* 1307 */ { MAD_F(0x06fa41fd) /* 0.436098087 */, 15 },
+ /* 1308 */ { MAD_F(0x06fc148b) /* 0.436543029 */, 15 },
+ /* 1309 */ { MAD_F(0x06fde737) /* 0.436988083 */, 15 },
+ /* 1310 */ { MAD_F(0x06ffba02) /* 0.437433251 */, 15 },
+ /* 1311 */ { MAD_F(0x07018ceb) /* 0.437878533 */, 15 },
+
+ /* 1312 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 15 },
+ /* 1313 */ { MAD_F(0x07053319) /* 0.438769435 */, 15 },
+ /* 1314 */ { MAD_F(0x0707065d) /* 0.439215056 */, 15 },
+ /* 1315 */ { MAD_F(0x0708d9c0) /* 0.439660790 */, 15 },
+ /* 1316 */ { MAD_F(0x070aad41) /* 0.440106636 */, 15 },
+ /* 1317 */ { MAD_F(0x070c80e1) /* 0.440552596 */, 15 },
+ /* 1318 */ { MAD_F(0x070e549f) /* 0.440998669 */, 15 },
+ /* 1319 */ { MAD_F(0x0710287b) /* 0.441444855 */, 15 },
+ /* 1320 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 15 },
+ /* 1321 */ { MAD_F(0x0713d08d) /* 0.442337564 */, 15 },
+ /* 1322 */ { MAD_F(0x0715a4c4) /* 0.442784088 */, 15 },
+ /* 1323 */ { MAD_F(0x07177919) /* 0.443230724 */, 15 },
+ /* 1324 */ { MAD_F(0x07194d8c) /* 0.443677473 */, 15 },
+ /* 1325 */ { MAD_F(0x071b221e) /* 0.444124334 */, 15 },
+ /* 1326 */ { MAD_F(0x071cf6ce) /* 0.444571308 */, 15 },
+ /* 1327 */ { MAD_F(0x071ecb9b) /* 0.445018394 */, 15 },
+
+ /* 1328 */ { MAD_F(0x0720a087) /* 0.445465593 */, 15 },
+ /* 1329 */ { MAD_F(0x07227591) /* 0.445912903 */, 15 },
+ /* 1330 */ { MAD_F(0x07244ab9) /* 0.446360326 */, 15 },
+ /* 1331 */ { MAD_F(0x07262000) /* 0.446807861 */, 15 },
+ /* 1332 */ { MAD_F(0x0727f564) /* 0.447255509 */, 15 },
+ /* 1333 */ { MAD_F(0x0729cae7) /* 0.447703268 */, 15 },
+ /* 1334 */ { MAD_F(0x072ba087) /* 0.448151139 */, 15 },
+ /* 1335 */ { MAD_F(0x072d7646) /* 0.448599122 */, 15 },
+ /* 1336 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 15 },
+ /* 1337 */ { MAD_F(0x0731221d) /* 0.449495424 */, 15 },
+ /* 1338 */ { MAD_F(0x0732f835) /* 0.449943742 */, 15 },
+ /* 1339 */ { MAD_F(0x0734ce6c) /* 0.450392173 */, 15 },
+ /* 1340 */ { MAD_F(0x0736a4c1) /* 0.450840715 */, 15 },
+ /* 1341 */ { MAD_F(0x07387b33) /* 0.451289368 */, 15 },
+ /* 1342 */ { MAD_F(0x073a51c4) /* 0.451738133 */, 15 },
+ /* 1343 */ { MAD_F(0x073c2872) /* 0.452187010 */, 15 },
+
+ /* 1344 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 15 },
+ /* 1345 */ { MAD_F(0x073fd628) /* 0.453085097 */, 15 },
+ /* 1346 */ { MAD_F(0x0741ad30) /* 0.453534308 */, 15 },
+ /* 1347 */ { MAD_F(0x07438456) /* 0.453983630 */, 15 },
+ /* 1348 */ { MAD_F(0x07455b9a) /* 0.454433063 */, 15 },
+ /* 1349 */ { MAD_F(0x074732fc) /* 0.454882607 */, 15 },
+ /* 1350 */ { MAD_F(0x07490a7b) /* 0.455332262 */, 15 },
+ /* 1351 */ { MAD_F(0x074ae218) /* 0.455782029 */, 15 },
+ /* 1352 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 15 },
+ /* 1353 */ { MAD_F(0x074e91ac) /* 0.456681894 */, 15 },
+ /* 1354 */ { MAD_F(0x075069a3) /* 0.457131993 */, 15 },
+ /* 1355 */ { MAD_F(0x075241b7) /* 0.457582203 */, 15 },
+ /* 1356 */ { MAD_F(0x075419e9) /* 0.458032524 */, 15 },
+ /* 1357 */ { MAD_F(0x0755f239) /* 0.458482956 */, 15 },
+ /* 1358 */ { MAD_F(0x0757caa7) /* 0.458933498 */, 15 },
+ /* 1359 */ { MAD_F(0x0759a332) /* 0.459384151 */, 15 },
+
+ /* 1360 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 15 },
+ /* 1361 */ { MAD_F(0x075d54a1) /* 0.460285788 */, 15 },
+ /* 1362 */ { MAD_F(0x075f2d85) /* 0.460736772 */, 15 },
+ /* 1363 */ { MAD_F(0x07610687) /* 0.461187867 */, 15 },
+ /* 1364 */ { MAD_F(0x0762dfa6) /* 0.461639071 */, 15 },
+ /* 1365 */ { MAD_F(0x0764b8e3) /* 0.462090387 */, 15 },
+ /* 1366 */ { MAD_F(0x0766923e) /* 0.462541812 */, 15 },
+ /* 1367 */ { MAD_F(0x07686bb6) /* 0.462993348 */, 15 },
+ /* 1368 */ { MAD_F(0x076a454c) /* 0.463444993 */, 15 },
+ /* 1369 */ { MAD_F(0x076c1eff) /* 0.463896749 */, 15 },
+ /* 1370 */ { MAD_F(0x076df8d0) /* 0.464348615 */, 15 },
+ /* 1371 */ { MAD_F(0x076fd2be) /* 0.464800591 */, 15 },
+ /* 1372 */ { MAD_F(0x0771acca) /* 0.465252676 */, 15 },
+ /* 1373 */ { MAD_F(0x077386f3) /* 0.465704872 */, 15 },
+ /* 1374 */ { MAD_F(0x0775613a) /* 0.466157177 */, 15 },
+ /* 1375 */ { MAD_F(0x07773b9e) /* 0.466609592 */, 15 },
+
+ /* 1376 */ { MAD_F(0x07791620) /* 0.467062117 */, 15 },
+ /* 1377 */ { MAD_F(0x077af0bf) /* 0.467514751 */, 15 },
+ /* 1378 */ { MAD_F(0x077ccb7c) /* 0.467967495 */, 15 },
+ /* 1379 */ { MAD_F(0x077ea656) /* 0.468420349 */, 15 },
+ /* 1380 */ { MAD_F(0x0780814d) /* 0.468873312 */, 15 },
+ /* 1381 */ { MAD_F(0x07825c62) /* 0.469326384 */, 15 },
+ /* 1382 */ { MAD_F(0x07843794) /* 0.469779566 */, 15 },
+ /* 1383 */ { MAD_F(0x078612e3) /* 0.470232857 */, 15 },
+ /* 1384 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 15 },
+ /* 1385 */ { MAD_F(0x0789c9da) /* 0.471139767 */, 15 },
+ /* 1386 */ { MAD_F(0x078ba581) /* 0.471593386 */, 15 },
+ /* 1387 */ { MAD_F(0x078d8146) /* 0.472047114 */, 15 },
+ /* 1388 */ { MAD_F(0x078f5d28) /* 0.472500951 */, 15 },
+ /* 1389 */ { MAD_F(0x07913927) /* 0.472954896 */, 15 },
+ /* 1390 */ { MAD_F(0x07931543) /* 0.473408951 */, 15 },
+ /* 1391 */ { MAD_F(0x0794f17d) /* 0.473863115 */, 15 },
+
+ /* 1392 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 15 },
+ /* 1393 */ { MAD_F(0x0798aa48) /* 0.474771769 */, 15 },
+ /* 1394 */ { MAD_F(0x079a86d9) /* 0.475226259 */, 15 },
+ /* 1395 */ { MAD_F(0x079c6388) /* 0.475680858 */, 15 },
+ /* 1396 */ { MAD_F(0x079e4053) /* 0.476135565 */, 15 },
+ /* 1397 */ { MAD_F(0x07a01d3c) /* 0.476590381 */, 15 },
+ /* 1398 */ { MAD_F(0x07a1fa42) /* 0.477045306 */, 15 },
+ /* 1399 */ { MAD_F(0x07a3d765) /* 0.477500339 */, 15 },
+ /* 1400 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 15 },
+ /* 1401 */ { MAD_F(0x07a79202) /* 0.478410731 */, 15 },
+ /* 1402 */ { MAD_F(0x07a96f7d) /* 0.478866089 */, 15 },
+ /* 1403 */ { MAD_F(0x07ab4d14) /* 0.479321555 */, 15 },
+ /* 1404 */ { MAD_F(0x07ad2ac8) /* 0.479777130 */, 15 },
+ /* 1405 */ { MAD_F(0x07af089a) /* 0.480232813 */, 15 },
+ /* 1406 */ { MAD_F(0x07b0e688) /* 0.480688604 */, 15 },
+ /* 1407 */ { MAD_F(0x07b2c494) /* 0.481144503 */, 15 },
+
+ /* 1408 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 15 },
+ /* 1409 */ { MAD_F(0x07b68102) /* 0.482056625 */, 15 },
+ /* 1410 */ { MAD_F(0x07b85f64) /* 0.482512848 */, 15 },
+ /* 1411 */ { MAD_F(0x07ba3de4) /* 0.482969179 */, 15 },
+ /* 1412 */ { MAD_F(0x07bc1c80) /* 0.483425618 */, 15 },
+ /* 1413 */ { MAD_F(0x07bdfb39) /* 0.483882164 */, 15 },
+ /* 1414 */ { MAD_F(0x07bfda0f) /* 0.484338818 */, 15 },
+ /* 1415 */ { MAD_F(0x07c1b902) /* 0.484795580 */, 15 },
+ /* 1416 */ { MAD_F(0x07c39812) /* 0.485252449 */, 15 },
+ /* 1417 */ { MAD_F(0x07c5773f) /* 0.485709426 */, 15 },
+ /* 1418 */ { MAD_F(0x07c75689) /* 0.486166511 */, 15 },
+ /* 1419 */ { MAD_F(0x07c935ef) /* 0.486623703 */, 15 },
+ /* 1420 */ { MAD_F(0x07cb1573) /* 0.487081002 */, 15 },
+ /* 1421 */ { MAD_F(0x07ccf513) /* 0.487538409 */, 15 },
+ /* 1422 */ { MAD_F(0x07ced4d0) /* 0.487995923 */, 15 },
+ /* 1423 */ { MAD_F(0x07d0b4aa) /* 0.488453544 */, 15 },
+
+ /* 1424 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 15 },
+ /* 1425 */ { MAD_F(0x07d474b3) /* 0.489369108 */, 15 },
+ /* 1426 */ { MAD_F(0x07d654e4) /* 0.489827051 */, 15 },
+ /* 1427 */ { MAD_F(0x07d83530) /* 0.490285101 */, 15 },
+ /* 1428 */ { MAD_F(0x07da159a) /* 0.490743258 */, 15 },
+ /* 1429 */ { MAD_F(0x07dbf620) /* 0.491201522 */, 15 },
+ /* 1430 */ { MAD_F(0x07ddd6c3) /* 0.491659892 */, 15 },
+ /* 1431 */ { MAD_F(0x07dfb783) /* 0.492118370 */, 15 },
+ /* 1432 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 15 },
+ /* 1433 */ { MAD_F(0x07e37958) /* 0.493035645 */, 15 },
+ /* 1434 */ { MAD_F(0x07e55a6e) /* 0.493494443 */, 15 },
+ /* 1435 */ { MAD_F(0x07e73ba0) /* 0.493953348 */, 15 },
+ /* 1436 */ { MAD_F(0x07e91cef) /* 0.494412359 */, 15 },
+ /* 1437 */ { MAD_F(0x07eafe5a) /* 0.494871476 */, 15 },
+ /* 1438 */ { MAD_F(0x07ecdfe2) /* 0.495330701 */, 15 },
+ /* 1439 */ { MAD_F(0x07eec187) /* 0.495790031 */, 15 },
+
+ /* 1440 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 15 },
+ /* 1441 */ { MAD_F(0x07f28526) /* 0.496709012 */, 15 },
+ /* 1442 */ { MAD_F(0x07f46720) /* 0.497168662 */, 15 },
+ /* 1443 */ { MAD_F(0x07f64937) /* 0.497628418 */, 15 },
+ /* 1444 */ { MAD_F(0x07f82b6a) /* 0.498088280 */, 15 },
+ /* 1445 */ { MAD_F(0x07fa0dba) /* 0.498548248 */, 15 },
+ /* 1446 */ { MAD_F(0x07fbf026) /* 0.499008323 */, 15 },
+ /* 1447 */ { MAD_F(0x07fdd2af) /* 0.499468503 */, 15 },
+ /* 1448 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 15 },
+ /* 1449 */ { MAD_F(0x0400cc0b) /* 0.250194591 */, 16 },
+ /* 1450 */ { MAD_F(0x0401bd7a) /* 0.250424840 */, 16 },
+ /* 1451 */ { MAD_F(0x0402aef7) /* 0.250655143 */, 16 },
+ /* 1452 */ { MAD_F(0x0403a083) /* 0.250885498 */, 16 },
+ /* 1453 */ { MAD_F(0x0404921c) /* 0.251115906 */, 16 },
+ /* 1454 */ { MAD_F(0x040583c4) /* 0.251346367 */, 16 },
+ /* 1455 */ { MAD_F(0x0406757a) /* 0.251576880 */, 16 },
+
+ /* 1456 */ { MAD_F(0x0407673f) /* 0.251807447 */, 16 },
+ /* 1457 */ { MAD_F(0x04085911) /* 0.252038066 */, 16 },
+ /* 1458 */ { MAD_F(0x04094af1) /* 0.252268738 */, 16 },
+ /* 1459 */ { MAD_F(0x040a3ce0) /* 0.252499463 */, 16 },
+ /* 1460 */ { MAD_F(0x040b2edd) /* 0.252730240 */, 16 },
+ /* 1461 */ { MAD_F(0x040c20e8) /* 0.252961071 */, 16 },
+ /* 1462 */ { MAD_F(0x040d1301) /* 0.253191953 */, 16 },
+ /* 1463 */ { MAD_F(0x040e0529) /* 0.253422889 */, 16 },
+ /* 1464 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 16 },
+ /* 1465 */ { MAD_F(0x040fe9a1) /* 0.253884918 */, 16 },
+ /* 1466 */ { MAD_F(0x0410dbf3) /* 0.254116011 */, 16 },
+ /* 1467 */ { MAD_F(0x0411ce53) /* 0.254347157 */, 16 },
+ /* 1468 */ { MAD_F(0x0412c0c1) /* 0.254578356 */, 16 },
+ /* 1469 */ { MAD_F(0x0413b33d) /* 0.254809606 */, 16 },
+ /* 1470 */ { MAD_F(0x0414a5c7) /* 0.255040910 */, 16 },
+ /* 1471 */ { MAD_F(0x0415985f) /* 0.255272266 */, 16 },
+
+ /* 1472 */ { MAD_F(0x04168b05) /* 0.255503674 */, 16 },
+ /* 1473 */ { MAD_F(0x04177db9) /* 0.255735135 */, 16 },
+ /* 1474 */ { MAD_F(0x0418707c) /* 0.255966648 */, 16 },
+ /* 1475 */ { MAD_F(0x0419634c) /* 0.256198213 */, 16 },
+ /* 1476 */ { MAD_F(0x041a562a) /* 0.256429831 */, 16 },
+ /* 1477 */ { MAD_F(0x041b4917) /* 0.256661501 */, 16 },
+ /* 1478 */ { MAD_F(0x041c3c11) /* 0.256893223 */, 16 },
+ /* 1479 */ { MAD_F(0x041d2f1a) /* 0.257124998 */, 16 },
+ /* 1480 */ { MAD_F(0x041e2230) /* 0.257356825 */, 16 },
+ /* 1481 */ { MAD_F(0x041f1555) /* 0.257588704 */, 16 },
+ /* 1482 */ { MAD_F(0x04200888) /* 0.257820635 */, 16 },
+ /* 1483 */ { MAD_F(0x0420fbc8) /* 0.258052619 */, 16 },
+ /* 1484 */ { MAD_F(0x0421ef17) /* 0.258284654 */, 16 },
+ /* 1485 */ { MAD_F(0x0422e273) /* 0.258516742 */, 16 },
+ /* 1486 */ { MAD_F(0x0423d5de) /* 0.258748882 */, 16 },
+ /* 1487 */ { MAD_F(0x0424c956) /* 0.258981074 */, 16 },
+
+ /* 1488 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 16 },
+ /* 1489 */ { MAD_F(0x0426b071) /* 0.259445614 */, 16 },
+ /* 1490 */ { MAD_F(0x0427a414) /* 0.259677962 */, 16 },
+ /* 1491 */ { MAD_F(0x042897c4) /* 0.259910362 */, 16 },
+ /* 1492 */ { MAD_F(0x04298b83) /* 0.260142814 */, 16 },
+ /* 1493 */ { MAD_F(0x042a7f4f) /* 0.260375318 */, 16 },
+ /* 1494 */ { MAD_F(0x042b7329) /* 0.260607874 */, 16 },
+ /* 1495 */ { MAD_F(0x042c6711) /* 0.260840481 */, 16 },
+ /* 1496 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 16 },
+ /* 1497 */ { MAD_F(0x042e4f0b) /* 0.261305852 */, 16 },
+ /* 1498 */ { MAD_F(0x042f431d) /* 0.261538616 */, 16 },
+ /* 1499 */ { MAD_F(0x0430373d) /* 0.261771431 */, 16 },
+ /* 1500 */ { MAD_F(0x04312b6b) /* 0.262004297 */, 16 },
+ /* 1501 */ { MAD_F(0x04321fa6) /* 0.262237216 */, 16 },
+ /* 1502 */ { MAD_F(0x043313f0) /* 0.262470186 */, 16 },
+ /* 1503 */ { MAD_F(0x04340847) /* 0.262703208 */, 16 },
+
+ /* 1504 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 16 },
+ /* 1505 */ { MAD_F(0x0435f120) /* 0.263169407 */, 16 },
+ /* 1506 */ { MAD_F(0x0436e5a1) /* 0.263402584 */, 16 },
+ /* 1507 */ { MAD_F(0x0437da2f) /* 0.263635813 */, 16 },
+ /* 1508 */ { MAD_F(0x0438cecc) /* 0.263869093 */, 16 },
+ /* 1509 */ { MAD_F(0x0439c377) /* 0.264102425 */, 16 },
+ /* 1510 */ { MAD_F(0x043ab82f) /* 0.264335808 */, 16 },
+ /* 1511 */ { MAD_F(0x043bacf5) /* 0.264569243 */, 16 },
+ /* 1512 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 16 },
+ /* 1513 */ { MAD_F(0x043d96ab) /* 0.265036267 */, 16 },
+ /* 1514 */ { MAD_F(0x043e8b9b) /* 0.265269857 */, 16 },
+ /* 1515 */ { MAD_F(0x043f8098) /* 0.265503498 */, 16 },
+ /* 1516 */ { MAD_F(0x044075a3) /* 0.265737190 */, 16 },
+ /* 1517 */ { MAD_F(0x04416abc) /* 0.265970933 */, 16 },
+ /* 1518 */ { MAD_F(0x04425fe3) /* 0.266204728 */, 16 },
+ /* 1519 */ { MAD_F(0x04435518) /* 0.266438574 */, 16 },
+
+ /* 1520 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 16 },
+ /* 1521 */ { MAD_F(0x04453fab) /* 0.266906421 */, 16 },
+ /* 1522 */ { MAD_F(0x04463508) /* 0.267140421 */, 16 },
+ /* 1523 */ { MAD_F(0x04472a74) /* 0.267374472 */, 16 },
+ /* 1524 */ { MAD_F(0x04481fee) /* 0.267608575 */, 16 },
+ /* 1525 */ { MAD_F(0x04491575) /* 0.267842729 */, 16 },
+ /* 1526 */ { MAD_F(0x044a0b0a) /* 0.268076934 */, 16 },
+ /* 1527 */ { MAD_F(0x044b00ac) /* 0.268311190 */, 16 },
+ /* 1528 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 16 },
+ /* 1529 */ { MAD_F(0x044cec1b) /* 0.268779856 */, 16 },
+ /* 1530 */ { MAD_F(0x044de1e7) /* 0.269014265 */, 16 },
+ /* 1531 */ { MAD_F(0x044ed7c0) /* 0.269248726 */, 16 },
+ /* 1532 */ { MAD_F(0x044fcda8) /* 0.269483238 */, 16 },
+ /* 1533 */ { MAD_F(0x0450c39c) /* 0.269717800 */, 16 },
+ /* 1534 */ { MAD_F(0x0451b99f) /* 0.269952414 */, 16 },
+ /* 1535 */ { MAD_F(0x0452afaf) /* 0.270187079 */, 16 },
+
+ /* 1536 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 16 },
+ /* 1537 */ { MAD_F(0x04549bf9) /* 0.270656561 */, 16 },
+ /* 1538 */ { MAD_F(0x04559232) /* 0.270891379 */, 16 },
+ /* 1539 */ { MAD_F(0x04568879) /* 0.271126247 */, 16 },
+ /* 1540 */ { MAD_F(0x04577ece) /* 0.271361166 */, 16 },
+ /* 1541 */ { MAD_F(0x04587530) /* 0.271596136 */, 16 },
+ /* 1542 */ { MAD_F(0x04596ba0) /* 0.271831157 */, 16 },
+ /* 1543 */ { MAD_F(0x045a621e) /* 0.272066229 */, 16 },
+ /* 1544 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 16 },
+ /* 1545 */ { MAD_F(0x045c4f42) /* 0.272536525 */, 16 },
+ /* 1546 */ { MAD_F(0x045d45e9) /* 0.272771749 */, 16 },
+ /* 1547 */ { MAD_F(0x045e3c9d) /* 0.273007024 */, 16 },
+ /* 1548 */ { MAD_F(0x045f335e) /* 0.273242350 */, 16 },
+ /* 1549 */ { MAD_F(0x04602a2e) /* 0.273477726 */, 16 },
+ /* 1550 */ { MAD_F(0x0461210b) /* 0.273713153 */, 16 },
+ /* 1551 */ { MAD_F(0x046217f5) /* 0.273948630 */, 16 },
+
+ /* 1552 */ { MAD_F(0x04630eed) /* 0.274184158 */, 16 },
+ /* 1553 */ { MAD_F(0x046405f3) /* 0.274419737 */, 16 },
+ /* 1554 */ { MAD_F(0x0464fd06) /* 0.274655366 */, 16 },
+ /* 1555 */ { MAD_F(0x0465f427) /* 0.274891046 */, 16 },
+ /* 1556 */ { MAD_F(0x0466eb55) /* 0.275126776 */, 16 },
+ /* 1557 */ { MAD_F(0x0467e291) /* 0.275362557 */, 16 },
+ /* 1558 */ { MAD_F(0x0468d9db) /* 0.275598389 */, 16 },
+ /* 1559 */ { MAD_F(0x0469d132) /* 0.275834270 */, 16 },
+ /* 1560 */ { MAD_F(0x046ac896) /* 0.276070203 */, 16 },
+ /* 1561 */ { MAD_F(0x046bc009) /* 0.276306185 */, 16 },
+ /* 1562 */ { MAD_F(0x046cb788) /* 0.276542218 */, 16 },
+ /* 1563 */ { MAD_F(0x046daf15) /* 0.276778302 */, 16 },
+ /* 1564 */ { MAD_F(0x046ea6b0) /* 0.277014435 */, 16 },
+ /* 1565 */ { MAD_F(0x046f9e58) /* 0.277250619 */, 16 },
+ /* 1566 */ { MAD_F(0x0470960e) /* 0.277486854 */, 16 },
+ /* 1567 */ { MAD_F(0x04718dd1) /* 0.277723139 */, 16 },
+
+ /* 1568 */ { MAD_F(0x047285a2) /* 0.277959474 */, 16 },
+ /* 1569 */ { MAD_F(0x04737d80) /* 0.278195859 */, 16 },
+ /* 1570 */ { MAD_F(0x0474756c) /* 0.278432294 */, 16 },
+ /* 1571 */ { MAD_F(0x04756d65) /* 0.278668780 */, 16 },
+ /* 1572 */ { MAD_F(0x0476656b) /* 0.278905316 */, 16 },
+ /* 1573 */ { MAD_F(0x04775d7f) /* 0.279141902 */, 16 },
+ /* 1574 */ { MAD_F(0x047855a1) /* 0.279378538 */, 16 },
+ /* 1575 */ { MAD_F(0x04794dd0) /* 0.279615224 */, 16 },
+ /* 1576 */ { MAD_F(0x047a460c) /* 0.279851960 */, 16 },
+ /* 1577 */ { MAD_F(0x047b3e56) /* 0.280088747 */, 16 },
+ /* 1578 */ { MAD_F(0x047c36ae) /* 0.280325583 */, 16 },
+ /* 1579 */ { MAD_F(0x047d2f12) /* 0.280562470 */, 16 },
+ /* 1580 */ { MAD_F(0x047e2784) /* 0.280799406 */, 16 },
+ /* 1581 */ { MAD_F(0x047f2004) /* 0.281036393 */, 16 },
+ /* 1582 */ { MAD_F(0x04801891) /* 0.281273429 */, 16 },
+ /* 1583 */ { MAD_F(0x0481112b) /* 0.281510516 */, 16 },
+
+ /* 1584 */ { MAD_F(0x048209d3) /* 0.281747652 */, 16 },
+ /* 1585 */ { MAD_F(0x04830288) /* 0.281984838 */, 16 },
+ /* 1586 */ { MAD_F(0x0483fb4b) /* 0.282222075 */, 16 },
+ /* 1587 */ { MAD_F(0x0484f41b) /* 0.282459361 */, 16 },
+ /* 1588 */ { MAD_F(0x0485ecf8) /* 0.282696697 */, 16 },
+ /* 1589 */ { MAD_F(0x0486e5e3) /* 0.282934082 */, 16 },
+ /* 1590 */ { MAD_F(0x0487dedb) /* 0.283171518 */, 16 },
+ /* 1591 */ { MAD_F(0x0488d7e1) /* 0.283409003 */, 16 },
+ /* 1592 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 16 },
+ /* 1593 */ { MAD_F(0x048aca14) /* 0.283884123 */, 16 },
+ /* 1594 */ { MAD_F(0x048bc341) /* 0.284121757 */, 16 },
+ /* 1595 */ { MAD_F(0x048cbc7c) /* 0.284359441 */, 16 },
+ /* 1596 */ { MAD_F(0x048db5c4) /* 0.284597175 */, 16 },
+ /* 1597 */ { MAD_F(0x048eaf1a) /* 0.284834959 */, 16 },
+ /* 1598 */ { MAD_F(0x048fa87d) /* 0.285072792 */, 16 },
+ /* 1599 */ { MAD_F(0x0490a1ed) /* 0.285310675 */, 16 },
+
+ /* 1600 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 16 },
+ /* 1601 */ { MAD_F(0x049294f5) /* 0.285786589 */, 16 },
+ /* 1602 */ { MAD_F(0x04938e8d) /* 0.286024621 */, 16 },
+ /* 1603 */ { MAD_F(0x04948833) /* 0.286262702 */, 16 },
+ /* 1604 */ { MAD_F(0x049581e5) /* 0.286500832 */, 16 },
+ /* 1605 */ { MAD_F(0x04967ba5) /* 0.286739012 */, 16 },
+ /* 1606 */ { MAD_F(0x04977573) /* 0.286977242 */, 16 },
+ /* 1607 */ { MAD_F(0x04986f4d) /* 0.287215521 */, 16 },
+ /* 1608 */ { MAD_F(0x04996935) /* 0.287453849 */, 16 },
+ /* 1609 */ { MAD_F(0x049a632a) /* 0.287692227 */, 16 },
+ /* 1610 */ { MAD_F(0x049b5d2c) /* 0.287930654 */, 16 },
+ /* 1611 */ { MAD_F(0x049c573c) /* 0.288169131 */, 16 },
+ /* 1612 */ { MAD_F(0x049d5159) /* 0.288407657 */, 16 },
+ /* 1613 */ { MAD_F(0x049e4b83) /* 0.288646232 */, 16 },
+ /* 1614 */ { MAD_F(0x049f45ba) /* 0.288884857 */, 16 },
+ /* 1615 */ { MAD_F(0x04a03ffe) /* 0.289123530 */, 16 },
+
+ /* 1616 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 16 },
+ /* 1617 */ { MAD_F(0x04a234af) /* 0.289601026 */, 16 },
+ /* 1618 */ { MAD_F(0x04a32f1b) /* 0.289839847 */, 16 },
+ /* 1619 */ { MAD_F(0x04a42995) /* 0.290078718 */, 16 },
+ /* 1620 */ { MAD_F(0x04a5241b) /* 0.290317638 */, 16 },
+ /* 1621 */ { MAD_F(0x04a61eaf) /* 0.290556607 */, 16 },
+ /* 1622 */ { MAD_F(0x04a71950) /* 0.290795626 */, 16 },
+ /* 1623 */ { MAD_F(0x04a813fe) /* 0.291034693 */, 16 },
+ /* 1624 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 16 },
+ /* 1625 */ { MAD_F(0x04aa0982) /* 0.291512975 */, 16 },
+ /* 1626 */ { MAD_F(0x04ab0458) /* 0.291752190 */, 16 },
+ /* 1627 */ { MAD_F(0x04abff3b) /* 0.291991453 */, 16 },
+ /* 1628 */ { MAD_F(0x04acfa2b) /* 0.292230766 */, 16 },
+ /* 1629 */ { MAD_F(0x04adf528) /* 0.292470128 */, 16 },
+ /* 1630 */ { MAD_F(0x04aef032) /* 0.292709539 */, 16 },
+ /* 1631 */ { MAD_F(0x04afeb4a) /* 0.292948998 */, 16 },
+
+ /* 1632 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 16 },
+ /* 1633 */ { MAD_F(0x04b1e1a0) /* 0.293428065 */, 16 },
+ /* 1634 */ { MAD_F(0x04b2dcdf) /* 0.293667671 */, 16 },
+ /* 1635 */ { MAD_F(0x04b3d82b) /* 0.293907326 */, 16 },
+ /* 1636 */ { MAD_F(0x04b4d384) /* 0.294147031 */, 16 },
+ /* 1637 */ { MAD_F(0x04b5ceea) /* 0.294386784 */, 16 },
+ /* 1638 */ { MAD_F(0x04b6ca5e) /* 0.294626585 */, 16 },
+ /* 1639 */ { MAD_F(0x04b7c5de) /* 0.294866436 */, 16 },
+ /* 1640 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 16 },
+ /* 1641 */ { MAD_F(0x04b9bd06) /* 0.295346284 */, 16 },
+ /* 1642 */ { MAD_F(0x04bab8ae) /* 0.295586281 */, 16 },
+ /* 1643 */ { MAD_F(0x04bbb463) /* 0.295826327 */, 16 },
+ /* 1644 */ { MAD_F(0x04bcb024) /* 0.296066421 */, 16 },
+ /* 1645 */ { MAD_F(0x04bdabf3) /* 0.296306564 */, 16 },
+ /* 1646 */ { MAD_F(0x04bea7cf) /* 0.296546756 */, 16 },
+ /* 1647 */ { MAD_F(0x04bfa3b8) /* 0.296786996 */, 16 },
+
+ /* 1648 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 16 },
+ /* 1649 */ { MAD_F(0x04c19bb2) /* 0.297267623 */, 16 },
+ /* 1650 */ { MAD_F(0x04c297c2) /* 0.297508009 */, 16 },
+ /* 1651 */ { MAD_F(0x04c393df) /* 0.297748444 */, 16 },
+ /* 1652 */ { MAD_F(0x04c49009) /* 0.297988927 */, 16 },
+ /* 1653 */ { MAD_F(0x04c58c41) /* 0.298229459 */, 16 },
+ /* 1654 */ { MAD_F(0x04c68885) /* 0.298470039 */, 16 },
+ /* 1655 */ { MAD_F(0x04c784d6) /* 0.298710668 */, 16 },
+ /* 1656 */ { MAD_F(0x04c88135) /* 0.298951346 */, 16 },
+ /* 1657 */ { MAD_F(0x04c97da0) /* 0.299192071 */, 16 },
+ /* 1658 */ { MAD_F(0x04ca7a18) /* 0.299432846 */, 16 },
+ /* 1659 */ { MAD_F(0x04cb769e) /* 0.299673668 */, 16 },
+ /* 1660 */ { MAD_F(0x04cc7330) /* 0.299914539 */, 16 },
+ /* 1661 */ { MAD_F(0x04cd6fcf) /* 0.300155459 */, 16 },
+ /* 1662 */ { MAD_F(0x04ce6c7b) /* 0.300396426 */, 16 },
+ /* 1663 */ { MAD_F(0x04cf6935) /* 0.300637443 */, 16 },
+
+ /* 1664 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 16 },
+ /* 1665 */ { MAD_F(0x04d162ce) /* 0.301119620 */, 16 },
+ /* 1666 */ { MAD_F(0x04d25fae) /* 0.301360781 */, 16 },
+ /* 1667 */ { MAD_F(0x04d35c9b) /* 0.301601990 */, 16 },
+ /* 1668 */ { MAD_F(0x04d45995) /* 0.301843247 */, 16 },
+ /* 1669 */ { MAD_F(0x04d5569c) /* 0.302084553 */, 16 },
+ /* 1670 */ { MAD_F(0x04d653b0) /* 0.302325907 */, 16 },
+ /* 1671 */ { MAD_F(0x04d750d1) /* 0.302567309 */, 16 },
+ /* 1672 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 16 },
+ /* 1673 */ { MAD_F(0x04d94b3a) /* 0.303050257 */, 16 },
+ /* 1674 */ { MAD_F(0x04da4881) /* 0.303291804 */, 16 },
+ /* 1675 */ { MAD_F(0x04db45d6) /* 0.303533399 */, 16 },
+ /* 1676 */ { MAD_F(0x04dc4337) /* 0.303775041 */, 16 },
+ /* 1677 */ { MAD_F(0x04dd40a6) /* 0.304016732 */, 16 },
+ /* 1678 */ { MAD_F(0x04de3e21) /* 0.304258471 */, 16 },
+ /* 1679 */ { MAD_F(0x04df3ba9) /* 0.304500257 */, 16 },
+
+ /* 1680 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 16 },
+ /* 1681 */ { MAD_F(0x04e136e0) /* 0.304983975 */, 16 },
+ /* 1682 */ { MAD_F(0x04e2348f) /* 0.305225906 */, 16 },
+ /* 1683 */ { MAD_F(0x04e3324b) /* 0.305467885 */, 16 },
+ /* 1684 */ { MAD_F(0x04e43013) /* 0.305709911 */, 16 },
+ /* 1685 */ { MAD_F(0x04e52de9) /* 0.305951986 */, 16 },
+ /* 1686 */ { MAD_F(0x04e62bcb) /* 0.306194108 */, 16 },
+ /* 1687 */ { MAD_F(0x04e729ba) /* 0.306436279 */, 16 },
+ /* 1688 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 16 },
+ /* 1689 */ { MAD_F(0x04e925bf) /* 0.306920763 */, 16 },
+ /* 1690 */ { MAD_F(0x04ea23d4) /* 0.307163077 */, 16 },
+ /* 1691 */ { MAD_F(0x04eb21f7) /* 0.307405438 */, 16 },
+ /* 1692 */ { MAD_F(0x04ec2026) /* 0.307647848 */, 16 },
+ /* 1693 */ { MAD_F(0x04ed1e62) /* 0.307890305 */, 16 },
+ /* 1694 */ { MAD_F(0x04ee1cab) /* 0.308132810 */, 16 },
+ /* 1695 */ { MAD_F(0x04ef1b01) /* 0.308375362 */, 16 },
+
+ /* 1696 */ { MAD_F(0x04f01963) /* 0.308617963 */, 16 },
+ /* 1697 */ { MAD_F(0x04f117d3) /* 0.308860611 */, 16 },
+ /* 1698 */ { MAD_F(0x04f2164f) /* 0.309103306 */, 16 },
+ /* 1699 */ { MAD_F(0x04f314d8) /* 0.309346050 */, 16 },
+ /* 1700 */ { MAD_F(0x04f4136d) /* 0.309588841 */, 16 },
+ /* 1701 */ { MAD_F(0x04f51210) /* 0.309831679 */, 16 },
+ /* 1702 */ { MAD_F(0x04f610bf) /* 0.310074565 */, 16 },
+ /* 1703 */ { MAD_F(0x04f70f7b) /* 0.310317499 */, 16 },
+ /* 1704 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 16 },
+ /* 1705 */ { MAD_F(0x04f90d19) /* 0.310803509 */, 16 },
+ /* 1706 */ { MAD_F(0x04fa0bfc) /* 0.311046586 */, 16 },
+ /* 1707 */ { MAD_F(0x04fb0aeb) /* 0.311289710 */, 16 },
+ /* 1708 */ { MAD_F(0x04fc09e7) /* 0.311532881 */, 16 },
+ /* 1709 */ { MAD_F(0x04fd08ef) /* 0.311776100 */, 16 },
+ /* 1710 */ { MAD_F(0x04fe0805) /* 0.312019366 */, 16 },
+ /* 1711 */ { MAD_F(0x04ff0727) /* 0.312262680 */, 16 },
+
+ /* 1712 */ { MAD_F(0x05000655) /* 0.312506041 */, 16 },
+ /* 1713 */ { MAD_F(0x05010591) /* 0.312749449 */, 16 },
+ /* 1714 */ { MAD_F(0x050204d9) /* 0.312992905 */, 16 },
+ /* 1715 */ { MAD_F(0x0503042e) /* 0.313236408 */, 16 },
+ /* 1716 */ { MAD_F(0x0504038f) /* 0.313479959 */, 16 },
+ /* 1717 */ { MAD_F(0x050502fe) /* 0.313723556 */, 16 },
+ /* 1718 */ { MAD_F(0x05060279) /* 0.313967202 */, 16 },
+ /* 1719 */ { MAD_F(0x05070200) /* 0.314210894 */, 16 },
+ /* 1720 */ { MAD_F(0x05080195) /* 0.314454634 */, 16 },
+ /* 1721 */ { MAD_F(0x05090136) /* 0.314698420 */, 16 },
+ /* 1722 */ { MAD_F(0x050a00e3) /* 0.314942255 */, 16 },
+ /* 1723 */ { MAD_F(0x050b009e) /* 0.315186136 */, 16 },
+ /* 1724 */ { MAD_F(0x050c0065) /* 0.315430064 */, 16 },
+ /* 1725 */ { MAD_F(0x050d0039) /* 0.315674040 */, 16 },
+ /* 1726 */ { MAD_F(0x050e0019) /* 0.315918063 */, 16 },
+ /* 1727 */ { MAD_F(0x050f0006) /* 0.316162133 */, 16 },
+
+ /* 1728 */ { MAD_F(0x05100000) /* 0.316406250 */, 16 },
+ /* 1729 */ { MAD_F(0x05110006) /* 0.316650414 */, 16 },
+ /* 1730 */ { MAD_F(0x05120019) /* 0.316894625 */, 16 },
+ /* 1731 */ { MAD_F(0x05130039) /* 0.317138884 */, 16 },
+ /* 1732 */ { MAD_F(0x05140065) /* 0.317383189 */, 16 },
+ /* 1733 */ { MAD_F(0x0515009e) /* 0.317627541 */, 16 },
+ /* 1734 */ { MAD_F(0x051600e3) /* 0.317871941 */, 16 },
+ /* 1735 */ { MAD_F(0x05170135) /* 0.318116387 */, 16 },
+ /* 1736 */ { MAD_F(0x05180194) /* 0.318360880 */, 16 },
+ /* 1737 */ { MAD_F(0x051901ff) /* 0.318605421 */, 16 },
+ /* 1738 */ { MAD_F(0x051a0277) /* 0.318850008 */, 16 },
+ /* 1739 */ { MAD_F(0x051b02fc) /* 0.319094642 */, 16 },
+ /* 1740 */ { MAD_F(0x051c038d) /* 0.319339323 */, 16 },
+ /* 1741 */ { MAD_F(0x051d042a) /* 0.319584051 */, 16 },
+ /* 1742 */ { MAD_F(0x051e04d4) /* 0.319828826 */, 16 },
+ /* 1743 */ { MAD_F(0x051f058b) /* 0.320073647 */, 16 },
+
+ /* 1744 */ { MAD_F(0x0520064f) /* 0.320318516 */, 16 },
+ /* 1745 */ { MAD_F(0x0521071f) /* 0.320563431 */, 16 },
+ /* 1746 */ { MAD_F(0x052207fb) /* 0.320808393 */, 16 },
+ /* 1747 */ { MAD_F(0x052308e4) /* 0.321053402 */, 16 },
+ /* 1748 */ { MAD_F(0x052409da) /* 0.321298457 */, 16 },
+ /* 1749 */ { MAD_F(0x05250adc) /* 0.321543560 */, 16 },
+ /* 1750 */ { MAD_F(0x05260bea) /* 0.321788709 */, 16 },
+ /* 1751 */ { MAD_F(0x05270d06) /* 0.322033904 */, 16 },
+ /* 1752 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 16 },
+ /* 1753 */ { MAD_F(0x05290f62) /* 0.322524436 */, 16 },
+ /* 1754 */ { MAD_F(0x052a10a3) /* 0.322769771 */, 16 },
+ /* 1755 */ { MAD_F(0x052b11f0) /* 0.323015154 */, 16 },
+ /* 1756 */ { MAD_F(0x052c134a) /* 0.323260583 */, 16 },
+ /* 1757 */ { MAD_F(0x052d14b0) /* 0.323506058 */, 16 },
+ /* 1758 */ { MAD_F(0x052e1623) /* 0.323751580 */, 16 },
+ /* 1759 */ { MAD_F(0x052f17a2) /* 0.323997149 */, 16 },
+
+ /* 1760 */ { MAD_F(0x0530192e) /* 0.324242764 */, 16 },
+ /* 1761 */ { MAD_F(0x05311ac6) /* 0.324488426 */, 16 },
+ /* 1762 */ { MAD_F(0x05321c6b) /* 0.324734134 */, 16 },
+ /* 1763 */ { MAD_F(0x05331e1c) /* 0.324979889 */, 16 },
+ /* 1764 */ { MAD_F(0x05341fda) /* 0.325225690 */, 16 },
+ /* 1765 */ { MAD_F(0x053521a4) /* 0.325471538 */, 16 },
+ /* 1766 */ { MAD_F(0x0536237b) /* 0.325717432 */, 16 },
+ /* 1767 */ { MAD_F(0x0537255e) /* 0.325963372 */, 16 },
+ /* 1768 */ { MAD_F(0x0538274e) /* 0.326209359 */, 16 },
+ /* 1769 */ { MAD_F(0x0539294a) /* 0.326455392 */, 16 },
+ /* 1770 */ { MAD_F(0x053a2b52) /* 0.326701472 */, 16 },
+ /* 1771 */ { MAD_F(0x053b2d67) /* 0.326947598 */, 16 },
+ /* 1772 */ { MAD_F(0x053c2f89) /* 0.327193770 */, 16 },
+ /* 1773 */ { MAD_F(0x053d31b6) /* 0.327439989 */, 16 },
+ /* 1774 */ { MAD_F(0x053e33f1) /* 0.327686254 */, 16 },
+ /* 1775 */ { MAD_F(0x053f3637) /* 0.327932565 */, 16 },
+
+ /* 1776 */ { MAD_F(0x0540388a) /* 0.328178922 */, 16 },
+ /* 1777 */ { MAD_F(0x05413aea) /* 0.328425326 */, 16 },
+ /* 1778 */ { MAD_F(0x05423d56) /* 0.328671776 */, 16 },
+ /* 1779 */ { MAD_F(0x05433fce) /* 0.328918272 */, 16 },
+ /* 1780 */ { MAD_F(0x05444253) /* 0.329164814 */, 16 },
+ /* 1781 */ { MAD_F(0x054544e4) /* 0.329411403 */, 16 },
+ /* 1782 */ { MAD_F(0x05464781) /* 0.329658038 */, 16 },
+ /* 1783 */ { MAD_F(0x05474a2b) /* 0.329904718 */, 16 },
+ /* 1784 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 16 },
+ /* 1785 */ { MAD_F(0x05494fa4) /* 0.330398218 */, 16 },
+ /* 1786 */ { MAD_F(0x054a5273) /* 0.330645037 */, 16 },
+ /* 1787 */ { MAD_F(0x054b554e) /* 0.330891903 */, 16 },
+ /* 1788 */ { MAD_F(0x054c5836) /* 0.331138814 */, 16 },
+ /* 1789 */ { MAD_F(0x054d5b2a) /* 0.331385771 */, 16 },
+ /* 1790 */ { MAD_F(0x054e5e2b) /* 0.331632774 */, 16 },
+ /* 1791 */ { MAD_F(0x054f6138) /* 0.331879824 */, 16 },
+
+ /* 1792 */ { MAD_F(0x05506451) /* 0.332126919 */, 16 },
+ /* 1793 */ { MAD_F(0x05516776) /* 0.332374060 */, 16 },
+ /* 1794 */ { MAD_F(0x05526aa8) /* 0.332621247 */, 16 },
+ /* 1795 */ { MAD_F(0x05536de6) /* 0.332868480 */, 16 },
+ /* 1796 */ { MAD_F(0x05547131) /* 0.333115759 */, 16 },
+ /* 1797 */ { MAD_F(0x05557487) /* 0.333363084 */, 16 },
+ /* 1798 */ { MAD_F(0x055677ea) /* 0.333610455 */, 16 },
+ /* 1799 */ { MAD_F(0x05577b5a) /* 0.333857872 */, 16 },
+ /* 1800 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 16 },
+ /* 1801 */ { MAD_F(0x0559825e) /* 0.334352843 */, 16 },
+ /* 1802 */ { MAD_F(0x055a85f2) /* 0.334600397 */, 16 },
+ /* 1803 */ { MAD_F(0x055b8992) /* 0.334847997 */, 16 },
+ /* 1804 */ { MAD_F(0x055c8d3f) /* 0.335095642 */, 16 },
+ /* 1805 */ { MAD_F(0x055d90f9) /* 0.335343334 */, 16 },
+ /* 1806 */ { MAD_F(0x055e94be) /* 0.335591071 */, 16 },
+ /* 1807 */ { MAD_F(0x055f9890) /* 0.335838854 */, 16 },
+
+ /* 1808 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 16 },
+ /* 1809 */ { MAD_F(0x0561a058) /* 0.336334557 */, 16 },
+ /* 1810 */ { MAD_F(0x0562a44f) /* 0.336582477 */, 16 },
+ /* 1811 */ { MAD_F(0x0563a851) /* 0.336830443 */, 16 },
+ /* 1812 */ { MAD_F(0x0564ac60) /* 0.337078454 */, 16 },
+ /* 1813 */ { MAD_F(0x0565b07c) /* 0.337326511 */, 16 },
+ /* 1814 */ { MAD_F(0x0566b4a3) /* 0.337574614 */, 16 },
+ /* 1815 */ { MAD_F(0x0567b8d7) /* 0.337822762 */, 16 },
+ /* 1816 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 16 },
+ /* 1817 */ { MAD_F(0x0569c163) /* 0.338319195 */, 16 },
+ /* 1818 */ { MAD_F(0x056ac5bc) /* 0.338567480 */, 16 },
+ /* 1819 */ { MAD_F(0x056bca20) /* 0.338815811 */, 16 },
+ /* 1820 */ { MAD_F(0x056cce91) /* 0.339064186 */, 16 },
+ /* 1821 */ { MAD_F(0x056dd30e) /* 0.339312608 */, 16 },
+ /* 1822 */ { MAD_F(0x056ed798) /* 0.339561075 */, 16 },
+ /* 1823 */ { MAD_F(0x056fdc2d) /* 0.339809587 */, 16 },
+
+ /* 1824 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 16 },
+ /* 1825 */ { MAD_F(0x0571e57d) /* 0.340306748 */, 16 },
+ /* 1826 */ { MAD_F(0x0572ea37) /* 0.340555397 */, 16 },
+ /* 1827 */ { MAD_F(0x0573eefd) /* 0.340804091 */, 16 },
+ /* 1828 */ { MAD_F(0x0574f3d0) /* 0.341052830 */, 16 },
+ /* 1829 */ { MAD_F(0x0575f8ae) /* 0.341301615 */, 16 },
+ /* 1830 */ { MAD_F(0x0576fd99) /* 0.341550445 */, 16 },
+ /* 1831 */ { MAD_F(0x05780290) /* 0.341799321 */, 16 },
+ /* 1832 */ { MAD_F(0x05790793) /* 0.342048241 */, 16 },
+ /* 1833 */ { MAD_F(0x057a0ca3) /* 0.342297207 */, 16 },
+ /* 1834 */ { MAD_F(0x057b11be) /* 0.342546219 */, 16 },
+ /* 1835 */ { MAD_F(0x057c16e6) /* 0.342795275 */, 16 },
+ /* 1836 */ { MAD_F(0x057d1c1a) /* 0.343044377 */, 16 },
+ /* 1837 */ { MAD_F(0x057e2159) /* 0.343293524 */, 16 },
+ /* 1838 */ { MAD_F(0x057f26a6) /* 0.343542717 */, 16 },
+ /* 1839 */ { MAD_F(0x05802bfe) /* 0.343791954 */, 16 },
+
+ /* 1840 */ { MAD_F(0x05813162) /* 0.344041237 */, 16 },
+ /* 1841 */ { MAD_F(0x058236d2) /* 0.344290564 */, 16 },
+ /* 1842 */ { MAD_F(0x05833c4f) /* 0.344539937 */, 16 },
+ /* 1843 */ { MAD_F(0x058441d8) /* 0.344789356 */, 16 },
+ /* 1844 */ { MAD_F(0x0585476c) /* 0.345038819 */, 16 },
+ /* 1845 */ { MAD_F(0x05864d0d) /* 0.345288327 */, 16 },
+ /* 1846 */ { MAD_F(0x058752ba) /* 0.345537880 */, 16 },
+ /* 1847 */ { MAD_F(0x05885873) /* 0.345787479 */, 16 },
+ /* 1848 */ { MAD_F(0x05895e39) /* 0.346037122 */, 16 },
+ /* 1849 */ { MAD_F(0x058a640a) /* 0.346286811 */, 16 },
+ /* 1850 */ { MAD_F(0x058b69e7) /* 0.346536545 */, 16 },
+ /* 1851 */ { MAD_F(0x058c6fd1) /* 0.346786323 */, 16 },
+ /* 1852 */ { MAD_F(0x058d75c6) /* 0.347036147 */, 16 },
+ /* 1853 */ { MAD_F(0x058e7bc8) /* 0.347286015 */, 16 },
+ /* 1854 */ { MAD_F(0x058f81d5) /* 0.347535929 */, 16 },
+ /* 1855 */ { MAD_F(0x059087ef) /* 0.347785887 */, 16 },
+
+ /* 1856 */ { MAD_F(0x05918e15) /* 0.348035890 */, 16 },
+ /* 1857 */ { MAD_F(0x05929447) /* 0.348285939 */, 16 },
+ /* 1858 */ { MAD_F(0x05939a84) /* 0.348536032 */, 16 },
+ /* 1859 */ { MAD_F(0x0594a0ce) /* 0.348786170 */, 16 },
+ /* 1860 */ { MAD_F(0x0595a724) /* 0.349036353 */, 16 },
+ /* 1861 */ { MAD_F(0x0596ad86) /* 0.349286580 */, 16 },
+ /* 1862 */ { MAD_F(0x0597b3f4) /* 0.349536853 */, 16 },
+ /* 1863 */ { MAD_F(0x0598ba6e) /* 0.349787170 */, 16 },
+ /* 1864 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 16 },
+ /* 1865 */ { MAD_F(0x059ac786) /* 0.350287939 */, 16 },
+ /* 1866 */ { MAD_F(0x059bce25) /* 0.350538391 */, 16 },
+ /* 1867 */ { MAD_F(0x059cd4cf) /* 0.350788887 */, 16 },
+ /* 1868 */ { MAD_F(0x059ddb85) /* 0.351039428 */, 16 },
+ /* 1869 */ { MAD_F(0x059ee247) /* 0.351290014 */, 16 },
+ /* 1870 */ { MAD_F(0x059fe915) /* 0.351540645 */, 16 },
+ /* 1871 */ { MAD_F(0x05a0efef) /* 0.351791320 */, 16 },
+
+ /* 1872 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 16 },
+ /* 1873 */ { MAD_F(0x05a2fdc7) /* 0.352292804 */, 16 },
+ /* 1874 */ { MAD_F(0x05a404c5) /* 0.352543613 */, 16 },
+ /* 1875 */ { MAD_F(0x05a50bcf) /* 0.352794467 */, 16 },
+ /* 1876 */ { MAD_F(0x05a612e5) /* 0.353045365 */, 16 },
+ /* 1877 */ { MAD_F(0x05a71a07) /* 0.353296308 */, 16 },
+ /* 1878 */ { MAD_F(0x05a82135) /* 0.353547296 */, 16 },
+ /* 1879 */ { MAD_F(0x05a9286f) /* 0.353798328 */, 16 },
+ /* 1880 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 16 },
+ /* 1881 */ { MAD_F(0x05ab3707) /* 0.354300526 */, 16 },
+ /* 1882 */ { MAD_F(0x05ac3e65) /* 0.354551691 */, 16 },
+ /* 1883 */ { MAD_F(0x05ad45ce) /* 0.354802901 */, 16 },
+ /* 1884 */ { MAD_F(0x05ae4d44) /* 0.355054156 */, 16 },
+ /* 1885 */ { MAD_F(0x05af54c6) /* 0.355305455 */, 16 },
+ /* 1886 */ { MAD_F(0x05b05c53) /* 0.355556799 */, 16 },
+ /* 1887 */ { MAD_F(0x05b163ed) /* 0.355808187 */, 16 },
+
+ /* 1888 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 16 },
+ /* 1889 */ { MAD_F(0x05b37343) /* 0.356311096 */, 16 },
+ /* 1890 */ { MAD_F(0x05b47b00) /* 0.356562617 */, 16 },
+ /* 1891 */ { MAD_F(0x05b582c9) /* 0.356814182 */, 16 },
+ /* 1892 */ { MAD_F(0x05b68a9e) /* 0.357065792 */, 16 },
+ /* 1893 */ { MAD_F(0x05b7927f) /* 0.357317446 */, 16 },
+ /* 1894 */ { MAD_F(0x05b89a6c) /* 0.357569145 */, 16 },
+ /* 1895 */ { MAD_F(0x05b9a265) /* 0.357820887 */, 16 },
+ /* 1896 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 16 },
+ /* 1897 */ { MAD_F(0x05bbb27a) /* 0.358324506 */, 16 },
+ /* 1898 */ { MAD_F(0x05bcba96) /* 0.358576381 */, 16 },
+ /* 1899 */ { MAD_F(0x05bdc2be) /* 0.358828301 */, 16 },
+ /* 1900 */ { MAD_F(0x05becaf2) /* 0.359080265 */, 16 },
+ /* 1901 */ { MAD_F(0x05bfd332) /* 0.359332273 */, 16 },
+ /* 1902 */ { MAD_F(0x05c0db7e) /* 0.359584326 */, 16 },
+ /* 1903 */ { MAD_F(0x05c1e3d6) /* 0.359836423 */, 16 },
+
+ /* 1904 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 16 },
+ /* 1905 */ { MAD_F(0x05c3f4a9) /* 0.360340748 */, 16 },
+ /* 1906 */ { MAD_F(0x05c4fd24) /* 0.360592977 */, 16 },
+ /* 1907 */ { MAD_F(0x05c605ab) /* 0.360845251 */, 16 },
+ /* 1908 */ { MAD_F(0x05c70e3e) /* 0.361097568 */, 16 },
+ /* 1909 */ { MAD_F(0x05c816dd) /* 0.361349929 */, 16 },
+ /* 1910 */ { MAD_F(0x05c91f87) /* 0.361602335 */, 16 },
+ /* 1911 */ { MAD_F(0x05ca283e) /* 0.361854784 */, 16 },
+ /* 1912 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 16 },
+ /* 1913 */ { MAD_F(0x05cc39ce) /* 0.362359815 */, 16 },
+ /* 1914 */ { MAD_F(0x05cd42a8) /* 0.362612397 */, 16 },
+ /* 1915 */ { MAD_F(0x05ce4b8d) /* 0.362865022 */, 16 },
+ /* 1916 */ { MAD_F(0x05cf547f) /* 0.363117692 */, 16 },
+ /* 1917 */ { MAD_F(0x05d05d7c) /* 0.363370405 */, 16 },
+ /* 1918 */ { MAD_F(0x05d16685) /* 0.363623163 */, 16 },
+ /* 1919 */ { MAD_F(0x05d26f9a) /* 0.363875964 */, 16 },
+
+ /* 1920 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 16 },
+ /* 1921 */ { MAD_F(0x05d481e7) /* 0.364381698 */, 16 },
+ /* 1922 */ { MAD_F(0x05d58b1f) /* 0.364634632 */, 16 },
+ /* 1923 */ { MAD_F(0x05d69463) /* 0.364887608 */, 16 },
+ /* 1924 */ { MAD_F(0x05d79db3) /* 0.365140629 */, 16 },
+ /* 1925 */ { MAD_F(0x05d8a70f) /* 0.365393694 */, 16 },
+ /* 1926 */ { MAD_F(0x05d9b076) /* 0.365646802 */, 16 },
+ /* 1927 */ { MAD_F(0x05dab9e9) /* 0.365899955 */, 16 },
+ /* 1928 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 16 },
+ /* 1929 */ { MAD_F(0x05dcccf2) /* 0.366406390 */, 16 },
+ /* 1930 */ { MAD_F(0x05ddd689) /* 0.366659674 */, 16 },
+ /* 1931 */ { MAD_F(0x05dee02b) /* 0.366913001 */, 16 },
+ /* 1932 */ { MAD_F(0x05dfe9d8) /* 0.367166372 */, 16 },
+ /* 1933 */ { MAD_F(0x05e0f392) /* 0.367419787 */, 16 },
+ /* 1934 */ { MAD_F(0x05e1fd57) /* 0.367673246 */, 16 },
+ /* 1935 */ { MAD_F(0x05e30728) /* 0.367926748 */, 16 },
+
+ /* 1936 */ { MAD_F(0x05e41105) /* 0.368180294 */, 16 },
+ /* 1937 */ { MAD_F(0x05e51aed) /* 0.368433883 */, 16 },
+ /* 1938 */ { MAD_F(0x05e624e1) /* 0.368687517 */, 16 },
+ /* 1939 */ { MAD_F(0x05e72ee1) /* 0.368941193 */, 16 },
+ /* 1940 */ { MAD_F(0x05e838ed) /* 0.369194914 */, 16 },
+ /* 1941 */ { MAD_F(0x05e94304) /* 0.369448678 */, 16 },
+ /* 1942 */ { MAD_F(0x05ea4d27) /* 0.369702485 */, 16 },
+ /* 1943 */ { MAD_F(0x05eb5756) /* 0.369956336 */, 16 },
+ /* 1944 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 16 },
+ /* 1945 */ { MAD_F(0x05ed6bd6) /* 0.370464169 */, 16 },
+ /* 1946 */ { MAD_F(0x05ee7628) /* 0.370718151 */, 16 },
+ /* 1947 */ { MAD_F(0x05ef8085) /* 0.370972177 */, 16 },
+ /* 1948 */ { MAD_F(0x05f08aee) /* 0.371226245 */, 16 },
+ /* 1949 */ { MAD_F(0x05f19563) /* 0.371480358 */, 16 },
+ /* 1950 */ { MAD_F(0x05f29fe3) /* 0.371734513 */, 16 },
+ /* 1951 */ { MAD_F(0x05f3aa6f) /* 0.371988712 */, 16 },
+
+ /* 1952 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 16 },
+ /* 1953 */ { MAD_F(0x05f5bfab) /* 0.372497241 */, 16 },
+ /* 1954 */ { MAD_F(0x05f6ca5a) /* 0.372751570 */, 16 },
+ /* 1955 */ { MAD_F(0x05f7d514) /* 0.373005943 */, 16 },
+ /* 1956 */ { MAD_F(0x05f8dfdb) /* 0.373260359 */, 16 },
+ /* 1957 */ { MAD_F(0x05f9eaad) /* 0.373514819 */, 16 },
+ /* 1958 */ { MAD_F(0x05faf58a) /* 0.373769322 */, 16 },
+ /* 1959 */ { MAD_F(0x05fc0073) /* 0.374023868 */, 16 },
+ /* 1960 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 16 },
+ /* 1961 */ { MAD_F(0x05fe1669) /* 0.374533091 */, 16 },
+ /* 1962 */ { MAD_F(0x05ff2175) /* 0.374787767 */, 16 },
+ /* 1963 */ { MAD_F(0x06002c8d) /* 0.375042486 */, 16 },
+ /* 1964 */ { MAD_F(0x060137b0) /* 0.375297249 */, 16 },
+ /* 1965 */ { MAD_F(0x060242df) /* 0.375552055 */, 16 },
+ /* 1966 */ { MAD_F(0x06034e19) /* 0.375806904 */, 16 },
+ /* 1967 */ { MAD_F(0x0604595f) /* 0.376061796 */, 16 },
+
+ /* 1968 */ { MAD_F(0x060564b1) /* 0.376316732 */, 16 },
+ /* 1969 */ { MAD_F(0x0606700f) /* 0.376571710 */, 16 },
+ /* 1970 */ { MAD_F(0x06077b77) /* 0.376826732 */, 16 },
+ /* 1971 */ { MAD_F(0x060886ec) /* 0.377081797 */, 16 },
+ /* 1972 */ { MAD_F(0x0609926c) /* 0.377336905 */, 16 },
+ /* 1973 */ { MAD_F(0x060a9df8) /* 0.377592057 */, 16 },
+ /* 1974 */ { MAD_F(0x060ba98f) /* 0.377847251 */, 16 },
+ /* 1975 */ { MAD_F(0x060cb532) /* 0.378102489 */, 16 },
+ /* 1976 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 16 },
+ /* 1977 */ { MAD_F(0x060ecc9a) /* 0.378613093 */, 16 },
+ /* 1978 */ { MAD_F(0x060fd860) /* 0.378868460 */, 16 },
+ /* 1979 */ { MAD_F(0x0610e431) /* 0.379123870 */, 16 },
+ /* 1980 */ { MAD_F(0x0611f00d) /* 0.379379322 */, 16 },
+ /* 1981 */ { MAD_F(0x0612fbf5) /* 0.379634818 */, 16 },
+ /* 1982 */ { MAD_F(0x061407e9) /* 0.379890357 */, 16 },
+ /* 1983 */ { MAD_F(0x061513e8) /* 0.380145939 */, 16 },
+
+ /* 1984 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 16 },
+ /* 1985 */ { MAD_F(0x06172c09) /* 0.380657231 */, 16 },
+ /* 1986 */ { MAD_F(0x0618382b) /* 0.380912942 */, 16 },
+ /* 1987 */ { MAD_F(0x06194458) /* 0.381168695 */, 16 },
+ /* 1988 */ { MAD_F(0x061a5091) /* 0.381424492 */, 16 },
+ /* 1989 */ { MAD_F(0x061b5cd5) /* 0.381680331 */, 16 },
+ /* 1990 */ { MAD_F(0x061c6925) /* 0.381936213 */, 16 },
+ /* 1991 */ { MAD_F(0x061d7581) /* 0.382192138 */, 16 },
+ /* 1992 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 16 },
+ /* 1993 */ { MAD_F(0x061f8e5a) /* 0.382704117 */, 16 },
+ /* 1994 */ { MAD_F(0x06209ad8) /* 0.382960171 */, 16 },
+ /* 1995 */ { MAD_F(0x0621a761) /* 0.383216267 */, 16 },
+ /* 1996 */ { MAD_F(0x0622b3f6) /* 0.383472406 */, 16 },
+ /* 1997 */ { MAD_F(0x0623c096) /* 0.383728588 */, 16 },
+ /* 1998 */ { MAD_F(0x0624cd42) /* 0.383984813 */, 16 },
+ /* 1999 */ { MAD_F(0x0625d9f9) /* 0.384241080 */, 16 },
+
+ /* 2000 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 16 },
+ /* 2001 */ { MAD_F(0x0627f38a) /* 0.384753744 */, 16 },
+ /* 2002 */ { MAD_F(0x06290064) /* 0.385010139 */, 16 },
+ /* 2003 */ { MAD_F(0x062a0d49) /* 0.385266578 */, 16 },
+ /* 2004 */ { MAD_F(0x062b1a3a) /* 0.385523059 */, 16 },
+ /* 2005 */ { MAD_F(0x062c2736) /* 0.385779582 */, 16 },
+ /* 2006 */ { MAD_F(0x062d343d) /* 0.386036149 */, 16 },
+ /* 2007 */ { MAD_F(0x062e4150) /* 0.386292758 */, 16 },
+ /* 2008 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 16 },
+ /* 2009 */ { MAD_F(0x06305b99) /* 0.386806104 */, 16 },
+ /* 2010 */ { MAD_F(0x063168ce) /* 0.387062840 */, 16 },
+ /* 2011 */ { MAD_F(0x0632760f) /* 0.387319620 */, 16 },
+ /* 2012 */ { MAD_F(0x0633835b) /* 0.387576442 */, 16 },
+ /* 2013 */ { MAD_F(0x063490b2) /* 0.387833306 */, 16 },
+ /* 2014 */ { MAD_F(0x06359e15) /* 0.388090213 */, 16 },
+ /* 2015 */ { MAD_F(0x0636ab83) /* 0.388347163 */, 16 },
+
+ /* 2016 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 16 },
+ /* 2017 */ { MAD_F(0x0638c682) /* 0.388861190 */, 16 },
+ /* 2018 */ { MAD_F(0x0639d413) /* 0.389118267 */, 16 },
+ /* 2019 */ { MAD_F(0x063ae1af) /* 0.389375386 */, 16 },
+ /* 2020 */ { MAD_F(0x063bef56) /* 0.389632548 */, 16 },
+ /* 2021 */ { MAD_F(0x063cfd09) /* 0.389889752 */, 16 },
+ /* 2022 */ { MAD_F(0x063e0ac7) /* 0.390146999 */, 16 },
+ /* 2023 */ { MAD_F(0x063f1891) /* 0.390404289 */, 16 },
+ /* 2024 */ { MAD_F(0x06402666) /* 0.390661620 */, 16 },
+ /* 2025 */ { MAD_F(0x06413446) /* 0.390918994 */, 16 },
+ /* 2026 */ { MAD_F(0x06424232) /* 0.391176411 */, 16 },
+ /* 2027 */ { MAD_F(0x06435029) /* 0.391433869 */, 16 },
+ /* 2028 */ { MAD_F(0x06445e2b) /* 0.391691371 */, 16 },
+ /* 2029 */ { MAD_F(0x06456c39) /* 0.391948914 */, 16 },
+ /* 2030 */ { MAD_F(0x06467a52) /* 0.392206500 */, 16 },
+ /* 2031 */ { MAD_F(0x06478877) /* 0.392464128 */, 16 },
+
+ /* 2032 */ { MAD_F(0x064896a7) /* 0.392721798 */, 16 },
+ /* 2033 */ { MAD_F(0x0649a4e2) /* 0.392979511 */, 16 },
+ /* 2034 */ { MAD_F(0x064ab328) /* 0.393237266 */, 16 },
+ /* 2035 */ { MAD_F(0x064bc17a) /* 0.393495063 */, 16 },
+ /* 2036 */ { MAD_F(0x064ccfd8) /* 0.393752902 */, 16 },
+ /* 2037 */ { MAD_F(0x064dde40) /* 0.394010784 */, 16 },
+ /* 2038 */ { MAD_F(0x064eecb4) /* 0.394268707 */, 16 },
+ /* 2039 */ { MAD_F(0x064ffb33) /* 0.394526673 */, 16 },
+ /* 2040 */ { MAD_F(0x065109be) /* 0.394784681 */, 16 },
+ /* 2041 */ { MAD_F(0x06521854) /* 0.395042732 */, 16 },
+ /* 2042 */ { MAD_F(0x065326f5) /* 0.395300824 */, 16 },
+ /* 2043 */ { MAD_F(0x065435a1) /* 0.395558959 */, 16 },
+ /* 2044 */ { MAD_F(0x06554459) /* 0.395817135 */, 16 },
+ /* 2045 */ { MAD_F(0x0656531c) /* 0.396075354 */, 16 },
+ /* 2046 */ { MAD_F(0x065761ea) /* 0.396333615 */, 16 },
+ /* 2047 */ { MAD_F(0x065870c4) /* 0.396591918 */, 16 },
+
+ /* 2048 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 16 },
+ /* 2049 */ { MAD_F(0x065a8e99) /* 0.397108650 */, 16 },
+ /* 2050 */ { MAD_F(0x065b9d95) /* 0.397367079 */, 16 },
+ /* 2051 */ { MAD_F(0x065cac9c) /* 0.397625550 */, 16 },
+ /* 2052 */ { MAD_F(0x065dbbae) /* 0.397884063 */, 16 },
+ /* 2053 */ { MAD_F(0x065ecacb) /* 0.398142619 */, 16 },
+ /* 2054 */ { MAD_F(0x065fd9f4) /* 0.398401216 */, 16 },
+ /* 2055 */ { MAD_F(0x0660e928) /* 0.398659855 */, 16 },
+ /* 2056 */ { MAD_F(0x0661f867) /* 0.398918536 */, 16 },
+ /* 2057 */ { MAD_F(0x066307b1) /* 0.399177259 */, 16 },
+ /* 2058 */ { MAD_F(0x06641707) /* 0.399436024 */, 16 },
+ /* 2059 */ { MAD_F(0x06652668) /* 0.399694831 */, 16 },
+ /* 2060 */ { MAD_F(0x066635d4) /* 0.399953679 */, 16 },
+ /* 2061 */ { MAD_F(0x0667454c) /* 0.400212570 */, 16 },
+ /* 2062 */ { MAD_F(0x066854ce) /* 0.400471503 */, 16 },
+ /* 2063 */ { MAD_F(0x0669645c) /* 0.400730477 */, 16 },
+
+ /* 2064 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 16 },
+ /* 2065 */ { MAD_F(0x066b839a) /* 0.401248551 */, 16 },
+ /* 2066 */ { MAD_F(0x066c9349) /* 0.401507651 */, 16 },
+ /* 2067 */ { MAD_F(0x066da304) /* 0.401766793 */, 16 },
+ /* 2068 */ { MAD_F(0x066eb2ca) /* 0.402025976 */, 16 },
+ /* 2069 */ { MAD_F(0x066fc29b) /* 0.402285202 */, 16 },
+ /* 2070 */ { MAD_F(0x0670d278) /* 0.402544469 */, 16 },
+ /* 2071 */ { MAD_F(0x0671e25f) /* 0.402803777 */, 16 },
+ /* 2072 */ { MAD_F(0x0672f252) /* 0.403063128 */, 16 },
+ /* 2073 */ { MAD_F(0x06740250) /* 0.403322520 */, 16 },
+ /* 2074 */ { MAD_F(0x0675125a) /* 0.403581954 */, 16 },
+ /* 2075 */ { MAD_F(0x0676226e) /* 0.403841430 */, 16 },
+ /* 2076 */ { MAD_F(0x0677328e) /* 0.404100947 */, 16 },
+ /* 2077 */ { MAD_F(0x067842b9) /* 0.404360506 */, 16 },
+ /* 2078 */ { MAD_F(0x067952ef) /* 0.404620107 */, 16 },
+ /* 2079 */ { MAD_F(0x067a6330) /* 0.404879749 */, 16 },
+
+ /* 2080 */ { MAD_F(0x067b737c) /* 0.405139433 */, 16 },
+ /* 2081 */ { MAD_F(0x067c83d4) /* 0.405399159 */, 16 },
+ /* 2082 */ { MAD_F(0x067d9436) /* 0.405658926 */, 16 },
+ /* 2083 */ { MAD_F(0x067ea4a4) /* 0.405918735 */, 16 },
+ /* 2084 */ { MAD_F(0x067fb51d) /* 0.406178585 */, 16 },
+ /* 2085 */ { MAD_F(0x0680c5a2) /* 0.406438477 */, 16 },
+ /* 2086 */ { MAD_F(0x0681d631) /* 0.406698410 */, 16 },
+ /* 2087 */ { MAD_F(0x0682e6cb) /* 0.406958385 */, 16 },
+ /* 2088 */ { MAD_F(0x0683f771) /* 0.407218402 */, 16 },
+ /* 2089 */ { MAD_F(0x06850822) /* 0.407478460 */, 16 },
+ /* 2090 */ { MAD_F(0x068618de) /* 0.407738559 */, 16 },
+ /* 2091 */ { MAD_F(0x068729a5) /* 0.407998700 */, 16 },
+ /* 2092 */ { MAD_F(0x06883a77) /* 0.408258883 */, 16 },
+ /* 2093 */ { MAD_F(0x06894b55) /* 0.408519107 */, 16 },
+ /* 2094 */ { MAD_F(0x068a5c3d) /* 0.408779372 */, 16 },
+ /* 2095 */ { MAD_F(0x068b6d31) /* 0.409039679 */, 16 },
+
+ /* 2096 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 16 },
+ /* 2097 */ { MAD_F(0x068d8f39) /* 0.409560417 */, 16 },
+ /* 2098 */ { MAD_F(0x068ea04e) /* 0.409820848 */, 16 },
+ /* 2099 */ { MAD_F(0x068fb16e) /* 0.410081321 */, 16 },
+ /* 2100 */ { MAD_F(0x0690c299) /* 0.410341834 */, 16 },
+ /* 2101 */ { MAD_F(0x0691d3cf) /* 0.410602390 */, 16 },
+ /* 2102 */ { MAD_F(0x0692e511) /* 0.410862986 */, 16 },
+ /* 2103 */ { MAD_F(0x0693f65d) /* 0.411123624 */, 16 },
+ /* 2104 */ { MAD_F(0x069507b5) /* 0.411384303 */, 16 },
+ /* 2105 */ { MAD_F(0x06961917) /* 0.411645024 */, 16 },
+ /* 2106 */ { MAD_F(0x06972a85) /* 0.411905785 */, 16 },
+ /* 2107 */ { MAD_F(0x06983bfe) /* 0.412166588 */, 16 },
+ /* 2108 */ { MAD_F(0x06994d82) /* 0.412427433 */, 16 },
+ /* 2109 */ { MAD_F(0x069a5f11) /* 0.412688318 */, 16 },
+ /* 2110 */ { MAD_F(0x069b70ab) /* 0.412949245 */, 16 },
+ /* 2111 */ { MAD_F(0x069c8250) /* 0.413210213 */, 16 },
+
+ /* 2112 */ { MAD_F(0x069d9400) /* 0.413471222 */, 16 },
+ /* 2113 */ { MAD_F(0x069ea5bb) /* 0.413732273 */, 16 },
+ /* 2114 */ { MAD_F(0x069fb781) /* 0.413993364 */, 16 },
+ /* 2115 */ { MAD_F(0x06a0c953) /* 0.414254497 */, 16 },
+ /* 2116 */ { MAD_F(0x06a1db2f) /* 0.414515671 */, 16 },
+ /* 2117 */ { MAD_F(0x06a2ed16) /* 0.414776886 */, 16 },
+ /* 2118 */ { MAD_F(0x06a3ff09) /* 0.415038142 */, 16 },
+ /* 2119 */ { MAD_F(0x06a51106) /* 0.415299440 */, 16 },
+ /* 2120 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 16 },
+ /* 2121 */ { MAD_F(0x06a73522) /* 0.415822157 */, 16 },
+ /* 2122 */ { MAD_F(0x06a84741) /* 0.416083578 */, 16 },
+ /* 2123 */ { MAD_F(0x06a9596a) /* 0.416345040 */, 16 },
+ /* 2124 */ { MAD_F(0x06aa6b9f) /* 0.416606542 */, 16 },
+ /* 2125 */ { MAD_F(0x06ab7ddf) /* 0.416868086 */, 16 },
+ /* 2126 */ { MAD_F(0x06ac9029) /* 0.417129671 */, 16 },
+ /* 2127 */ { MAD_F(0x06ada27f) /* 0.417391297 */, 16 },
+
+ /* 2128 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 16 },
+ /* 2129 */ { MAD_F(0x06afc74b) /* 0.417914672 */, 16 },
+ /* 2130 */ { MAD_F(0x06b0d9c2) /* 0.418176420 */, 16 },
+ /* 2131 */ { MAD_F(0x06b1ec43) /* 0.418438210 */, 16 },
+ /* 2132 */ { MAD_F(0x06b2fed0) /* 0.418700041 */, 16 },
+ /* 2133 */ { MAD_F(0x06b41168) /* 0.418961912 */, 16 },
+ /* 2134 */ { MAD_F(0x06b5240a) /* 0.419223825 */, 16 },
+ /* 2135 */ { MAD_F(0x06b636b8) /* 0.419485778 */, 16 },
+ /* 2136 */ { MAD_F(0x06b74971) /* 0.419747773 */, 16 },
+ /* 2137 */ { MAD_F(0x06b85c34) /* 0.420009808 */, 16 },
+ /* 2138 */ { MAD_F(0x06b96f03) /* 0.420271884 */, 16 },
+ /* 2139 */ { MAD_F(0x06ba81dc) /* 0.420534001 */, 16 },
+ /* 2140 */ { MAD_F(0x06bb94c1) /* 0.420796159 */, 16 },
+ /* 2141 */ { MAD_F(0x06bca7b0) /* 0.421058358 */, 16 },
+ /* 2142 */ { MAD_F(0x06bdbaaa) /* 0.421320597 */, 16 },
+ /* 2143 */ { MAD_F(0x06becdb0) /* 0.421582878 */, 16 },
+
+ /* 2144 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 16 },
+ /* 2145 */ { MAD_F(0x06c0f3db) /* 0.422107561 */, 16 },
+ /* 2146 */ { MAD_F(0x06c20702) /* 0.422369964 */, 16 },
+ /* 2147 */ { MAD_F(0x06c31a33) /* 0.422632407 */, 16 },
+ /* 2148 */ { MAD_F(0x06c42d6f) /* 0.422894891 */, 16 },
+ /* 2149 */ { MAD_F(0x06c540b6) /* 0.423157416 */, 16 },
+ /* 2150 */ { MAD_F(0x06c65408) /* 0.423419982 */, 16 },
+ /* 2151 */ { MAD_F(0x06c76765) /* 0.423682588 */, 16 },
+ /* 2152 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 16 },
+ /* 2153 */ { MAD_F(0x06c98e3f) /* 0.424207923 */, 16 },
+ /* 2154 */ { MAD_F(0x06caa1bd) /* 0.424470652 */, 16 },
+ /* 2155 */ { MAD_F(0x06cbb545) /* 0.424733421 */, 16 },
+ /* 2156 */ { MAD_F(0x06ccc8d9) /* 0.424996230 */, 16 },
+ /* 2157 */ { MAD_F(0x06cddc77) /* 0.425259081 */, 16 },
+ /* 2158 */ { MAD_F(0x06cef020) /* 0.425521972 */, 16 },
+ /* 2159 */ { MAD_F(0x06d003d4) /* 0.425784903 */, 16 },
+
+ /* 2160 */ { MAD_F(0x06d11794) /* 0.426047876 */, 16 },
+ /* 2161 */ { MAD_F(0x06d22b5e) /* 0.426310889 */, 16 },
+ /* 2162 */ { MAD_F(0x06d33f32) /* 0.426573942 */, 16 },
+ /* 2163 */ { MAD_F(0x06d45312) /* 0.426837036 */, 16 },
+ /* 2164 */ { MAD_F(0x06d566fd) /* 0.427100170 */, 16 },
+ /* 2165 */ { MAD_F(0x06d67af2) /* 0.427363345 */, 16 },
+ /* 2166 */ { MAD_F(0x06d78ef3) /* 0.427626561 */, 16 },
+ /* 2167 */ { MAD_F(0x06d8a2fe) /* 0.427889817 */, 16 },
+ /* 2168 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 16 },
+ /* 2169 */ { MAD_F(0x06dacb35) /* 0.428416451 */, 16 },
+ /* 2170 */ { MAD_F(0x06dbdf61) /* 0.428679828 */, 16 },
+ /* 2171 */ { MAD_F(0x06dcf398) /* 0.428943246 */, 16 },
+ /* 2172 */ { MAD_F(0x06de07d9) /* 0.429206704 */, 16 },
+ /* 2173 */ { MAD_F(0x06df1c26) /* 0.429470203 */, 16 },
+ /* 2174 */ { MAD_F(0x06e0307d) /* 0.429733743 */, 16 },
+ /* 2175 */ { MAD_F(0x06e144df) /* 0.429997322 */, 16 },
+
+ /* 2176 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 16 },
+ /* 2177 */ { MAD_F(0x06e36dc4) /* 0.430524603 */, 16 },
+ /* 2178 */ { MAD_F(0x06e48246) /* 0.430788304 */, 16 },
+ /* 2179 */ { MAD_F(0x06e596d4) /* 0.431052045 */, 16 },
+ /* 2180 */ { MAD_F(0x06e6ab6c) /* 0.431315826 */, 16 },
+ /* 2181 */ { MAD_F(0x06e7c00f) /* 0.431579648 */, 16 },
+ /* 2182 */ { MAD_F(0x06e8d4bd) /* 0.431843511 */, 16 },
+ /* 2183 */ { MAD_F(0x06e9e976) /* 0.432107413 */, 16 },
+ /* 2184 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 16 },
+ /* 2185 */ { MAD_F(0x06ec1308) /* 0.432635339 */, 16 },
+ /* 2186 */ { MAD_F(0x06ed27e2) /* 0.432899362 */, 16 },
+ /* 2187 */ { MAD_F(0x06ee3cc6) /* 0.433163426 */, 16 },
+ /* 2188 */ { MAD_F(0x06ef51b4) /* 0.433427530 */, 16 },
+ /* 2189 */ { MAD_F(0x06f066ae) /* 0.433691674 */, 16 },
+ /* 2190 */ { MAD_F(0x06f17bb3) /* 0.433955859 */, 16 },
+ /* 2191 */ { MAD_F(0x06f290c2) /* 0.434220083 */, 16 },
+
+ /* 2192 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 16 },
+ /* 2193 */ { MAD_F(0x06f4bb01) /* 0.434748653 */, 16 },
+ /* 2194 */ { MAD_F(0x06f5d030) /* 0.435012998 */, 16 },
+ /* 2195 */ { MAD_F(0x06f6e56b) /* 0.435277383 */, 16 },
+ /* 2196 */ { MAD_F(0x06f7fab0) /* 0.435541809 */, 16 },
+ /* 2197 */ { MAD_F(0x06f91000) /* 0.435806274 */, 16 },
+ /* 2198 */ { MAD_F(0x06fa255a) /* 0.436070780 */, 16 },
+ /* 2199 */ { MAD_F(0x06fb3ac0) /* 0.436335326 */, 16 },
+ /* 2200 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 16 },
+ /* 2201 */ { MAD_F(0x06fd65ab) /* 0.436864538 */, 16 },
+ /* 2202 */ { MAD_F(0x06fe7b31) /* 0.437129204 */, 16 },
+ /* 2203 */ { MAD_F(0x06ff90c2) /* 0.437393910 */, 16 },
+ /* 2204 */ { MAD_F(0x0700a65d) /* 0.437658657 */, 16 },
+ /* 2205 */ { MAD_F(0x0701bc03) /* 0.437923443 */, 16 },
+ /* 2206 */ { MAD_F(0x0702d1b4) /* 0.438188269 */, 16 },
+ /* 2207 */ { MAD_F(0x0703e76f) /* 0.438453136 */, 16 },
+
+ /* 2208 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 16 },
+ /* 2209 */ { MAD_F(0x07061306) /* 0.438982988 */, 16 },
+ /* 2210 */ { MAD_F(0x070728e2) /* 0.439247975 */, 16 },
+ /* 2211 */ { MAD_F(0x07083ec9) /* 0.439513001 */, 16 },
+ /* 2212 */ { MAD_F(0x070954ba) /* 0.439778067 */, 16 },
+ /* 2213 */ { MAD_F(0x070a6ab6) /* 0.440043173 */, 16 },
+ /* 2214 */ { MAD_F(0x070b80bc) /* 0.440308320 */, 16 },
+ /* 2215 */ { MAD_F(0x070c96ce) /* 0.440573506 */, 16 },
+ /* 2216 */ { MAD_F(0x070dacea) /* 0.440838732 */, 16 },
+ /* 2217 */ { MAD_F(0x070ec310) /* 0.441103997 */, 16 },
+ /* 2218 */ { MAD_F(0x070fd942) /* 0.441369303 */, 16 },
+ /* 2219 */ { MAD_F(0x0710ef7e) /* 0.441634649 */, 16 },
+ /* 2220 */ { MAD_F(0x071205c5) /* 0.441900034 */, 16 },
+ /* 2221 */ { MAD_F(0x07131c17) /* 0.442165460 */, 16 },
+ /* 2222 */ { MAD_F(0x07143273) /* 0.442430925 */, 16 },
+ /* 2223 */ { MAD_F(0x071548da) /* 0.442696430 */, 16 },
+
+ /* 2224 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 16 },
+ /* 2225 */ { MAD_F(0x071775c8) /* 0.443227559 */, 16 },
+ /* 2226 */ { MAD_F(0x07188c4f) /* 0.443493184 */, 16 },
+ /* 2227 */ { MAD_F(0x0719a2e0) /* 0.443758848 */, 16 },
+ /* 2228 */ { MAD_F(0x071ab97d) /* 0.444024552 */, 16 },
+ /* 2229 */ { MAD_F(0x071bd024) /* 0.444290296 */, 16 },
+ /* 2230 */ { MAD_F(0x071ce6d6) /* 0.444556079 */, 16 },
+ /* 2231 */ { MAD_F(0x071dfd92) /* 0.444821902 */, 16 },
+ /* 2232 */ { MAD_F(0x071f1459) /* 0.445087765 */, 16 },
+ /* 2233 */ { MAD_F(0x07202b2b) /* 0.445353668 */, 16 },
+ /* 2234 */ { MAD_F(0x07214207) /* 0.445619610 */, 16 },
+ /* 2235 */ { MAD_F(0x072258ee) /* 0.445885592 */, 16 },
+ /* 2236 */ { MAD_F(0x07236fe0) /* 0.446151614 */, 16 },
+ /* 2237 */ { MAD_F(0x072486dc) /* 0.446417675 */, 16 },
+ /* 2238 */ { MAD_F(0x07259de3) /* 0.446683776 */, 16 },
+ /* 2239 */ { MAD_F(0x0726b4f4) /* 0.446949917 */, 16 },
+
+ /* 2240 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 16 },
+ /* 2241 */ { MAD_F(0x0728e338) /* 0.447482317 */, 16 },
+ /* 2242 */ { MAD_F(0x0729fa69) /* 0.447748576 */, 16 },
+ /* 2243 */ { MAD_F(0x072b11a5) /* 0.448014875 */, 16 },
+ /* 2244 */ { MAD_F(0x072c28ec) /* 0.448281214 */, 16 },
+ /* 2245 */ { MAD_F(0x072d403d) /* 0.448547592 */, 16 },
+ /* 2246 */ { MAD_F(0x072e5799) /* 0.448814010 */, 16 },
+ /* 2247 */ { MAD_F(0x072f6f00) /* 0.449080467 */, 16 },
+ /* 2248 */ { MAD_F(0x07308671) /* 0.449346964 */, 16 },
+ /* 2249 */ { MAD_F(0x07319ded) /* 0.449613501 */, 16 },
+ /* 2250 */ { MAD_F(0x0732b573) /* 0.449880076 */, 16 },
+ /* 2251 */ { MAD_F(0x0733cd04) /* 0.450146692 */, 16 },
+ /* 2252 */ { MAD_F(0x0734e4a0) /* 0.450413347 */, 16 },
+ /* 2253 */ { MAD_F(0x0735fc46) /* 0.450680041 */, 16 },
+ /* 2254 */ { MAD_F(0x073713f7) /* 0.450946775 */, 16 },
+ /* 2255 */ { MAD_F(0x07382bb2) /* 0.451213548 */, 16 },
+
+ /* 2256 */ { MAD_F(0x07394378) /* 0.451480360 */, 16 },
+ /* 2257 */ { MAD_F(0x073a5b49) /* 0.451747213 */, 16 },
+ /* 2258 */ { MAD_F(0x073b7324) /* 0.452014104 */, 16 },
+ /* 2259 */ { MAD_F(0x073c8b0a) /* 0.452281035 */, 16 },
+ /* 2260 */ { MAD_F(0x073da2fa) /* 0.452548005 */, 16 },
+ /* 2261 */ { MAD_F(0x073ebaf5) /* 0.452815015 */, 16 },
+ /* 2262 */ { MAD_F(0x073fd2fa) /* 0.453082064 */, 16 },
+ /* 2263 */ { MAD_F(0x0740eb0a) /* 0.453349152 */, 16 },
+ /* 2264 */ { MAD_F(0x07420325) /* 0.453616280 */, 16 },
+ /* 2265 */ { MAD_F(0x07431b4a) /* 0.453883447 */, 16 },
+ /* 2266 */ { MAD_F(0x0744337a) /* 0.454150653 */, 16 },
+ /* 2267 */ { MAD_F(0x07454bb4) /* 0.454417899 */, 16 },
+ /* 2268 */ { MAD_F(0x074663f8) /* 0.454685184 */, 16 },
+ /* 2269 */ { MAD_F(0x07477c48) /* 0.454952508 */, 16 },
+ /* 2270 */ { MAD_F(0x074894a2) /* 0.455219872 */, 16 },
+ /* 2271 */ { MAD_F(0x0749ad06) /* 0.455487275 */, 16 },
+
+ /* 2272 */ { MAD_F(0x074ac575) /* 0.455754717 */, 16 },
+ /* 2273 */ { MAD_F(0x074bddee) /* 0.456022198 */, 16 },
+ /* 2274 */ { MAD_F(0x074cf672) /* 0.456289719 */, 16 },
+ /* 2275 */ { MAD_F(0x074e0f01) /* 0.456557278 */, 16 },
+ /* 2276 */ { MAD_F(0x074f279a) /* 0.456824877 */, 16 },
+ /* 2277 */ { MAD_F(0x0750403e) /* 0.457092516 */, 16 },
+ /* 2278 */ { MAD_F(0x075158ec) /* 0.457360193 */, 16 },
+ /* 2279 */ { MAD_F(0x075271a4) /* 0.457627909 */, 16 },
+ /* 2280 */ { MAD_F(0x07538a67) /* 0.457895665 */, 16 },
+ /* 2281 */ { MAD_F(0x0754a335) /* 0.458163460 */, 16 },
+ /* 2282 */ { MAD_F(0x0755bc0d) /* 0.458431294 */, 16 },
+ /* 2283 */ { MAD_F(0x0756d4f0) /* 0.458699167 */, 16 },
+ /* 2284 */ { MAD_F(0x0757eddd) /* 0.458967079 */, 16 },
+ /* 2285 */ { MAD_F(0x075906d5) /* 0.459235030 */, 16 },
+ /* 2286 */ { MAD_F(0x075a1fd7) /* 0.459503021 */, 16 },
+ /* 2287 */ { MAD_F(0x075b38e3) /* 0.459771050 */, 16 },
+
+ /* 2288 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 16 },
+ /* 2289 */ { MAD_F(0x075d6b1c) /* 0.460307226 */, 16 },
+ /* 2290 */ { MAD_F(0x075e8448) /* 0.460575373 */, 16 },
+ /* 2291 */ { MAD_F(0x075f9d7f) /* 0.460843559 */, 16 },
+ /* 2292 */ { MAD_F(0x0760b6c0) /* 0.461111783 */, 16 },
+ /* 2293 */ { MAD_F(0x0761d00b) /* 0.461380047 */, 16 },
+ /* 2294 */ { MAD_F(0x0762e961) /* 0.461648350 */, 16 },
+ /* 2295 */ { MAD_F(0x076402c1) /* 0.461916691 */, 16 },
+ /* 2296 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 16 },
+ /* 2297 */ { MAD_F(0x076635a2) /* 0.462453492 */, 16 },
+ /* 2298 */ { MAD_F(0x07674f22) /* 0.462721950 */, 16 },
+ /* 2299 */ { MAD_F(0x076868ac) /* 0.462990448 */, 16 },
+ /* 2300 */ { MAD_F(0x07698240) /* 0.463258984 */, 16 },
+ /* 2301 */ { MAD_F(0x076a9be0) /* 0.463527560 */, 16 },
+ /* 2302 */ { MAD_F(0x076bb589) /* 0.463796174 */, 16 },
+ /* 2303 */ { MAD_F(0x076ccf3d) /* 0.464064827 */, 16 },
+
+ /* 2304 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 16 },
+ /* 2305 */ { MAD_F(0x076f02c5) /* 0.464602250 */, 16 },
+ /* 2306 */ { MAD_F(0x07701c98) /* 0.464871020 */, 16 },
+ /* 2307 */ { MAD_F(0x07713676) /* 0.465139829 */, 16 },
+ /* 2308 */ { MAD_F(0x0772505e) /* 0.465408676 */, 16 },
+ /* 2309 */ { MAD_F(0x07736a51) /* 0.465677563 */, 16 },
+ /* 2310 */ { MAD_F(0x0774844e) /* 0.465946488 */, 16 },
+ /* 2311 */ { MAD_F(0x07759e55) /* 0.466215452 */, 16 },
+ /* 2312 */ { MAD_F(0x0776b867) /* 0.466484455 */, 16 },
+ /* 2313 */ { MAD_F(0x0777d283) /* 0.466753496 */, 16 },
+ /* 2314 */ { MAD_F(0x0778ecaa) /* 0.467022577 */, 16 },
+ /* 2315 */ { MAD_F(0x077a06db) /* 0.467291696 */, 16 },
+ /* 2316 */ { MAD_F(0x077b2117) /* 0.467560854 */, 16 },
+ /* 2317 */ { MAD_F(0x077c3b5d) /* 0.467830050 */, 16 },
+ /* 2318 */ { MAD_F(0x077d55ad) /* 0.468099285 */, 16 },
+ /* 2319 */ { MAD_F(0x077e7008) /* 0.468368560 */, 16 },
+
+ /* 2320 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 16 },
+ /* 2321 */ { MAD_F(0x0780a4dc) /* 0.468907224 */, 16 },
+ /* 2322 */ { MAD_F(0x0781bf56) /* 0.469176614 */, 16 },
+ /* 2323 */ { MAD_F(0x0782d9da) /* 0.469446043 */, 16 },
+ /* 2324 */ { MAD_F(0x0783f469) /* 0.469715510 */, 16 },
+ /* 2325 */ { MAD_F(0x07850f02) /* 0.469985016 */, 16 },
+ /* 2326 */ { MAD_F(0x078629a5) /* 0.470254561 */, 16 },
+ /* 2327 */ { MAD_F(0x07874453) /* 0.470524145 */, 16 },
+ /* 2328 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 16 },
+ /* 2329 */ { MAD_F(0x078979ce) /* 0.471063427 */, 16 },
+ /* 2330 */ { MAD_F(0x078a949a) /* 0.471333126 */, 16 },
+ /* 2331 */ { MAD_F(0x078baf72) /* 0.471602864 */, 16 },
+ /* 2332 */ { MAD_F(0x078cca53) /* 0.471872641 */, 16 },
+ /* 2333 */ { MAD_F(0x078de53f) /* 0.472142456 */, 16 },
+ /* 2334 */ { MAD_F(0x078f0035) /* 0.472412309 */, 16 },
+ /* 2335 */ { MAD_F(0x07901b36) /* 0.472682201 */, 16 },
+
+ /* 2336 */ { MAD_F(0x07913641) /* 0.472952132 */, 16 },
+ /* 2337 */ { MAD_F(0x07925156) /* 0.473222101 */, 16 },
+ /* 2338 */ { MAD_F(0x07936c76) /* 0.473492108 */, 16 },
+ /* 2339 */ { MAD_F(0x079487a0) /* 0.473762155 */, 16 },
+ /* 2340 */ { MAD_F(0x0795a2d4) /* 0.474032239 */, 16 },
+ /* 2341 */ { MAD_F(0x0796be13) /* 0.474302362 */, 16 },
+ /* 2342 */ { MAD_F(0x0797d95c) /* 0.474572524 */, 16 },
+ /* 2343 */ { MAD_F(0x0798f4af) /* 0.474842724 */, 16 },
+ /* 2344 */ { MAD_F(0x079a100c) /* 0.475112962 */, 16 },
+ /* 2345 */ { MAD_F(0x079b2b74) /* 0.475383239 */, 16 },
+ /* 2346 */ { MAD_F(0x079c46e7) /* 0.475653554 */, 16 },
+ /* 2347 */ { MAD_F(0x079d6263) /* 0.475923908 */, 16 },
+ /* 2348 */ { MAD_F(0x079e7dea) /* 0.476194300 */, 16 },
+ /* 2349 */ { MAD_F(0x079f997b) /* 0.476464731 */, 16 },
+ /* 2350 */ { MAD_F(0x07a0b516) /* 0.476735200 */, 16 },
+ /* 2351 */ { MAD_F(0x07a1d0bc) /* 0.477005707 */, 16 },
+
+ /* 2352 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 16 },
+ /* 2353 */ { MAD_F(0x07a40827) /* 0.477546836 */, 16 },
+ /* 2354 */ { MAD_F(0x07a523eb) /* 0.477817459 */, 16 },
+ /* 2355 */ { MAD_F(0x07a63fba) /* 0.478088119 */, 16 },
+ /* 2356 */ { MAD_F(0x07a75b93) /* 0.478358818 */, 16 },
+ /* 2357 */ { MAD_F(0x07a87777) /* 0.478629555 */, 16 },
+ /* 2358 */ { MAD_F(0x07a99364) /* 0.478900331 */, 16 },
+ /* 2359 */ { MAD_F(0x07aaaf5c) /* 0.479171145 */, 16 },
+ /* 2360 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 16 },
+ /* 2361 */ { MAD_F(0x07ace76b) /* 0.479712887 */, 16 },
+ /* 2362 */ { MAD_F(0x07ae0382) /* 0.479983816 */, 16 },
+ /* 2363 */ { MAD_F(0x07af1fa3) /* 0.480254782 */, 16 },
+ /* 2364 */ { MAD_F(0x07b03bcf) /* 0.480525787 */, 16 },
+ /* 2365 */ { MAD_F(0x07b15804) /* 0.480796831 */, 16 },
+ /* 2366 */ { MAD_F(0x07b27444) /* 0.481067912 */, 16 },
+ /* 2367 */ { MAD_F(0x07b3908e) /* 0.481339032 */, 16 },
+
+ /* 2368 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 16 },
+ /* 2369 */ { MAD_F(0x07b5c941) /* 0.481881385 */, 16 },
+ /* 2370 */ { MAD_F(0x07b6e5aa) /* 0.482152620 */, 16 },
+ /* 2371 */ { MAD_F(0x07b8021d) /* 0.482423892 */, 16 },
+ /* 2372 */ { MAD_F(0x07b91e9b) /* 0.482695202 */, 16 },
+ /* 2373 */ { MAD_F(0x07ba3b22) /* 0.482966551 */, 16 },
+ /* 2374 */ { MAD_F(0x07bb57b4) /* 0.483237938 */, 16 },
+ /* 2375 */ { MAD_F(0x07bc7450) /* 0.483509362 */, 16 },
+ /* 2376 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 16 },
+ /* 2377 */ { MAD_F(0x07beada7) /* 0.484052326 */, 16 },
+ /* 2378 */ { MAD_F(0x07bfca61) /* 0.484323865 */, 16 },
+ /* 2379 */ { MAD_F(0x07c0e726) /* 0.484595443 */, 16 },
+ /* 2380 */ { MAD_F(0x07c203f5) /* 0.484867058 */, 16 },
+ /* 2381 */ { MAD_F(0x07c320cf) /* 0.485138711 */, 16 },
+ /* 2382 */ { MAD_F(0x07c43db2) /* 0.485410402 */, 16 },
+ /* 2383 */ { MAD_F(0x07c55aa0) /* 0.485682131 */, 16 },
+
+ /* 2384 */ { MAD_F(0x07c67798) /* 0.485953899 */, 16 },
+ /* 2385 */ { MAD_F(0x07c7949a) /* 0.486225704 */, 16 },
+ /* 2386 */ { MAD_F(0x07c8b1a7) /* 0.486497547 */, 16 },
+ /* 2387 */ { MAD_F(0x07c9cebd) /* 0.486769429 */, 16 },
+ /* 2388 */ { MAD_F(0x07caebde) /* 0.487041348 */, 16 },
+ /* 2389 */ { MAD_F(0x07cc0909) /* 0.487313305 */, 16 },
+ /* 2390 */ { MAD_F(0x07cd263e) /* 0.487585300 */, 16 },
+ /* 2391 */ { MAD_F(0x07ce437d) /* 0.487857333 */, 16 },
+ /* 2392 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 16 },
+ /* 2393 */ { MAD_F(0x07d07e1b) /* 0.488401513 */, 16 },
+ /* 2394 */ { MAD_F(0x07d19b79) /* 0.488673660 */, 16 },
+ /* 2395 */ { MAD_F(0x07d2b8e1) /* 0.488945845 */, 16 },
+ /* 2396 */ { MAD_F(0x07d3d653) /* 0.489218067 */, 16 },
+ /* 2397 */ { MAD_F(0x07d4f3cf) /* 0.489490328 */, 16 },
+ /* 2398 */ { MAD_F(0x07d61156) /* 0.489762626 */, 16 },
+ /* 2399 */ { MAD_F(0x07d72ee6) /* 0.490034962 */, 16 },
+
+ /* 2400 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 16 },
+ /* 2401 */ { MAD_F(0x07d96a26) /* 0.490579748 */, 16 },
+ /* 2402 */ { MAD_F(0x07da87d5) /* 0.490852198 */, 16 },
+ /* 2403 */ { MAD_F(0x07dba58f) /* 0.491124686 */, 16 },
+ /* 2404 */ { MAD_F(0x07dcc352) /* 0.491397211 */, 16 },
+ /* 2405 */ { MAD_F(0x07dde120) /* 0.491669774 */, 16 },
+ /* 2406 */ { MAD_F(0x07defef7) /* 0.491942375 */, 16 },
+ /* 2407 */ { MAD_F(0x07e01cd9) /* 0.492215014 */, 16 },
+ /* 2408 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 16 },
+ /* 2409 */ { MAD_F(0x07e258bc) /* 0.492760404 */, 16 },
+ /* 2410 */ { MAD_F(0x07e376bc) /* 0.493033156 */, 16 },
+ /* 2411 */ { MAD_F(0x07e494c6) /* 0.493305946 */, 16 },
+ /* 2412 */ { MAD_F(0x07e5b2db) /* 0.493578773 */, 16 },
+ /* 2413 */ { MAD_F(0x07e6d0f9) /* 0.493851638 */, 16 },
+ /* 2414 */ { MAD_F(0x07e7ef22) /* 0.494124541 */, 16 },
+ /* 2415 */ { MAD_F(0x07e90d55) /* 0.494397481 */, 16 },
+
+ /* 2416 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 16 },
+ /* 2417 */ { MAD_F(0x07eb49d9) /* 0.494943475 */, 16 },
+ /* 2418 */ { MAD_F(0x07ec682a) /* 0.495216529 */, 16 },
+ /* 2419 */ { MAD_F(0x07ed8686) /* 0.495489620 */, 16 },
+ /* 2420 */ { MAD_F(0x07eea4eb) /* 0.495762748 */, 16 },
+ /* 2421 */ { MAD_F(0x07efc35b) /* 0.496035915 */, 16 },
+ /* 2422 */ { MAD_F(0x07f0e1d4) /* 0.496309119 */, 16 },
+ /* 2423 */ { MAD_F(0x07f20058) /* 0.496582360 */, 16 },
+ /* 2424 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 16 },
+ /* 2425 */ { MAD_F(0x07f43d7e) /* 0.497128956 */, 16 },
+ /* 2426 */ { MAD_F(0x07f55c20) /* 0.497402310 */, 16 },
+ /* 2427 */ { MAD_F(0x07f67acc) /* 0.497675702 */, 16 },
+ /* 2428 */ { MAD_F(0x07f79982) /* 0.497949132 */, 16 },
+ /* 2429 */ { MAD_F(0x07f8b842) /* 0.498222598 */, 16 },
+ /* 2430 */ { MAD_F(0x07f9d70c) /* 0.498496103 */, 16 },
+ /* 2431 */ { MAD_F(0x07faf5e1) /* 0.498769645 */, 16 },
+
+ /* 2432 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 16 },
+ /* 2433 */ { MAD_F(0x07fd33a8) /* 0.499316841 */, 16 },
+ /* 2434 */ { MAD_F(0x07fe529a) /* 0.499590496 */, 16 },
+ /* 2435 */ { MAD_F(0x07ff7197) /* 0.499864188 */, 16 },
+ /* 2436 */ { MAD_F(0x0400484f) /* 0.250068959 */, 17 },
+ /* 2437 */ { MAD_F(0x0400d7d7) /* 0.250205842 */, 17 },
+ /* 2438 */ { MAD_F(0x04016764) /* 0.250342744 */, 17 },
+ /* 2439 */ { MAD_F(0x0401f6f7) /* 0.250479665 */, 17 },
+ /* 2440 */ { MAD_F(0x0402868e) /* 0.250616605 */, 17 },
+ /* 2441 */ { MAD_F(0x0403162b) /* 0.250753563 */, 17 },
+ /* 2442 */ { MAD_F(0x0403a5cc) /* 0.250890540 */, 17 },
+ /* 2443 */ { MAD_F(0x04043573) /* 0.251027536 */, 17 },
+ /* 2444 */ { MAD_F(0x0404c51e) /* 0.251164550 */, 17 },
+ /* 2445 */ { MAD_F(0x040554cf) /* 0.251301583 */, 17 },
+ /* 2446 */ { MAD_F(0x0405e484) /* 0.251438635 */, 17 },
+ /* 2447 */ { MAD_F(0x0406743f) /* 0.251575706 */, 17 },
+
+ /* 2448 */ { MAD_F(0x040703ff) /* 0.251712795 */, 17 },
+ /* 2449 */ { MAD_F(0x040793c3) /* 0.251849903 */, 17 },
+ /* 2450 */ { MAD_F(0x0408238d) /* 0.251987029 */, 17 },
+ /* 2451 */ { MAD_F(0x0408b35b) /* 0.252124174 */, 17 },
+ /* 2452 */ { MAD_F(0x0409432f) /* 0.252261338 */, 17 },
+ /* 2453 */ { MAD_F(0x0409d308) /* 0.252398520 */, 17 },
+ /* 2454 */ { MAD_F(0x040a62e5) /* 0.252535721 */, 17 },
+ /* 2455 */ { MAD_F(0x040af2c8) /* 0.252672941 */, 17 },
+ /* 2456 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 17 },
+ /* 2457 */ { MAD_F(0x040c129c) /* 0.252947436 */, 17 },
+ /* 2458 */ { MAD_F(0x040ca28e) /* 0.253084712 */, 17 },
+ /* 2459 */ { MAD_F(0x040d3284) /* 0.253222006 */, 17 },
+ /* 2460 */ { MAD_F(0x040dc280) /* 0.253359319 */, 17 },
+ /* 2461 */ { MAD_F(0x040e5281) /* 0.253496651 */, 17 },
+ /* 2462 */ { MAD_F(0x040ee286) /* 0.253634001 */, 17 },
+ /* 2463 */ { MAD_F(0x040f7291) /* 0.253771369 */, 17 },
+
+ /* 2464 */ { MAD_F(0x041002a1) /* 0.253908756 */, 17 },
+ /* 2465 */ { MAD_F(0x041092b5) /* 0.254046162 */, 17 },
+ /* 2466 */ { MAD_F(0x041122cf) /* 0.254183587 */, 17 },
+ /* 2467 */ { MAD_F(0x0411b2ed) /* 0.254321030 */, 17 },
+ /* 2468 */ { MAD_F(0x04124311) /* 0.254458491 */, 17 },
+ /* 2469 */ { MAD_F(0x0412d339) /* 0.254595971 */, 17 },
+ /* 2470 */ { MAD_F(0x04136367) /* 0.254733470 */, 17 },
+ /* 2471 */ { MAD_F(0x0413f399) /* 0.254870987 */, 17 },
+ /* 2472 */ { MAD_F(0x041483d1) /* 0.255008523 */, 17 },
+ /* 2473 */ { MAD_F(0x0415140d) /* 0.255146077 */, 17 },
+ /* 2474 */ { MAD_F(0x0415a44f) /* 0.255283650 */, 17 },
+ /* 2475 */ { MAD_F(0x04163495) /* 0.255421241 */, 17 },
+ /* 2476 */ { MAD_F(0x0416c4e1) /* 0.255558851 */, 17 },
+ /* 2477 */ { MAD_F(0x04175531) /* 0.255696480 */, 17 },
+ /* 2478 */ { MAD_F(0x0417e586) /* 0.255834127 */, 17 },
+ /* 2479 */ { MAD_F(0x041875e1) /* 0.255971792 */, 17 },
+
+ /* 2480 */ { MAD_F(0x04190640) /* 0.256109476 */, 17 },
+ /* 2481 */ { MAD_F(0x041996a4) /* 0.256247179 */, 17 },
+ /* 2482 */ { MAD_F(0x041a270d) /* 0.256384900 */, 17 },
+ /* 2483 */ { MAD_F(0x041ab77b) /* 0.256522639 */, 17 },
+ /* 2484 */ { MAD_F(0x041b47ef) /* 0.256660397 */, 17 },
+ /* 2485 */ { MAD_F(0x041bd867) /* 0.256798174 */, 17 },
+ /* 2486 */ { MAD_F(0x041c68e4) /* 0.256935969 */, 17 },
+ /* 2487 */ { MAD_F(0x041cf966) /* 0.257073782 */, 17 },
+ /* 2488 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 17 },
+ /* 2489 */ { MAD_F(0x041e1a79) /* 0.257349465 */, 17 },
+ /* 2490 */ { MAD_F(0x041eab0a) /* 0.257487334 */, 17 },
+ /* 2491 */ { MAD_F(0x041f3b9f) /* 0.257625221 */, 17 },
+ /* 2492 */ { MAD_F(0x041fcc3a) /* 0.257763127 */, 17 },
+ /* 2493 */ { MAD_F(0x04205cda) /* 0.257901051 */, 17 },
+ /* 2494 */ { MAD_F(0x0420ed7f) /* 0.258038994 */, 17 },
+ /* 2495 */ { MAD_F(0x04217e28) /* 0.258176955 */, 17 },
+
+ /* 2496 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 17 },
+ /* 2497 */ { MAD_F(0x04229f8a) /* 0.258452932 */, 17 },
+ /* 2498 */ { MAD_F(0x04233043) /* 0.258590948 */, 17 },
+ /* 2499 */ { MAD_F(0x0423c100) /* 0.258728983 */, 17 },
+ /* 2500 */ { MAD_F(0x042451c3) /* 0.258867036 */, 17 },
+ /* 2501 */ { MAD_F(0x0424e28a) /* 0.259005108 */, 17 },
+ /* 2502 */ { MAD_F(0x04257356) /* 0.259143198 */, 17 },
+ /* 2503 */ { MAD_F(0x04260428) /* 0.259281307 */, 17 },
+ /* 2504 */ { MAD_F(0x042694fe) /* 0.259419433 */, 17 },
+ /* 2505 */ { MAD_F(0x042725d9) /* 0.259557579 */, 17 },
+ /* 2506 */ { MAD_F(0x0427b6b9) /* 0.259695742 */, 17 },
+ /* 2507 */ { MAD_F(0x0428479e) /* 0.259833924 */, 17 },
+ /* 2508 */ { MAD_F(0x0428d888) /* 0.259972124 */, 17 },
+ /* 2509 */ { MAD_F(0x04296976) /* 0.260110343 */, 17 },
+ /* 2510 */ { MAD_F(0x0429fa6a) /* 0.260248580 */, 17 },
+ /* 2511 */ { MAD_F(0x042a8b63) /* 0.260386836 */, 17 },
+
+ /* 2512 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 17 },
+ /* 2513 */ { MAD_F(0x042bad63) /* 0.260663402 */, 17 },
+ /* 2514 */ { MAD_F(0x042c3e6a) /* 0.260801712 */, 17 },
+ /* 2515 */ { MAD_F(0x042ccf77) /* 0.260940041 */, 17 },
+ /* 2516 */ { MAD_F(0x042d6088) /* 0.261078388 */, 17 },
+ /* 2517 */ { MAD_F(0x042df19e) /* 0.261216754 */, 17 },
+ /* 2518 */ { MAD_F(0x042e82b9) /* 0.261355137 */, 17 },
+ /* 2519 */ { MAD_F(0x042f13d9) /* 0.261493540 */, 17 },
+ /* 2520 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 17 },
+ /* 2521 */ { MAD_F(0x04303628) /* 0.261770399 */, 17 },
+ /* 2522 */ { MAD_F(0x0430c757) /* 0.261908856 */, 17 },
+ /* 2523 */ { MAD_F(0x0431588b) /* 0.262047331 */, 17 },
+ /* 2524 */ { MAD_F(0x0431e9c3) /* 0.262185825 */, 17 },
+ /* 2525 */ { MAD_F(0x04327b01) /* 0.262324337 */, 17 },
+ /* 2526 */ { MAD_F(0x04330c43) /* 0.262462867 */, 17 },
+ /* 2527 */ { MAD_F(0x04339d8a) /* 0.262601416 */, 17 },
+
+ /* 2528 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 17 },
+ /* 2529 */ { MAD_F(0x0434c028) /* 0.262878568 */, 17 },
+ /* 2530 */ { MAD_F(0x0435517e) /* 0.263017171 */, 17 },
+ /* 2531 */ { MAD_F(0x0435e2d9) /* 0.263155792 */, 17 },
+ /* 2532 */ { MAD_F(0x04367439) /* 0.263294432 */, 17 },
+ /* 2533 */ { MAD_F(0x0437059e) /* 0.263433090 */, 17 },
+ /* 2534 */ { MAD_F(0x04379707) /* 0.263571767 */, 17 },
+ /* 2535 */ { MAD_F(0x04382876) /* 0.263710461 */, 17 },
+ /* 2536 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 17 },
+ /* 2537 */ { MAD_F(0x04394b61) /* 0.263987905 */, 17 },
+ /* 2538 */ { MAD_F(0x0439dcdf) /* 0.264126655 */, 17 },
+ /* 2539 */ { MAD_F(0x043a6e61) /* 0.264265422 */, 17 },
+ /* 2540 */ { MAD_F(0x043affe8) /* 0.264404208 */, 17 },
+ /* 2541 */ { MAD_F(0x043b9174) /* 0.264543012 */, 17 },
+ /* 2542 */ { MAD_F(0x043c2305) /* 0.264681834 */, 17 },
+ /* 2543 */ { MAD_F(0x043cb49a) /* 0.264820674 */, 17 },
+
+ /* 2544 */ { MAD_F(0x043d4635) /* 0.264959533 */, 17 },
+ /* 2545 */ { MAD_F(0x043dd7d4) /* 0.265098410 */, 17 },
+ /* 2546 */ { MAD_F(0x043e6979) /* 0.265237305 */, 17 },
+ /* 2547 */ { MAD_F(0x043efb22) /* 0.265376218 */, 17 },
+ /* 2548 */ { MAD_F(0x043f8cd0) /* 0.265515149 */, 17 },
+ /* 2549 */ { MAD_F(0x04401e83) /* 0.265654099 */, 17 },
+ /* 2550 */ { MAD_F(0x0440b03b) /* 0.265793066 */, 17 },
+ /* 2551 */ { MAD_F(0x044141f7) /* 0.265932052 */, 17 },
+ /* 2552 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 17 },
+ /* 2553 */ { MAD_F(0x04426580) /* 0.266210078 */, 17 },
+ /* 2554 */ { MAD_F(0x0442f74b) /* 0.266349119 */, 17 },
+ /* 2555 */ { MAD_F(0x0443891b) /* 0.266488177 */, 17 },
+ /* 2556 */ { MAD_F(0x04441af0) /* 0.266627254 */, 17 },
+ /* 2557 */ { MAD_F(0x0444acca) /* 0.266766349 */, 17 },
+ /* 2558 */ { MAD_F(0x04453ea9) /* 0.266905462 */, 17 },
+ /* 2559 */ { MAD_F(0x0445d08d) /* 0.267044593 */, 17 },
+
+ /* 2560 */ { MAD_F(0x04466275) /* 0.267183742 */, 17 },
+ /* 2561 */ { MAD_F(0x0446f463) /* 0.267322909 */, 17 },
+ /* 2562 */ { MAD_F(0x04478655) /* 0.267462094 */, 17 },
+ /* 2563 */ { MAD_F(0x0448184c) /* 0.267601298 */, 17 },
+ /* 2564 */ { MAD_F(0x0448aa48) /* 0.267740519 */, 17 },
+ /* 2565 */ { MAD_F(0x04493c49) /* 0.267879759 */, 17 },
+ /* 2566 */ { MAD_F(0x0449ce4f) /* 0.268019017 */, 17 },
+ /* 2567 */ { MAD_F(0x044a6059) /* 0.268158293 */, 17 },
+ /* 2568 */ { MAD_F(0x044af269) /* 0.268297587 */, 17 },
+ /* 2569 */ { MAD_F(0x044b847d) /* 0.268436899 */, 17 },
+ /* 2570 */ { MAD_F(0x044c1696) /* 0.268576229 */, 17 },
+ /* 2571 */ { MAD_F(0x044ca8b4) /* 0.268715577 */, 17 },
+ /* 2572 */ { MAD_F(0x044d3ad7) /* 0.268854943 */, 17 },
+ /* 2573 */ { MAD_F(0x044dccff) /* 0.268994328 */, 17 },
+ /* 2574 */ { MAD_F(0x044e5f2b) /* 0.269133730 */, 17 },
+ /* 2575 */ { MAD_F(0x044ef15d) /* 0.269273150 */, 17 },
+
+ /* 2576 */ { MAD_F(0x044f8393) /* 0.269412589 */, 17 },
+ /* 2577 */ { MAD_F(0x045015ce) /* 0.269552045 */, 17 },
+ /* 2578 */ { MAD_F(0x0450a80e) /* 0.269691520 */, 17 },
+ /* 2579 */ { MAD_F(0x04513a53) /* 0.269831013 */, 17 },
+ /* 2580 */ { MAD_F(0x0451cc9c) /* 0.269970523 */, 17 },
+ /* 2581 */ { MAD_F(0x04525eeb) /* 0.270110052 */, 17 },
+ /* 2582 */ { MAD_F(0x0452f13e) /* 0.270249599 */, 17 },
+ /* 2583 */ { MAD_F(0x04538396) /* 0.270389163 */, 17 },
+ /* 2584 */ { MAD_F(0x045415f3) /* 0.270528746 */, 17 },
+ /* 2585 */ { MAD_F(0x0454a855) /* 0.270668347 */, 17 },
+ /* 2586 */ { MAD_F(0x04553abb) /* 0.270807965 */, 17 },
+ /* 2587 */ { MAD_F(0x0455cd27) /* 0.270947602 */, 17 },
+ /* 2588 */ { MAD_F(0x04565f97) /* 0.271087257 */, 17 },
+ /* 2589 */ { MAD_F(0x0456f20c) /* 0.271226930 */, 17 },
+ /* 2590 */ { MAD_F(0x04578486) /* 0.271366620 */, 17 },
+ /* 2591 */ { MAD_F(0x04581705) /* 0.271506329 */, 17 },
+
+ /* 2592 */ { MAD_F(0x0458a989) /* 0.271646056 */, 17 },
+ /* 2593 */ { MAD_F(0x04593c11) /* 0.271785800 */, 17 },
+ /* 2594 */ { MAD_F(0x0459ce9e) /* 0.271925563 */, 17 },
+ /* 2595 */ { MAD_F(0x045a6130) /* 0.272065343 */, 17 },
+ /* 2596 */ { MAD_F(0x045af3c7) /* 0.272205142 */, 17 },
+ /* 2597 */ { MAD_F(0x045b8663) /* 0.272344958 */, 17 },
+ /* 2598 */ { MAD_F(0x045c1903) /* 0.272484793 */, 17 },
+ /* 2599 */ { MAD_F(0x045caba9) /* 0.272624645 */, 17 },
+ /* 2600 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 17 },
+ /* 2601 */ { MAD_F(0x045dd102) /* 0.272904403 */, 17 },
+ /* 2602 */ { MAD_F(0x045e63b6) /* 0.273044310 */, 17 },
+ /* 2603 */ { MAD_F(0x045ef66e) /* 0.273184234 */, 17 },
+ /* 2604 */ { MAD_F(0x045f892b) /* 0.273324176 */, 17 },
+ /* 2605 */ { MAD_F(0x04601bee) /* 0.273464136 */, 17 },
+ /* 2606 */ { MAD_F(0x0460aeb5) /* 0.273604113 */, 17 },
+ /* 2607 */ { MAD_F(0x04614180) /* 0.273744109 */, 17 },
+
+ /* 2608 */ { MAD_F(0x0461d451) /* 0.273884123 */, 17 },
+ /* 2609 */ { MAD_F(0x04626727) /* 0.274024154 */, 17 },
+ /* 2610 */ { MAD_F(0x0462fa01) /* 0.274164204 */, 17 },
+ /* 2611 */ { MAD_F(0x04638ce0) /* 0.274304271 */, 17 },
+ /* 2612 */ { MAD_F(0x04641fc4) /* 0.274444356 */, 17 },
+ /* 2613 */ { MAD_F(0x0464b2ac) /* 0.274584459 */, 17 },
+ /* 2614 */ { MAD_F(0x0465459a) /* 0.274724580 */, 17 },
+ /* 2615 */ { MAD_F(0x0465d88c) /* 0.274864719 */, 17 },
+ /* 2616 */ { MAD_F(0x04666b83) /* 0.275004875 */, 17 },
+ /* 2617 */ { MAD_F(0x0466fe7f) /* 0.275145050 */, 17 },
+ /* 2618 */ { MAD_F(0x0467917f) /* 0.275285242 */, 17 },
+ /* 2619 */ { MAD_F(0x04682485) /* 0.275425452 */, 17 },
+ /* 2620 */ { MAD_F(0x0468b78f) /* 0.275565681 */, 17 },
+ /* 2621 */ { MAD_F(0x04694a9e) /* 0.275705926 */, 17 },
+ /* 2622 */ { MAD_F(0x0469ddb2) /* 0.275846190 */, 17 },
+ /* 2623 */ { MAD_F(0x046a70ca) /* 0.275986472 */, 17 },
+
+ /* 2624 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 17 },
+ /* 2625 */ { MAD_F(0x046b970a) /* 0.276267088 */, 17 },
+ /* 2626 */ { MAD_F(0x046c2a31) /* 0.276407423 */, 17 },
+ /* 2627 */ { MAD_F(0x046cbd5c) /* 0.276547776 */, 17 },
+ /* 2628 */ { MAD_F(0x046d508d) /* 0.276688147 */, 17 },
+ /* 2629 */ { MAD_F(0x046de3c2) /* 0.276828535 */, 17 },
+ /* 2630 */ { MAD_F(0x046e76fc) /* 0.276968942 */, 17 },
+ /* 2631 */ { MAD_F(0x046f0a3b) /* 0.277109366 */, 17 },
+ /* 2632 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 17 },
+ /* 2633 */ { MAD_F(0x047030c7) /* 0.277390267 */, 17 },
+ /* 2634 */ { MAD_F(0x0470c414) /* 0.277530745 */, 17 },
+ /* 2635 */ { MAD_F(0x04715766) /* 0.277671240 */, 17 },
+ /* 2636 */ { MAD_F(0x0471eabc) /* 0.277811753 */, 17 },
+ /* 2637 */ { MAD_F(0x04727e18) /* 0.277952284 */, 17 },
+ /* 2638 */ { MAD_F(0x04731178) /* 0.278092832 */, 17 },
+ /* 2639 */ { MAD_F(0x0473a4dd) /* 0.278233399 */, 17 },
+
+ /* 2640 */ { MAD_F(0x04743847) /* 0.278373983 */, 17 },
+ /* 2641 */ { MAD_F(0x0474cbb5) /* 0.278514584 */, 17 },
+ /* 2642 */ { MAD_F(0x04755f29) /* 0.278655204 */, 17 },
+ /* 2643 */ { MAD_F(0x0475f2a1) /* 0.278795841 */, 17 },
+ /* 2644 */ { MAD_F(0x0476861d) /* 0.278936496 */, 17 },
+ /* 2645 */ { MAD_F(0x0477199f) /* 0.279077169 */, 17 },
+ /* 2646 */ { MAD_F(0x0477ad25) /* 0.279217860 */, 17 },
+ /* 2647 */ { MAD_F(0x047840b0) /* 0.279358568 */, 17 },
+ /* 2648 */ { MAD_F(0x0478d440) /* 0.279499294 */, 17 },
+ /* 2649 */ { MAD_F(0x047967d5) /* 0.279640037 */, 17 },
+ /* 2650 */ { MAD_F(0x0479fb6e) /* 0.279780799 */, 17 },
+ /* 2651 */ { MAD_F(0x047a8f0c) /* 0.279921578 */, 17 },
+ /* 2652 */ { MAD_F(0x047b22af) /* 0.280062375 */, 17 },
+ /* 2653 */ { MAD_F(0x047bb657) /* 0.280203189 */, 17 },
+ /* 2654 */ { MAD_F(0x047c4a03) /* 0.280344021 */, 17 },
+ /* 2655 */ { MAD_F(0x047cddb4) /* 0.280484871 */, 17 },
+
+ /* 2656 */ { MAD_F(0x047d716a) /* 0.280625739 */, 17 },
+ /* 2657 */ { MAD_F(0x047e0524) /* 0.280766624 */, 17 },
+ /* 2658 */ { MAD_F(0x047e98e4) /* 0.280907527 */, 17 },
+ /* 2659 */ { MAD_F(0x047f2ca8) /* 0.281048447 */, 17 },
+ /* 2660 */ { MAD_F(0x047fc071) /* 0.281189385 */, 17 },
+ /* 2661 */ { MAD_F(0x0480543e) /* 0.281330341 */, 17 },
+ /* 2662 */ { MAD_F(0x0480e811) /* 0.281471315 */, 17 },
+ /* 2663 */ { MAD_F(0x04817be8) /* 0.281612306 */, 17 },
+ /* 2664 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 17 },
+ /* 2665 */ { MAD_F(0x0482a3a4) /* 0.281894341 */, 17 },
+ /* 2666 */ { MAD_F(0x04833789) /* 0.282035386 */, 17 },
+ /* 2667 */ { MAD_F(0x0483cb73) /* 0.282176447 */, 17 },
+ /* 2668 */ { MAD_F(0x04845f62) /* 0.282317527 */, 17 },
+ /* 2669 */ { MAD_F(0x0484f355) /* 0.282458624 */, 17 },
+ /* 2670 */ { MAD_F(0x0485874d) /* 0.282599738 */, 17 },
+ /* 2671 */ { MAD_F(0x04861b4a) /* 0.282740871 */, 17 },
+
+ /* 2672 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 17 },
+ /* 2673 */ { MAD_F(0x04874352) /* 0.283023188 */, 17 },
+ /* 2674 */ { MAD_F(0x0487d75d) /* 0.283164373 */, 17 },
+ /* 2675 */ { MAD_F(0x04886b6d) /* 0.283305576 */, 17 },
+ /* 2676 */ { MAD_F(0x0488ff82) /* 0.283446796 */, 17 },
+ /* 2677 */ { MAD_F(0x0489939b) /* 0.283588034 */, 17 },
+ /* 2678 */ { MAD_F(0x048a27b9) /* 0.283729290 */, 17 },
+ /* 2679 */ { MAD_F(0x048abbdc) /* 0.283870563 */, 17 },
+ /* 2680 */ { MAD_F(0x048b5003) /* 0.284011853 */, 17 },
+ /* 2681 */ { MAD_F(0x048be42f) /* 0.284153161 */, 17 },
+ /* 2682 */ { MAD_F(0x048c7860) /* 0.284294487 */, 17 },
+ /* 2683 */ { MAD_F(0x048d0c96) /* 0.284435831 */, 17 },
+ /* 2684 */ { MAD_F(0x048da0d0) /* 0.284577192 */, 17 },
+ /* 2685 */ { MAD_F(0x048e350f) /* 0.284718570 */, 17 },
+ /* 2686 */ { MAD_F(0x048ec953) /* 0.284859966 */, 17 },
+ /* 2687 */ { MAD_F(0x048f5d9b) /* 0.285001380 */, 17 },
+
+ /* 2688 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 17 },
+ /* 2689 */ { MAD_F(0x0490863a) /* 0.285284259 */, 17 },
+ /* 2690 */ { MAD_F(0x04911a91) /* 0.285425726 */, 17 },
+ /* 2691 */ { MAD_F(0x0491aeec) /* 0.285567209 */, 17 },
+ /* 2692 */ { MAD_F(0x0492434c) /* 0.285708711 */, 17 },
+ /* 2693 */ { MAD_F(0x0492d7b0) /* 0.285850229 */, 17 },
+ /* 2694 */ { MAD_F(0x04936c1a) /* 0.285991766 */, 17 },
+ /* 2695 */ { MAD_F(0x04940088) /* 0.286133319 */, 17 },
+ /* 2696 */ { MAD_F(0x049494fb) /* 0.286274891 */, 17 },
+ /* 2697 */ { MAD_F(0x04952972) /* 0.286416480 */, 17 },
+ /* 2698 */ { MAD_F(0x0495bdee) /* 0.286558086 */, 17 },
+ /* 2699 */ { MAD_F(0x0496526f) /* 0.286699710 */, 17 },
+ /* 2700 */ { MAD_F(0x0496e6f5) /* 0.286841351 */, 17 },
+ /* 2701 */ { MAD_F(0x04977b7f) /* 0.286983010 */, 17 },
+ /* 2702 */ { MAD_F(0x0498100e) /* 0.287124686 */, 17 },
+ /* 2703 */ { MAD_F(0x0498a4a1) /* 0.287266380 */, 17 },
+
+ /* 2704 */ { MAD_F(0x0499393a) /* 0.287408091 */, 17 },
+ /* 2705 */ { MAD_F(0x0499cdd7) /* 0.287549820 */, 17 },
+ /* 2706 */ { MAD_F(0x049a6278) /* 0.287691566 */, 17 },
+ /* 2707 */ { MAD_F(0x049af71f) /* 0.287833330 */, 17 },
+ /* 2708 */ { MAD_F(0x049b8bca) /* 0.287975111 */, 17 },
+ /* 2709 */ { MAD_F(0x049c207a) /* 0.288116909 */, 17 },
+ /* 2710 */ { MAD_F(0x049cb52e) /* 0.288258725 */, 17 },
+ /* 2711 */ { MAD_F(0x049d49e7) /* 0.288400559 */, 17 },
+ /* 2712 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 17 },
+ /* 2713 */ { MAD_F(0x049e7367) /* 0.288684278 */, 17 },
+ /* 2714 */ { MAD_F(0x049f082f) /* 0.288826163 */, 17 },
+ /* 2715 */ { MAD_F(0x049f9cfa) /* 0.288968067 */, 17 },
+ /* 2716 */ { MAD_F(0x04a031cb) /* 0.289109987 */, 17 },
+ /* 2717 */ { MAD_F(0x04a0c6a0) /* 0.289251925 */, 17 },
+ /* 2718 */ { MAD_F(0x04a15b7a) /* 0.289393881 */, 17 },
+ /* 2719 */ { MAD_F(0x04a1f059) /* 0.289535854 */, 17 },
+
+ /* 2720 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 17 },
+ /* 2721 */ { MAD_F(0x04a31a24) /* 0.289819851 */, 17 },
+ /* 2722 */ { MAD_F(0x04a3af10) /* 0.289961876 */, 17 },
+ /* 2723 */ { MAD_F(0x04a44401) /* 0.290103919 */, 17 },
+ /* 2724 */ { MAD_F(0x04a4d8f7) /* 0.290245979 */, 17 },
+ /* 2725 */ { MAD_F(0x04a56df2) /* 0.290388056 */, 17 },
+ /* 2726 */ { MAD_F(0x04a602f1) /* 0.290530150 */, 17 },
+ /* 2727 */ { MAD_F(0x04a697f5) /* 0.290672262 */, 17 },
+ /* 2728 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 17 },
+ /* 2729 */ { MAD_F(0x04a7c20b) /* 0.290956538 */, 17 },
+ /* 2730 */ { MAD_F(0x04a8571d) /* 0.291098703 */, 17 },
+ /* 2731 */ { MAD_F(0x04a8ec33) /* 0.291240884 */, 17 },
+ /* 2732 */ { MAD_F(0x04a9814e) /* 0.291383083 */, 17 },
+ /* 2733 */ { MAD_F(0x04aa166e) /* 0.291525299 */, 17 },
+ /* 2734 */ { MAD_F(0x04aaab93) /* 0.291667532 */, 17 },
+ /* 2735 */ { MAD_F(0x04ab40bc) /* 0.291809783 */, 17 },
+
+ /* 2736 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 17 },
+ /* 2737 */ { MAD_F(0x04ac6b1c) /* 0.292094337 */, 17 },
+ /* 2738 */ { MAD_F(0x04ad0053) /* 0.292236640 */, 17 },
+ /* 2739 */ { MAD_F(0x04ad958f) /* 0.292378960 */, 17 },
+ /* 2740 */ { MAD_F(0x04ae2ad0) /* 0.292521297 */, 17 },
+ /* 2741 */ { MAD_F(0x04aec015) /* 0.292663652 */, 17 },
+ /* 2742 */ { MAD_F(0x04af555e) /* 0.292806024 */, 17 },
+ /* 2743 */ { MAD_F(0x04afeaad) /* 0.292948414 */, 17 },
+ /* 2744 */ { MAD_F(0x04b08000) /* 0.293090820 */, 17 },
+ /* 2745 */ { MAD_F(0x04b11557) /* 0.293233244 */, 17 },
+ /* 2746 */ { MAD_F(0x04b1aab4) /* 0.293375686 */, 17 },
+ /* 2747 */ { MAD_F(0x04b24015) /* 0.293518144 */, 17 },
+ /* 2748 */ { MAD_F(0x04b2d57a) /* 0.293660620 */, 17 },
+ /* 2749 */ { MAD_F(0x04b36ae4) /* 0.293803113 */, 17 },
+ /* 2750 */ { MAD_F(0x04b40053) /* 0.293945624 */, 17 },
+ /* 2751 */ { MAD_F(0x04b495c7) /* 0.294088151 */, 17 },
+
+ /* 2752 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 17 },
+ /* 2753 */ { MAD_F(0x04b5c0bc) /* 0.294373259 */, 17 },
+ /* 2754 */ { MAD_F(0x04b6563d) /* 0.294515838 */, 17 },
+ /* 2755 */ { MAD_F(0x04b6ebc3) /* 0.294658435 */, 17 },
+ /* 2756 */ { MAD_F(0x04b7814e) /* 0.294801049 */, 17 },
+ /* 2757 */ { MAD_F(0x04b816dd) /* 0.294943680 */, 17 },
+ /* 2758 */ { MAD_F(0x04b8ac71) /* 0.295086329 */, 17 },
+ /* 2759 */ { MAD_F(0x04b9420a) /* 0.295228995 */, 17 },
+ /* 2760 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 17 },
+ /* 2761 */ { MAD_F(0x04ba6d49) /* 0.295514378 */, 17 },
+ /* 2762 */ { MAD_F(0x04bb02ef) /* 0.295657095 */, 17 },
+ /* 2763 */ { MAD_F(0x04bb989a) /* 0.295799830 */, 17 },
+ /* 2764 */ { MAD_F(0x04bc2e4a) /* 0.295942582 */, 17 },
+ /* 2765 */ { MAD_F(0x04bcc3fe) /* 0.296085351 */, 17 },
+ /* 2766 */ { MAD_F(0x04bd59b7) /* 0.296228138 */, 17 },
+ /* 2767 */ { MAD_F(0x04bdef74) /* 0.296370941 */, 17 },
+
+ /* 2768 */ { MAD_F(0x04be8537) /* 0.296513762 */, 17 },
+ /* 2769 */ { MAD_F(0x04bf1afd) /* 0.296656600 */, 17 },
+ /* 2770 */ { MAD_F(0x04bfb0c9) /* 0.296799455 */, 17 },
+ /* 2771 */ { MAD_F(0x04c04699) /* 0.296942327 */, 17 },
+ /* 2772 */ { MAD_F(0x04c0dc6d) /* 0.297085217 */, 17 },
+ /* 2773 */ { MAD_F(0x04c17247) /* 0.297228124 */, 17 },
+ /* 2774 */ { MAD_F(0x04c20824) /* 0.297371048 */, 17 },
+ /* 2775 */ { MAD_F(0x04c29e07) /* 0.297513989 */, 17 },
+ /* 2776 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 17 },
+ /* 2777 */ { MAD_F(0x04c3c9da) /* 0.297799922 */, 17 },
+ /* 2778 */ { MAD_F(0x04c45fca) /* 0.297942915 */, 17 },
+ /* 2779 */ { MAD_F(0x04c4f5bf) /* 0.298085925 */, 17 },
+ /* 2780 */ { MAD_F(0x04c58bb8) /* 0.298228951 */, 17 },
+ /* 2781 */ { MAD_F(0x04c621b6) /* 0.298371996 */, 17 },
+ /* 2782 */ { MAD_F(0x04c6b7b9) /* 0.298515057 */, 17 },
+ /* 2783 */ { MAD_F(0x04c74dc0) /* 0.298658135 */, 17 },
+
+ /* 2784 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 17 },
+ /* 2785 */ { MAD_F(0x04c879dd) /* 0.298944343 */, 17 },
+ /* 2786 */ { MAD_F(0x04c90ff2) /* 0.299087473 */, 17 },
+ /* 2787 */ { MAD_F(0x04c9a60c) /* 0.299230620 */, 17 },
+ /* 2788 */ { MAD_F(0x04ca3c2a) /* 0.299373784 */, 17 },
+ /* 2789 */ { MAD_F(0x04cad24d) /* 0.299516965 */, 17 },
+ /* 2790 */ { MAD_F(0x04cb6874) /* 0.299660163 */, 17 },
+ /* 2791 */ { MAD_F(0x04cbfea0) /* 0.299803378 */, 17 },
+ /* 2792 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 17 },
+ /* 2793 */ { MAD_F(0x04cd2b06) /* 0.300089860 */, 17 },
+ /* 2794 */ { MAD_F(0x04cdc140) /* 0.300233127 */, 17 },
+ /* 2795 */ { MAD_F(0x04ce577f) /* 0.300376411 */, 17 },
+ /* 2796 */ { MAD_F(0x04ceedc2) /* 0.300519711 */, 17 },
+ /* 2797 */ { MAD_F(0x04cf8409) /* 0.300663029 */, 17 },
+ /* 2798 */ { MAD_F(0x04d01a55) /* 0.300806364 */, 17 },
+ /* 2799 */ { MAD_F(0x04d0b0a6) /* 0.300949716 */, 17 },
+
+ /* 2800 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 17 },
+ /* 2801 */ { MAD_F(0x04d1dd55) /* 0.301236472 */, 17 },
+ /* 2802 */ { MAD_F(0x04d273b4) /* 0.301379875 */, 17 },
+ /* 2803 */ { MAD_F(0x04d30a17) /* 0.301523295 */, 17 },
+ /* 2804 */ { MAD_F(0x04d3a07f) /* 0.301666733 */, 17 },
+ /* 2805 */ { MAD_F(0x04d436eb) /* 0.301810187 */, 17 },
+ /* 2806 */ { MAD_F(0x04d4cd5c) /* 0.301953659 */, 17 },
+ /* 2807 */ { MAD_F(0x04d563d1) /* 0.302097147 */, 17 },
+ /* 2808 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 17 },
+ /* 2809 */ { MAD_F(0x04d690ca) /* 0.302384175 */, 17 },
+ /* 2810 */ { MAD_F(0x04d7274d) /* 0.302527715 */, 17 },
+ /* 2811 */ { MAD_F(0x04d7bdd5) /* 0.302671271 */, 17 },
+ /* 2812 */ { MAD_F(0x04d85461) /* 0.302814845 */, 17 },
+ /* 2813 */ { MAD_F(0x04d8eaf2) /* 0.302958436 */, 17 },
+ /* 2814 */ { MAD_F(0x04d98187) /* 0.303102044 */, 17 },
+ /* 2815 */ { MAD_F(0x04da1821) /* 0.303245668 */, 17 },
+
+ /* 2816 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 17 },
+ /* 2817 */ { MAD_F(0x04db4563) /* 0.303532969 */, 17 },
+ /* 2818 */ { MAD_F(0x04dbdc0a) /* 0.303676645 */, 17 },
+ /* 2819 */ { MAD_F(0x04dc72b7) /* 0.303820337 */, 17 },
+ /* 2820 */ { MAD_F(0x04dd0967) /* 0.303964047 */, 17 },
+ /* 2821 */ { MAD_F(0x04dda01d) /* 0.304107774 */, 17 },
+ /* 2822 */ { MAD_F(0x04de36d7) /* 0.304251517 */, 17 },
+ /* 2823 */ { MAD_F(0x04decd95) /* 0.304395278 */, 17 },
+ /* 2824 */ { MAD_F(0x04df6458) /* 0.304539056 */, 17 },
+ /* 2825 */ { MAD_F(0x04dffb20) /* 0.304682850 */, 17 },
+ /* 2826 */ { MAD_F(0x04e091ec) /* 0.304826662 */, 17 },
+ /* 2827 */ { MAD_F(0x04e128bc) /* 0.304970491 */, 17 },
+ /* 2828 */ { MAD_F(0x04e1bf92) /* 0.305114336 */, 17 },
+ /* 2829 */ { MAD_F(0x04e2566b) /* 0.305258199 */, 17 },
+ /* 2830 */ { MAD_F(0x04e2ed4a) /* 0.305402078 */, 17 },
+ /* 2831 */ { MAD_F(0x04e3842d) /* 0.305545974 */, 17 },
+
+ /* 2832 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 17 },
+ /* 2833 */ { MAD_F(0x04e4b200) /* 0.305833818 */, 17 },
+ /* 2834 */ { MAD_F(0x04e548f1) /* 0.305977765 */, 17 },
+ /* 2835 */ { MAD_F(0x04e5dfe6) /* 0.306121729 */, 17 },
+ /* 2836 */ { MAD_F(0x04e676df) /* 0.306265710 */, 17 },
+ /* 2837 */ { MAD_F(0x04e70dde) /* 0.306409708 */, 17 },
+ /* 2838 */ { MAD_F(0x04e7a4e0) /* 0.306553723 */, 17 },
+ /* 2839 */ { MAD_F(0x04e83be7) /* 0.306697755 */, 17 },
+ /* 2840 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 17 },
+ /* 2841 */ { MAD_F(0x04e96a04) /* 0.306985869 */, 17 },
+ /* 2842 */ { MAD_F(0x04ea0118) /* 0.307129952 */, 17 },
+ /* 2843 */ { MAD_F(0x04ea9832) /* 0.307274051 */, 17 },
+ /* 2844 */ { MAD_F(0x04eb2f50) /* 0.307418168 */, 17 },
+ /* 2845 */ { MAD_F(0x04ebc672) /* 0.307562301 */, 17 },
+ /* 2846 */ { MAD_F(0x04ec5d99) /* 0.307706451 */, 17 },
+ /* 2847 */ { MAD_F(0x04ecf4c5) /* 0.307850618 */, 17 },
+
+ /* 2848 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 17 },
+ /* 2849 */ { MAD_F(0x04ee2329) /* 0.308139003 */, 17 },
+ /* 2850 */ { MAD_F(0x04eeba63) /* 0.308283220 */, 17 },
+ /* 2851 */ { MAD_F(0x04ef51a0) /* 0.308427455 */, 17 },
+ /* 2852 */ { MAD_F(0x04efe8e2) /* 0.308571706 */, 17 },
+ /* 2853 */ { MAD_F(0x04f08029) /* 0.308715974 */, 17 },
+ /* 2854 */ { MAD_F(0x04f11774) /* 0.308860260 */, 17 },
+ /* 2855 */ { MAD_F(0x04f1aec4) /* 0.309004561 */, 17 },
+ /* 2856 */ { MAD_F(0x04f24618) /* 0.309148880 */, 17 },
+ /* 2857 */ { MAD_F(0x04f2dd71) /* 0.309293216 */, 17 },
+ /* 2858 */ { MAD_F(0x04f374cf) /* 0.309437568 */, 17 },
+ /* 2859 */ { MAD_F(0x04f40c30) /* 0.309581938 */, 17 },
+ /* 2860 */ { MAD_F(0x04f4a397) /* 0.309726324 */, 17 },
+ /* 2861 */ { MAD_F(0x04f53b02) /* 0.309870727 */, 17 },
+ /* 2862 */ { MAD_F(0x04f5d271) /* 0.310015147 */, 17 },
+ /* 2863 */ { MAD_F(0x04f669e5) /* 0.310159583 */, 17 },
+
+ /* 2864 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 17 },
+ /* 2865 */ { MAD_F(0x04f798da) /* 0.310448507 */, 17 },
+ /* 2866 */ { MAD_F(0x04f8305c) /* 0.310592994 */, 17 },
+ /* 2867 */ { MAD_F(0x04f8c7e2) /* 0.310737498 */, 17 },
+ /* 2868 */ { MAD_F(0x04f95f6c) /* 0.310882018 */, 17 },
+ /* 2869 */ { MAD_F(0x04f9f6fb) /* 0.311026556 */, 17 },
+ /* 2870 */ { MAD_F(0x04fa8e8f) /* 0.311171110 */, 17 },
+ /* 2871 */ { MAD_F(0x04fb2627) /* 0.311315681 */, 17 },
+ /* 2872 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 17 },
+ /* 2873 */ { MAD_F(0x04fc5564) /* 0.311604874 */, 17 },
+ /* 2874 */ { MAD_F(0x04fced0a) /* 0.311749495 */, 17 },
+ /* 2875 */ { MAD_F(0x04fd84b4) /* 0.311894133 */, 17 },
+ /* 2876 */ { MAD_F(0x04fe1c62) /* 0.312038788 */, 17 },
+ /* 2877 */ { MAD_F(0x04feb415) /* 0.312183460 */, 17 },
+ /* 2878 */ { MAD_F(0x04ff4bcd) /* 0.312328148 */, 17 },
+ /* 2879 */ { MAD_F(0x04ffe389) /* 0.312472854 */, 17 },
+
+ /* 2880 */ { MAD_F(0x05007b49) /* 0.312617576 */, 17 },
+ /* 2881 */ { MAD_F(0x0501130e) /* 0.312762314 */, 17 },
+ /* 2882 */ { MAD_F(0x0501aad8) /* 0.312907070 */, 17 },
+ /* 2883 */ { MAD_F(0x050242a6) /* 0.313051842 */, 17 },
+ /* 2884 */ { MAD_F(0x0502da78) /* 0.313196631 */, 17 },
+ /* 2885 */ { MAD_F(0x0503724f) /* 0.313341437 */, 17 },
+ /* 2886 */ { MAD_F(0x05040a2b) /* 0.313486259 */, 17 },
+ /* 2887 */ { MAD_F(0x0504a20b) /* 0.313631098 */, 17 },
+ /* 2888 */ { MAD_F(0x050539ef) /* 0.313775954 */, 17 },
+ /* 2889 */ { MAD_F(0x0505d1d8) /* 0.313920827 */, 17 },
+ /* 2890 */ { MAD_F(0x050669c5) /* 0.314065716 */, 17 },
+ /* 2891 */ { MAD_F(0x050701b7) /* 0.314210622 */, 17 },
+ /* 2892 */ { MAD_F(0x050799ae) /* 0.314355545 */, 17 },
+ /* 2893 */ { MAD_F(0x050831a9) /* 0.314500484 */, 17 },
+ /* 2894 */ { MAD_F(0x0508c9a8) /* 0.314645440 */, 17 },
+ /* 2895 */ { MAD_F(0x050961ac) /* 0.314790413 */, 17 },
+
+ /* 2896 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 17 },
+ /* 2897 */ { MAD_F(0x050a91c1) /* 0.315080409 */, 17 },
+ /* 2898 */ { MAD_F(0x050b29d2) /* 0.315225432 */, 17 },
+ /* 2899 */ { MAD_F(0x050bc1e8) /* 0.315370472 */, 17 },
+ /* 2900 */ { MAD_F(0x050c5a02) /* 0.315515528 */, 17 },
+ /* 2901 */ { MAD_F(0x050cf221) /* 0.315660601 */, 17 },
+ /* 2902 */ { MAD_F(0x050d8a44) /* 0.315805690 */, 17 },
+ /* 2903 */ { MAD_F(0x050e226c) /* 0.315950797 */, 17 },
+ /* 2904 */ { MAD_F(0x050eba98) /* 0.316095920 */, 17 },
+ /* 2905 */ { MAD_F(0x050f52c9) /* 0.316241059 */, 17 },
+ /* 2906 */ { MAD_F(0x050feafe) /* 0.316386216 */, 17 },
+ /* 2907 */ { MAD_F(0x05108337) /* 0.316531388 */, 17 },
+ /* 2908 */ { MAD_F(0x05111b75) /* 0.316676578 */, 17 },
+ /* 2909 */ { MAD_F(0x0511b3b8) /* 0.316821784 */, 17 },
+ /* 2910 */ { MAD_F(0x05124bff) /* 0.316967007 */, 17 },
+ /* 2911 */ { MAD_F(0x0512e44a) /* 0.317112247 */, 17 },
+
+ /* 2912 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 17 },
+ /* 2913 */ { MAD_F(0x051414ee) /* 0.317402775 */, 17 },
+ /* 2914 */ { MAD_F(0x0514ad47) /* 0.317548065 */, 17 },
+ /* 2915 */ { MAD_F(0x051545a5) /* 0.317693371 */, 17 },
+ /* 2916 */ { MAD_F(0x0515de06) /* 0.317838693 */, 17 },
+ /* 2917 */ { MAD_F(0x0516766d) /* 0.317984033 */, 17 },
+ /* 2918 */ { MAD_F(0x05170ed7) /* 0.318129388 */, 17 },
+ /* 2919 */ { MAD_F(0x0517a746) /* 0.318274761 */, 17 },
+ /* 2920 */ { MAD_F(0x05183fba) /* 0.318420150 */, 17 },
+ /* 2921 */ { MAD_F(0x0518d832) /* 0.318565555 */, 17 },
+ /* 2922 */ { MAD_F(0x051970ae) /* 0.318710978 */, 17 },
+ /* 2923 */ { MAD_F(0x051a092f) /* 0.318856416 */, 17 },
+ /* 2924 */ { MAD_F(0x051aa1b5) /* 0.319001872 */, 17 },
+ /* 2925 */ { MAD_F(0x051b3a3f) /* 0.319147344 */, 17 },
+ /* 2926 */ { MAD_F(0x051bd2cd) /* 0.319292832 */, 17 },
+ /* 2927 */ { MAD_F(0x051c6b60) /* 0.319438338 */, 17 },
+
+ /* 2928 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 17 },
+ /* 2929 */ { MAD_F(0x051d9c92) /* 0.319729398 */, 17 },
+ /* 2930 */ { MAD_F(0x051e3532) /* 0.319874952 */, 17 },
+ /* 2931 */ { MAD_F(0x051ecdd7) /* 0.320020524 */, 17 },
+ /* 2932 */ { MAD_F(0x051f6680) /* 0.320166112 */, 17 },
+ /* 2933 */ { MAD_F(0x051fff2d) /* 0.320311716 */, 17 },
+ /* 2934 */ { MAD_F(0x052097df) /* 0.320457337 */, 17 },
+ /* 2935 */ { MAD_F(0x05213095) /* 0.320602975 */, 17 },
+ /* 2936 */ { MAD_F(0x0521c950) /* 0.320748629 */, 17 },
+ /* 2937 */ { MAD_F(0x0522620f) /* 0.320894300 */, 17 },
+ /* 2938 */ { MAD_F(0x0522fad3) /* 0.321039987 */, 17 },
+ /* 2939 */ { MAD_F(0x0523939b) /* 0.321185691 */, 17 },
+ /* 2940 */ { MAD_F(0x05242c68) /* 0.321331411 */, 17 },
+ /* 2941 */ { MAD_F(0x0524c538) /* 0.321477148 */, 17 },
+ /* 2942 */ { MAD_F(0x05255e0e) /* 0.321622901 */, 17 },
+ /* 2943 */ { MAD_F(0x0525f6e8) /* 0.321768671 */, 17 },
+
+ /* 2944 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 17 },
+ /* 2945 */ { MAD_F(0x052728a9) /* 0.322060260 */, 17 },
+ /* 2946 */ { MAD_F(0x0527c190) /* 0.322206079 */, 17 },
+ /* 2947 */ { MAD_F(0x05285a7b) /* 0.322351915 */, 17 },
+ /* 2948 */ { MAD_F(0x0528f36b) /* 0.322497768 */, 17 },
+ /* 2949 */ { MAD_F(0x05298c5f) /* 0.322643636 */, 17 },
+ /* 2950 */ { MAD_F(0x052a2558) /* 0.322789522 */, 17 },
+ /* 2951 */ { MAD_F(0x052abe55) /* 0.322935424 */, 17 },
+ /* 2952 */ { MAD_F(0x052b5757) /* 0.323081342 */, 17 },
+ /* 2953 */ { MAD_F(0x052bf05d) /* 0.323227277 */, 17 },
+ /* 2954 */ { MAD_F(0x052c8968) /* 0.323373228 */, 17 },
+ /* 2955 */ { MAD_F(0x052d2277) /* 0.323519196 */, 17 },
+ /* 2956 */ { MAD_F(0x052dbb8a) /* 0.323665180 */, 17 },
+ /* 2957 */ { MAD_F(0x052e54a2) /* 0.323811180 */, 17 },
+ /* 2958 */ { MAD_F(0x052eedbe) /* 0.323957197 */, 17 },
+ /* 2959 */ { MAD_F(0x052f86de) /* 0.324103231 */, 17 },
+
+ /* 2960 */ { MAD_F(0x05302003) /* 0.324249281 */, 17 },
+ /* 2961 */ { MAD_F(0x0530b92d) /* 0.324395347 */, 17 },
+ /* 2962 */ { MAD_F(0x0531525b) /* 0.324541430 */, 17 },
+ /* 2963 */ { MAD_F(0x0531eb8d) /* 0.324687530 */, 17 },
+ /* 2964 */ { MAD_F(0x053284c4) /* 0.324833646 */, 17 },
+ /* 2965 */ { MAD_F(0x05331dff) /* 0.324979778 */, 17 },
+ /* 2966 */ { MAD_F(0x0533b73e) /* 0.325125926 */, 17 },
+ /* 2967 */ { MAD_F(0x05345082) /* 0.325272091 */, 17 },
+ /* 2968 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 17 },
+ /* 2969 */ { MAD_F(0x05358317) /* 0.325564471 */, 17 },
+ /* 2970 */ { MAD_F(0x05361c68) /* 0.325710685 */, 17 },
+ /* 2971 */ { MAD_F(0x0536b5be) /* 0.325856916 */, 17 },
+ /* 2972 */ { MAD_F(0x05374f17) /* 0.326003163 */, 17 },
+ /* 2973 */ { MAD_F(0x0537e876) /* 0.326149427 */, 17 },
+ /* 2974 */ { MAD_F(0x053881d9) /* 0.326295707 */, 17 },
+ /* 2975 */ { MAD_F(0x05391b40) /* 0.326442003 */, 17 },
+
+ /* 2976 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 17 },
+ /* 2977 */ { MAD_F(0x053a4e1b) /* 0.326734645 */, 17 },
+ /* 2978 */ { MAD_F(0x053ae78f) /* 0.326880990 */, 17 },
+ /* 2979 */ { MAD_F(0x053b8108) /* 0.327027352 */, 17 },
+ /* 2980 */ { MAD_F(0x053c1a85) /* 0.327173730 */, 17 },
+ /* 2981 */ { MAD_F(0x053cb407) /* 0.327320125 */, 17 },
+ /* 2982 */ { MAD_F(0x053d4d8d) /* 0.327466536 */, 17 },
+ /* 2983 */ { MAD_F(0x053de717) /* 0.327612963 */, 17 },
+ /* 2984 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 17 },
+ /* 2985 */ { MAD_F(0x053f1a39) /* 0.327905867 */, 17 },
+ /* 2986 */ { MAD_F(0x053fb3d0) /* 0.328052344 */, 17 },
+ /* 2987 */ { MAD_F(0x05404d6c) /* 0.328198837 */, 17 },
+ /* 2988 */ { MAD_F(0x0540e70c) /* 0.328345346 */, 17 },
+ /* 2989 */ { MAD_F(0x054180b1) /* 0.328491871 */, 17 },
+ /* 2990 */ { MAD_F(0x05421a5a) /* 0.328638413 */, 17 },
+ /* 2991 */ { MAD_F(0x0542b407) /* 0.328784971 */, 17 },
+
+ /* 2992 */ { MAD_F(0x05434db9) /* 0.328931546 */, 17 },
+ /* 2993 */ { MAD_F(0x0543e76f) /* 0.329078137 */, 17 },
+ /* 2994 */ { MAD_F(0x0544812a) /* 0.329224744 */, 17 },
+ /* 2995 */ { MAD_F(0x05451ae9) /* 0.329371367 */, 17 },
+ /* 2996 */ { MAD_F(0x0545b4ac) /* 0.329518007 */, 17 },
+ /* 2997 */ { MAD_F(0x05464e74) /* 0.329664663 */, 17 },
+ /* 2998 */ { MAD_F(0x0546e840) /* 0.329811336 */, 17 },
+ /* 2999 */ { MAD_F(0x05478211) /* 0.329958024 */, 17 },
+ /* 3000 */ { MAD_F(0x05481be5) /* 0.330104730 */, 17 },
+ /* 3001 */ { MAD_F(0x0548b5bf) /* 0.330251451 */, 17 },
+ /* 3002 */ { MAD_F(0x05494f9c) /* 0.330398189 */, 17 },
+ /* 3003 */ { MAD_F(0x0549e97e) /* 0.330544943 */, 17 },
+ /* 3004 */ { MAD_F(0x054a8364) /* 0.330691713 */, 17 },
+ /* 3005 */ { MAD_F(0x054b1d4f) /* 0.330838499 */, 17 },
+ /* 3006 */ { MAD_F(0x054bb73e) /* 0.330985302 */, 17 },
+ /* 3007 */ { MAD_F(0x054c5132) /* 0.331132121 */, 17 },
+
+ /* 3008 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 17 },
+ /* 3009 */ { MAD_F(0x054d8526) /* 0.331425808 */, 17 },
+ /* 3010 */ { MAD_F(0x054e1f26) /* 0.331572676 */, 17 },
+ /* 3011 */ { MAD_F(0x054eb92b) /* 0.331719560 */, 17 },
+ /* 3012 */ { MAD_F(0x054f5334) /* 0.331866461 */, 17 },
+ /* 3013 */ { MAD_F(0x054fed42) /* 0.332013377 */, 17 },
+ /* 3014 */ { MAD_F(0x05508754) /* 0.332160310 */, 17 },
+ /* 3015 */ { MAD_F(0x0551216b) /* 0.332307260 */, 17 },
+ /* 3016 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 17 },
+ /* 3017 */ { MAD_F(0x055255a4) /* 0.332601207 */, 17 },
+ /* 3018 */ { MAD_F(0x0552efc8) /* 0.332748205 */, 17 },
+ /* 3019 */ { MAD_F(0x055389f0) /* 0.332895219 */, 17 },
+ /* 3020 */ { MAD_F(0x0554241c) /* 0.333042249 */, 17 },
+ /* 3021 */ { MAD_F(0x0554be4c) /* 0.333189296 */, 17 },
+ /* 3022 */ { MAD_F(0x05555881) /* 0.333336359 */, 17 },
+ /* 3023 */ { MAD_F(0x0555f2ba) /* 0.333483438 */, 17 },
+
+ /* 3024 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 17 },
+ /* 3025 */ { MAD_F(0x0557273a) /* 0.333777645 */, 17 },
+ /* 3026 */ { MAD_F(0x0557c180) /* 0.333924772 */, 17 },
+ /* 3027 */ { MAD_F(0x05585bcb) /* 0.334071916 */, 17 },
+ /* 3028 */ { MAD_F(0x0558f61a) /* 0.334219076 */, 17 },
+ /* 3029 */ { MAD_F(0x0559906d) /* 0.334366253 */, 17 },
+ /* 3030 */ { MAD_F(0x055a2ac5) /* 0.334513445 */, 17 },
+ /* 3031 */ { MAD_F(0x055ac521) /* 0.334660654 */, 17 },
+ /* 3032 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 17 },
+ /* 3033 */ { MAD_F(0x055bf9e6) /* 0.334955120 */, 17 },
+ /* 3034 */ { MAD_F(0x055c944f) /* 0.335102377 */, 17 },
+ /* 3035 */ { MAD_F(0x055d2ebd) /* 0.335249651 */, 17 },
+ /* 3036 */ { MAD_F(0x055dc92e) /* 0.335396941 */, 17 },
+ /* 3037 */ { MAD_F(0x055e63a5) /* 0.335544246 */, 17 },
+ /* 3038 */ { MAD_F(0x055efe1f) /* 0.335691568 */, 17 },
+ /* 3039 */ { MAD_F(0x055f989e) /* 0.335838906 */, 17 },
+
+ /* 3040 */ { MAD_F(0x05603321) /* 0.335986261 */, 17 },
+ /* 3041 */ { MAD_F(0x0560cda8) /* 0.336133631 */, 17 },
+ /* 3042 */ { MAD_F(0x05616834) /* 0.336281018 */, 17 },
+ /* 3043 */ { MAD_F(0x056202c4) /* 0.336428421 */, 17 },
+ /* 3044 */ { MAD_F(0x05629d59) /* 0.336575840 */, 17 },
+ /* 3045 */ { MAD_F(0x056337f2) /* 0.336723275 */, 17 },
+ /* 3046 */ { MAD_F(0x0563d28f) /* 0.336870726 */, 17 },
+ /* 3047 */ { MAD_F(0x05646d30) /* 0.337018193 */, 17 },
+ /* 3048 */ { MAD_F(0x056507d6) /* 0.337165677 */, 17 },
+ /* 3049 */ { MAD_F(0x0565a280) /* 0.337313176 */, 17 },
+ /* 3050 */ { MAD_F(0x05663d2f) /* 0.337460692 */, 17 },
+ /* 3051 */ { MAD_F(0x0566d7e1) /* 0.337608224 */, 17 },
+ /* 3052 */ { MAD_F(0x05677298) /* 0.337755772 */, 17 },
+ /* 3053 */ { MAD_F(0x05680d54) /* 0.337903336 */, 17 },
+ /* 3054 */ { MAD_F(0x0568a814) /* 0.338050916 */, 17 },
+ /* 3055 */ { MAD_F(0x056942d8) /* 0.338198513 */, 17 },
+
+ /* 3056 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 17 },
+ /* 3057 */ { MAD_F(0x056a786d) /* 0.338493753 */, 17 },
+ /* 3058 */ { MAD_F(0x056b133e) /* 0.338641398 */, 17 },
+ /* 3059 */ { MAD_F(0x056bae13) /* 0.338789059 */, 17 },
+ /* 3060 */ { MAD_F(0x056c48ed) /* 0.338936736 */, 17 },
+ /* 3061 */ { MAD_F(0x056ce3cb) /* 0.339084429 */, 17 },
+ /* 3062 */ { MAD_F(0x056d7ead) /* 0.339232138 */, 17 },
+ /* 3063 */ { MAD_F(0x056e1994) /* 0.339379863 */, 17 },
+ /* 3064 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 17 },
+ /* 3065 */ { MAD_F(0x056f4f6e) /* 0.339675361 */, 17 },
+ /* 3066 */ { MAD_F(0x056fea62) /* 0.339823134 */, 17 },
+ /* 3067 */ { MAD_F(0x0570855a) /* 0.339970924 */, 17 },
+ /* 3068 */ { MAD_F(0x05712056) /* 0.340118729 */, 17 },
+ /* 3069 */ { MAD_F(0x0571bb56) /* 0.340266550 */, 17 },
+ /* 3070 */ { MAD_F(0x0572565b) /* 0.340414388 */, 17 },
+ /* 3071 */ { MAD_F(0x0572f164) /* 0.340562242 */, 17 },
+
+ /* 3072 */ { MAD_F(0x05738c72) /* 0.340710111 */, 17 },
+ /* 3073 */ { MAD_F(0x05742784) /* 0.340857997 */, 17 },
+ /* 3074 */ { MAD_F(0x0574c29a) /* 0.341005899 */, 17 },
+ /* 3075 */ { MAD_F(0x05755db4) /* 0.341153816 */, 17 },
+ /* 3076 */ { MAD_F(0x0575f8d3) /* 0.341301750 */, 17 },
+ /* 3077 */ { MAD_F(0x057693f6) /* 0.341449700 */, 17 },
+ /* 3078 */ { MAD_F(0x05772f1d) /* 0.341597666 */, 17 },
+ /* 3079 */ { MAD_F(0x0577ca49) /* 0.341745648 */, 17 },
+ /* 3080 */ { MAD_F(0x05786578) /* 0.341893646 */, 17 },
+ /* 3081 */ { MAD_F(0x057900ad) /* 0.342041659 */, 17 },
+ /* 3082 */ { MAD_F(0x05799be5) /* 0.342189689 */, 17 },
+ /* 3083 */ { MAD_F(0x057a3722) /* 0.342337735 */, 17 },
+ /* 3084 */ { MAD_F(0x057ad263) /* 0.342485797 */, 17 },
+ /* 3085 */ { MAD_F(0x057b6da8) /* 0.342633875 */, 17 },
+ /* 3086 */ { MAD_F(0x057c08f2) /* 0.342781969 */, 17 },
+ /* 3087 */ { MAD_F(0x057ca440) /* 0.342930079 */, 17 },
+
+ /* 3088 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 17 },
+ /* 3089 */ { MAD_F(0x057ddae9) /* 0.343226347 */, 17 },
+ /* 3090 */ { MAD_F(0x057e7644) /* 0.343374505 */, 17 },
+ /* 3091 */ { MAD_F(0x057f11a3) /* 0.343522679 */, 17 },
+ /* 3092 */ { MAD_F(0x057fad06) /* 0.343670869 */, 17 },
+ /* 3093 */ { MAD_F(0x0580486e) /* 0.343819075 */, 17 },
+ /* 3094 */ { MAD_F(0x0580e3da) /* 0.343967296 */, 17 },
+ /* 3095 */ { MAD_F(0x05817f4a) /* 0.344115534 */, 17 },
+ /* 3096 */ { MAD_F(0x05821abf) /* 0.344263788 */, 17 },
+ /* 3097 */ { MAD_F(0x0582b638) /* 0.344412058 */, 17 },
+ /* 3098 */ { MAD_F(0x058351b5) /* 0.344560343 */, 17 },
+ /* 3099 */ { MAD_F(0x0583ed36) /* 0.344708645 */, 17 },
+ /* 3100 */ { MAD_F(0x058488bc) /* 0.344856963 */, 17 },
+ /* 3101 */ { MAD_F(0x05852446) /* 0.345005296 */, 17 },
+ /* 3102 */ { MAD_F(0x0585bfd4) /* 0.345153646 */, 17 },
+ /* 3103 */ { MAD_F(0x05865b67) /* 0.345302011 */, 17 },
+
+ /* 3104 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 17 },
+ /* 3105 */ { MAD_F(0x05879298) /* 0.345598790 */, 17 },
+ /* 3106 */ { MAD_F(0x05882e38) /* 0.345747203 */, 17 },
+ /* 3107 */ { MAD_F(0x0588c9dc) /* 0.345895632 */, 17 },
+ /* 3108 */ { MAD_F(0x05896583) /* 0.346044077 */, 17 },
+ /* 3109 */ { MAD_F(0x058a0130) /* 0.346192538 */, 17 },
+ /* 3110 */ { MAD_F(0x058a9ce0) /* 0.346341015 */, 17 },
+ /* 3111 */ { MAD_F(0x058b3895) /* 0.346489508 */, 17 },
+ /* 3112 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 17 },
+ /* 3113 */ { MAD_F(0x058c700b) /* 0.346786542 */, 17 },
+ /* 3114 */ { MAD_F(0x058d0bcd) /* 0.346935082 */, 17 },
+ /* 3115 */ { MAD_F(0x058da793) /* 0.347083639 */, 17 },
+ /* 3116 */ { MAD_F(0x058e435d) /* 0.347232211 */, 17 },
+ /* 3117 */ { MAD_F(0x058edf2b) /* 0.347380799 */, 17 },
+ /* 3118 */ { MAD_F(0x058f7afe) /* 0.347529403 */, 17 },
+ /* 3119 */ { MAD_F(0x059016d5) /* 0.347678023 */, 17 },
+
+ /* 3120 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 17 },
+ /* 3121 */ { MAD_F(0x05914e8f) /* 0.347975311 */, 17 },
+ /* 3122 */ { MAD_F(0x0591ea73) /* 0.348123979 */, 17 },
+ /* 3123 */ { MAD_F(0x0592865b) /* 0.348272662 */, 17 },
+ /* 3124 */ { MAD_F(0x05932247) /* 0.348421362 */, 17 },
+ /* 3125 */ { MAD_F(0x0593be37) /* 0.348570077 */, 17 },
+ /* 3126 */ { MAD_F(0x05945a2c) /* 0.348718808 */, 17 },
+ /* 3127 */ { MAD_F(0x0594f625) /* 0.348867555 */, 17 },
+ /* 3128 */ { MAD_F(0x05959222) /* 0.349016318 */, 17 },
+ /* 3129 */ { MAD_F(0x05962e24) /* 0.349165097 */, 17 },
+ /* 3130 */ { MAD_F(0x0596ca2a) /* 0.349313892 */, 17 },
+ /* 3131 */ { MAD_F(0x05976634) /* 0.349462702 */, 17 },
+ /* 3132 */ { MAD_F(0x05980242) /* 0.349611528 */, 17 },
+ /* 3133 */ { MAD_F(0x05989e54) /* 0.349760370 */, 17 },
+ /* 3134 */ { MAD_F(0x05993a6b) /* 0.349909228 */, 17 },
+ /* 3135 */ { MAD_F(0x0599d686) /* 0.350058102 */, 17 },
+
+ /* 3136 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 17 },
+ /* 3137 */ { MAD_F(0x059b0ec9) /* 0.350355897 */, 17 },
+ /* 3138 */ { MAD_F(0x059baaf1) /* 0.350504818 */, 17 },
+ /* 3139 */ { MAD_F(0x059c471d) /* 0.350653756 */, 17 },
+ /* 3140 */ { MAD_F(0x059ce34d) /* 0.350802708 */, 17 },
+ /* 3141 */ { MAD_F(0x059d7f81) /* 0.350951677 */, 17 },
+ /* 3142 */ { MAD_F(0x059e1bba) /* 0.351100662 */, 17 },
+ /* 3143 */ { MAD_F(0x059eb7f7) /* 0.351249662 */, 17 },
+ /* 3144 */ { MAD_F(0x059f5438) /* 0.351398678 */, 17 },
+ /* 3145 */ { MAD_F(0x059ff07e) /* 0.351547710 */, 17 },
+ /* 3146 */ { MAD_F(0x05a08cc7) /* 0.351696758 */, 17 },
+ /* 3147 */ { MAD_F(0x05a12915) /* 0.351845821 */, 17 },
+ /* 3148 */ { MAD_F(0x05a1c567) /* 0.351994901 */, 17 },
+ /* 3149 */ { MAD_F(0x05a261be) /* 0.352143996 */, 17 },
+ /* 3150 */ { MAD_F(0x05a2fe18) /* 0.352293107 */, 17 },
+ /* 3151 */ { MAD_F(0x05a39a77) /* 0.352442233 */, 17 },
+
+ /* 3152 */ { MAD_F(0x05a436da) /* 0.352591376 */, 17 },
+ /* 3153 */ { MAD_F(0x05a4d342) /* 0.352740534 */, 17 },
+ /* 3154 */ { MAD_F(0x05a56fad) /* 0.352889708 */, 17 },
+ /* 3155 */ { MAD_F(0x05a60c1d) /* 0.353038898 */, 17 },
+ /* 3156 */ { MAD_F(0x05a6a891) /* 0.353188103 */, 17 },
+ /* 3157 */ { MAD_F(0x05a7450a) /* 0.353337325 */, 17 },
+ /* 3158 */ { MAD_F(0x05a7e186) /* 0.353486562 */, 17 },
+ /* 3159 */ { MAD_F(0x05a87e07) /* 0.353635814 */, 17 },
+ /* 3160 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 17 },
+ /* 3161 */ { MAD_F(0x05a9b715) /* 0.353934367 */, 17 },
+ /* 3162 */ { MAD_F(0x05aa53a2) /* 0.354083667 */, 17 },
+ /* 3163 */ { MAD_F(0x05aaf034) /* 0.354232983 */, 17 },
+ /* 3164 */ { MAD_F(0x05ab8cca) /* 0.354382314 */, 17 },
+ /* 3165 */ { MAD_F(0x05ac2964) /* 0.354531662 */, 17 },
+ /* 3166 */ { MAD_F(0x05acc602) /* 0.354681025 */, 17 },
+ /* 3167 */ { MAD_F(0x05ad62a5) /* 0.354830403 */, 17 },
+
+ /* 3168 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 17 },
+ /* 3169 */ { MAD_F(0x05ae9bf7) /* 0.355129208 */, 17 },
+ /* 3170 */ { MAD_F(0x05af38a6) /* 0.355278634 */, 17 },
+ /* 3171 */ { MAD_F(0x05afd559) /* 0.355428075 */, 17 },
+ /* 3172 */ { MAD_F(0x05b07211) /* 0.355577533 */, 17 },
+ /* 3173 */ { MAD_F(0x05b10ecd) /* 0.355727006 */, 17 },
+ /* 3174 */ { MAD_F(0x05b1ab8d) /* 0.355876494 */, 17 },
+ /* 3175 */ { MAD_F(0x05b24851) /* 0.356025999 */, 17 },
+ /* 3176 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 17 },
+ /* 3177 */ { MAD_F(0x05b381e6) /* 0.356325054 */, 17 },
+ /* 3178 */ { MAD_F(0x05b41eb7) /* 0.356474606 */, 17 },
+ /* 3179 */ { MAD_F(0x05b4bb8c) /* 0.356624173 */, 17 },
+ /* 3180 */ { MAD_F(0x05b55866) /* 0.356773756 */, 17 },
+ /* 3181 */ { MAD_F(0x05b5f543) /* 0.356923354 */, 17 },
+ /* 3182 */ { MAD_F(0x05b69225) /* 0.357072969 */, 17 },
+ /* 3183 */ { MAD_F(0x05b72f0b) /* 0.357222598 */, 17 },
+
+ /* 3184 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 17 },
+ /* 3185 */ { MAD_F(0x05b868e3) /* 0.357521905 */, 17 },
+ /* 3186 */ { MAD_F(0x05b905d6) /* 0.357671582 */, 17 },
+ /* 3187 */ { MAD_F(0x05b9a2cd) /* 0.357821275 */, 17 },
+ /* 3188 */ { MAD_F(0x05ba3fc8) /* 0.357970983 */, 17 },
+ /* 3189 */ { MAD_F(0x05badcc7) /* 0.358120707 */, 17 },
+ /* 3190 */ { MAD_F(0x05bb79ca) /* 0.358270446 */, 17 },
+ /* 3191 */ { MAD_F(0x05bc16d2) /* 0.358420201 */, 17 },
+ /* 3192 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 17 },
+ /* 3193 */ { MAD_F(0x05bd50ee) /* 0.358719758 */, 17 },
+ /* 3194 */ { MAD_F(0x05bdee02) /* 0.358869560 */, 17 },
+ /* 3195 */ { MAD_F(0x05be8b1a) /* 0.359019378 */, 17 },
+ /* 3196 */ { MAD_F(0x05bf2837) /* 0.359169211 */, 17 },
+ /* 3197 */ { MAD_F(0x05bfc558) /* 0.359319060 */, 17 },
+ /* 3198 */ { MAD_F(0x05c0627d) /* 0.359468925 */, 17 },
+ /* 3199 */ { MAD_F(0x05c0ffa6) /* 0.359618805 */, 17 },
+
+ /* 3200 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 17 },
+ /* 3201 */ { MAD_F(0x05c23a05) /* 0.359918612 */, 17 },
+ /* 3202 */ { MAD_F(0x05c2d73a) /* 0.360068540 */, 17 },
+ /* 3203 */ { MAD_F(0x05c37474) /* 0.360218482 */, 17 },
+ /* 3204 */ { MAD_F(0x05c411b2) /* 0.360368440 */, 17 },
+ /* 3205 */ { MAD_F(0x05c4aef5) /* 0.360518414 */, 17 },
+ /* 3206 */ { MAD_F(0x05c54c3b) /* 0.360668404 */, 17 },
+ /* 3207 */ { MAD_F(0x05c5e986) /* 0.360818409 */, 17 },
+ /* 3208 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 17 },
+ /* 3209 */ { MAD_F(0x05c72428) /* 0.361118466 */, 17 },
+ /* 3210 */ { MAD_F(0x05c7c17f) /* 0.361268517 */, 17 },
+ /* 3211 */ { MAD_F(0x05c85eda) /* 0.361418585 */, 17 },
+ /* 3212 */ { MAD_F(0x05c8fc3a) /* 0.361568668 */, 17 },
+ /* 3213 */ { MAD_F(0x05c9999e) /* 0.361718766 */, 17 },
+ /* 3214 */ { MAD_F(0x05ca3706) /* 0.361868881 */, 17 },
+ /* 3215 */ { MAD_F(0x05cad472) /* 0.362019010 */, 17 },
+
+ /* 3216 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 17 },
+ /* 3217 */ { MAD_F(0x05cc0f57) /* 0.362319316 */, 17 },
+ /* 3218 */ { MAD_F(0x05ccaccf) /* 0.362469493 */, 17 },
+ /* 3219 */ { MAD_F(0x05cd4a4c) /* 0.362619685 */, 17 },
+ /* 3220 */ { MAD_F(0x05cde7cd) /* 0.362769892 */, 17 },
+ /* 3221 */ { MAD_F(0x05ce8552) /* 0.362920115 */, 17 },
+ /* 3222 */ { MAD_F(0x05cf22dc) /* 0.363070354 */, 17 },
+ /* 3223 */ { MAD_F(0x05cfc069) /* 0.363220608 */, 17 },
+ /* 3224 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 17 },
+ /* 3225 */ { MAD_F(0x05d0fb91) /* 0.363521163 */, 17 },
+ /* 3226 */ { MAD_F(0x05d1992b) /* 0.363671464 */, 17 },
+ /* 3227 */ { MAD_F(0x05d236c9) /* 0.363821780 */, 17 },
+ /* 3228 */ { MAD_F(0x05d2d46c) /* 0.363972112 */, 17 },
+ /* 3229 */ { MAD_F(0x05d37212) /* 0.364122459 */, 17 },
+ /* 3230 */ { MAD_F(0x05d40fbd) /* 0.364272822 */, 17 },
+ /* 3231 */ { MAD_F(0x05d4ad6c) /* 0.364423200 */, 17 },
+
+ /* 3232 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 17 },
+ /* 3233 */ { MAD_F(0x05d5e8d6) /* 0.364724004 */, 17 },
+ /* 3234 */ { MAD_F(0x05d68691) /* 0.364874429 */, 17 },
+ /* 3235 */ { MAD_F(0x05d72451) /* 0.365024869 */, 17 },
+ /* 3236 */ { MAD_F(0x05d7c215) /* 0.365175325 */, 17 },
+ /* 3237 */ { MAD_F(0x05d85fdc) /* 0.365325796 */, 17 },
+ /* 3238 */ { MAD_F(0x05d8fda8) /* 0.365476283 */, 17 },
+ /* 3239 */ { MAD_F(0x05d99b79) /* 0.365626786 */, 17 },
+ /* 3240 */ { MAD_F(0x05da394d) /* 0.365777304 */, 17 },
+ /* 3241 */ { MAD_F(0x05dad726) /* 0.365927837 */, 17 },
+ /* 3242 */ { MAD_F(0x05db7502) /* 0.366078386 */, 17 },
+ /* 3243 */ { MAD_F(0x05dc12e3) /* 0.366228950 */, 17 },
+ /* 3244 */ { MAD_F(0x05dcb0c8) /* 0.366379530 */, 17 },
+ /* 3245 */ { MAD_F(0x05dd4eb1) /* 0.366530125 */, 17 },
+ /* 3246 */ { MAD_F(0x05ddec9e) /* 0.366680736 */, 17 },
+ /* 3247 */ { MAD_F(0x05de8a90) /* 0.366831362 */, 17 },
+
+ /* 3248 */ { MAD_F(0x05df2885) /* 0.366982004 */, 17 },
+ /* 3249 */ { MAD_F(0x05dfc67f) /* 0.367132661 */, 17 },
+ /* 3250 */ { MAD_F(0x05e0647d) /* 0.367283334 */, 17 },
+ /* 3251 */ { MAD_F(0x05e1027f) /* 0.367434022 */, 17 },
+ /* 3252 */ { MAD_F(0x05e1a085) /* 0.367584725 */, 17 },
+ /* 3253 */ { MAD_F(0x05e23e8f) /* 0.367735444 */, 17 },
+ /* 3254 */ { MAD_F(0x05e2dc9e) /* 0.367886179 */, 17 },
+ /* 3255 */ { MAD_F(0x05e37ab0) /* 0.368036929 */, 17 },
+ /* 3256 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 17 },
+ /* 3257 */ { MAD_F(0x05e4b6e2) /* 0.368338475 */, 17 },
+ /* 3258 */ { MAD_F(0x05e55501) /* 0.368489271 */, 17 },
+ /* 3259 */ { MAD_F(0x05e5f324) /* 0.368640082 */, 17 },
+ /* 3260 */ { MAD_F(0x05e6914c) /* 0.368790909 */, 17 },
+ /* 3261 */ { MAD_F(0x05e72f77) /* 0.368941752 */, 17 },
+ /* 3262 */ { MAD_F(0x05e7cda7) /* 0.369092610 */, 17 },
+ /* 3263 */ { MAD_F(0x05e86bda) /* 0.369243483 */, 17 },
+
+ /* 3264 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 17 },
+ /* 3265 */ { MAD_F(0x05e9a84e) /* 0.369545276 */, 17 },
+ /* 3266 */ { MAD_F(0x05ea468e) /* 0.369696195 */, 17 },
+ /* 3267 */ { MAD_F(0x05eae4d3) /* 0.369847130 */, 17 },
+ /* 3268 */ { MAD_F(0x05eb831b) /* 0.369998080 */, 17 },
+ /* 3269 */ { MAD_F(0x05ec2168) /* 0.370149046 */, 17 },
+ /* 3270 */ { MAD_F(0x05ecbfb8) /* 0.370300027 */, 17 },
+ /* 3271 */ { MAD_F(0x05ed5e0d) /* 0.370451024 */, 17 },
+ /* 3272 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 17 },
+ /* 3273 */ { MAD_F(0x05ee9ac3) /* 0.370753063 */, 17 },
+ /* 3274 */ { MAD_F(0x05ef3924) /* 0.370904105 */, 17 },
+ /* 3275 */ { MAD_F(0x05efd78a) /* 0.371055163 */, 17 },
+ /* 3276 */ { MAD_F(0x05f075f3) /* 0.371206237 */, 17 },
+ /* 3277 */ { MAD_F(0x05f11461) /* 0.371357326 */, 17 },
+ /* 3278 */ { MAD_F(0x05f1b2d3) /* 0.371508430 */, 17 },
+ /* 3279 */ { MAD_F(0x05f25148) /* 0.371659549 */, 17 },
+
+ /* 3280 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 17 },
+ /* 3281 */ { MAD_F(0x05f38e40) /* 0.371961834 */, 17 },
+ /* 3282 */ { MAD_F(0x05f42cc3) /* 0.372113000 */, 17 },
+ /* 3283 */ { MAD_F(0x05f4cb49) /* 0.372264181 */, 17 },
+ /* 3284 */ { MAD_F(0x05f569d3) /* 0.372415377 */, 17 },
+ /* 3285 */ { MAD_F(0x05f60862) /* 0.372566589 */, 17 },
+ /* 3286 */ { MAD_F(0x05f6a6f5) /* 0.372717816 */, 17 },
+ /* 3287 */ { MAD_F(0x05f7458b) /* 0.372869058 */, 17 },
+ /* 3288 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 17 },
+ /* 3289 */ { MAD_F(0x05f882c5) /* 0.373171589 */, 17 },
+ /* 3290 */ { MAD_F(0x05f92169) /* 0.373322877 */, 17 },
+ /* 3291 */ { MAD_F(0x05f9c010) /* 0.373474181 */, 17 },
+ /* 3292 */ { MAD_F(0x05fa5ebb) /* 0.373625500 */, 17 },
+ /* 3293 */ { MAD_F(0x05fafd6b) /* 0.373776834 */, 17 },
+ /* 3294 */ { MAD_F(0x05fb9c1e) /* 0.373928184 */, 17 },
+ /* 3295 */ { MAD_F(0x05fc3ad6) /* 0.374079549 */, 17 },
+
+ /* 3296 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 17 },
+ /* 3297 */ { MAD_F(0x05fd7852) /* 0.374382325 */, 17 },
+ /* 3298 */ { MAD_F(0x05fe1716) /* 0.374533735 */, 17 },
+ /* 3299 */ { MAD_F(0x05feb5de) /* 0.374685162 */, 17 },
+ /* 3300 */ { MAD_F(0x05ff54aa) /* 0.374836603 */, 17 },
+ /* 3301 */ { MAD_F(0x05fff37b) /* 0.374988060 */, 17 },
+ /* 3302 */ { MAD_F(0x0600924f) /* 0.375139532 */, 17 },
+ /* 3303 */ { MAD_F(0x06013128) /* 0.375291019 */, 17 },
+ /* 3304 */ { MAD_F(0x0601d004) /* 0.375442522 */, 17 },
+ /* 3305 */ { MAD_F(0x06026ee5) /* 0.375594040 */, 17 },
+ /* 3306 */ { MAD_F(0x06030dca) /* 0.375745573 */, 17 },
+ /* 3307 */ { MAD_F(0x0603acb3) /* 0.375897122 */, 17 },
+ /* 3308 */ { MAD_F(0x06044ba0) /* 0.376048685 */, 17 },
+ /* 3309 */ { MAD_F(0x0604ea91) /* 0.376200265 */, 17 },
+ /* 3310 */ { MAD_F(0x06058987) /* 0.376351859 */, 17 },
+ /* 3311 */ { MAD_F(0x06062880) /* 0.376503468 */, 17 },
+
+ /* 3312 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 17 },
+ /* 3313 */ { MAD_F(0x0607667f) /* 0.376806733 */, 17 },
+ /* 3314 */ { MAD_F(0x06080585) /* 0.376958389 */, 17 },
+ /* 3315 */ { MAD_F(0x0608a48f) /* 0.377110059 */, 17 },
+ /* 3316 */ { MAD_F(0x0609439c) /* 0.377261745 */, 17 },
+ /* 3317 */ { MAD_F(0x0609e2ae) /* 0.377413446 */, 17 },
+ /* 3318 */ { MAD_F(0x060a81c4) /* 0.377565163 */, 17 },
+ /* 3319 */ { MAD_F(0x060b20df) /* 0.377716894 */, 17 },
+ /* 3320 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 17 },
+ /* 3321 */ { MAD_F(0x060c5f1f) /* 0.378020403 */, 17 },
+ /* 3322 */ { MAD_F(0x060cfe46) /* 0.378172181 */, 17 },
+ /* 3323 */ { MAD_F(0x060d9d70) /* 0.378323973 */, 17 },
+ /* 3324 */ { MAD_F(0x060e3c9f) /* 0.378475781 */, 17 },
+ /* 3325 */ { MAD_F(0x060edbd1) /* 0.378627604 */, 17 },
+ /* 3326 */ { MAD_F(0x060f7b08) /* 0.378779442 */, 17 },
+ /* 3327 */ { MAD_F(0x06101a43) /* 0.378931296 */, 17 },
+
+ /* 3328 */ { MAD_F(0x0610b982) /* 0.379083164 */, 17 },
+ /* 3329 */ { MAD_F(0x061158c5) /* 0.379235048 */, 17 },
+ /* 3330 */ { MAD_F(0x0611f80c) /* 0.379386947 */, 17 },
+ /* 3331 */ { MAD_F(0x06129757) /* 0.379538862 */, 17 },
+ /* 3332 */ { MAD_F(0x061336a6) /* 0.379690791 */, 17 },
+ /* 3333 */ { MAD_F(0x0613d5fa) /* 0.379842736 */, 17 },
+ /* 3334 */ { MAD_F(0x06147551) /* 0.379994696 */, 17 },
+ /* 3335 */ { MAD_F(0x061514ad) /* 0.380146671 */, 17 },
+ /* 3336 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 17 },
+ /* 3337 */ { MAD_F(0x06165370) /* 0.380450666 */, 17 },
+ /* 3338 */ { MAD_F(0x0616f2d8) /* 0.380602687 */, 17 },
+ /* 3339 */ { MAD_F(0x06179243) /* 0.380754723 */, 17 },
+ /* 3340 */ { MAD_F(0x061831b3) /* 0.380906774 */, 17 },
+ /* 3341 */ { MAD_F(0x0618d127) /* 0.381058840 */, 17 },
+ /* 3342 */ { MAD_F(0x0619709f) /* 0.381210921 */, 17 },
+ /* 3343 */ { MAD_F(0x061a101b) /* 0.381363018 */, 17 },
+
+ /* 3344 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 17 },
+ /* 3345 */ { MAD_F(0x061b4f20) /* 0.381667257 */, 17 },
+ /* 3346 */ { MAD_F(0x061beea8) /* 0.381819399 */, 17 },
+ /* 3347 */ { MAD_F(0x061c8e34) /* 0.381971556 */, 17 },
+ /* 3348 */ { MAD_F(0x061d2dc5) /* 0.382123728 */, 17 },
+ /* 3349 */ { MAD_F(0x061dcd59) /* 0.382275916 */, 17 },
+ /* 3350 */ { MAD_F(0x061e6cf2) /* 0.382428118 */, 17 },
+ /* 3351 */ { MAD_F(0x061f0c8f) /* 0.382580336 */, 17 },
+ /* 3352 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 17 },
+ /* 3353 */ { MAD_F(0x06204bd4) /* 0.382884817 */, 17 },
+ /* 3354 */ { MAD_F(0x0620eb7d) /* 0.383037080 */, 17 },
+ /* 3355 */ { MAD_F(0x06218b2a) /* 0.383189358 */, 17 },
+ /* 3356 */ { MAD_F(0x06222adb) /* 0.383341652 */, 17 },
+ /* 3357 */ { MAD_F(0x0622ca90) /* 0.383493960 */, 17 },
+ /* 3358 */ { MAD_F(0x06236a49) /* 0.383646284 */, 17 },
+ /* 3359 */ { MAD_F(0x06240a06) /* 0.383798623 */, 17 },
+
+ /* 3360 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 17 },
+ /* 3361 */ { MAD_F(0x0625498d) /* 0.384103346 */, 17 },
+ /* 3362 */ { MAD_F(0x0625e956) /* 0.384255730 */, 17 },
+ /* 3363 */ { MAD_F(0x06268923) /* 0.384408129 */, 17 },
+ /* 3364 */ { MAD_F(0x062728f5) /* 0.384560544 */, 17 },
+ /* 3365 */ { MAD_F(0x0627c8ca) /* 0.384712973 */, 17 },
+ /* 3366 */ { MAD_F(0x062868a4) /* 0.384865418 */, 17 },
+ /* 3367 */ { MAD_F(0x06290881) /* 0.385017878 */, 17 },
+ /* 3368 */ { MAD_F(0x0629a863) /* 0.385170352 */, 17 },
+ /* 3369 */ { MAD_F(0x062a4849) /* 0.385322842 */, 17 },
+ /* 3370 */ { MAD_F(0x062ae832) /* 0.385475347 */, 17 },
+ /* 3371 */ { MAD_F(0x062b8820) /* 0.385627867 */, 17 },
+ /* 3372 */ { MAD_F(0x062c2812) /* 0.385780402 */, 17 },
+ /* 3373 */ { MAD_F(0x062cc808) /* 0.385932953 */, 17 },
+ /* 3374 */ { MAD_F(0x062d6802) /* 0.386085518 */, 17 },
+ /* 3375 */ { MAD_F(0x062e0800) /* 0.386238098 */, 17 },
+
+ /* 3376 */ { MAD_F(0x062ea802) /* 0.386390694 */, 17 },
+ /* 3377 */ { MAD_F(0x062f4808) /* 0.386543304 */, 17 },
+ /* 3378 */ { MAD_F(0x062fe812) /* 0.386695930 */, 17 },
+ /* 3379 */ { MAD_F(0x06308820) /* 0.386848570 */, 17 },
+ /* 3380 */ { MAD_F(0x06312832) /* 0.387001226 */, 17 },
+ /* 3381 */ { MAD_F(0x0631c849) /* 0.387153897 */, 17 },
+ /* 3382 */ { MAD_F(0x06326863) /* 0.387306582 */, 17 },
+ /* 3383 */ { MAD_F(0x06330881) /* 0.387459283 */, 17 },
+ /* 3384 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 17 },
+ /* 3385 */ { MAD_F(0x063448ca) /* 0.387764730 */, 17 },
+ /* 3386 */ { MAD_F(0x0634e8f4) /* 0.387917476 */, 17 },
+ /* 3387 */ { MAD_F(0x06358923) /* 0.388070237 */, 17 },
+ /* 3388 */ { MAD_F(0x06362955) /* 0.388223013 */, 17 },
+ /* 3389 */ { MAD_F(0x0636c98c) /* 0.388375804 */, 17 },
+ /* 3390 */ { MAD_F(0x063769c6) /* 0.388528610 */, 17 },
+ /* 3391 */ { MAD_F(0x06380a05) /* 0.388681431 */, 17 },
+
+ /* 3392 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 17 },
+ /* 3393 */ { MAD_F(0x06394a8e) /* 0.388987119 */, 17 },
+ /* 3394 */ { MAD_F(0x0639ead9) /* 0.389139985 */, 17 },
+ /* 3395 */ { MAD_F(0x063a8b28) /* 0.389292866 */, 17 },
+ /* 3396 */ { MAD_F(0x063b2b7b) /* 0.389445762 */, 17 },
+ /* 3397 */ { MAD_F(0x063bcbd1) /* 0.389598674 */, 17 },
+ /* 3398 */ { MAD_F(0x063c6c2c) /* 0.389751600 */, 17 },
+ /* 3399 */ { MAD_F(0x063d0c8b) /* 0.389904541 */, 17 },
+ /* 3400 */ { MAD_F(0x063dacee) /* 0.390057497 */, 17 },
+ /* 3401 */ { MAD_F(0x063e4d55) /* 0.390210468 */, 17 },
+ /* 3402 */ { MAD_F(0x063eedc0) /* 0.390363455 */, 17 },
+ /* 3403 */ { MAD_F(0x063f8e2f) /* 0.390516456 */, 17 },
+ /* 3404 */ { MAD_F(0x06402ea2) /* 0.390669472 */, 17 },
+ /* 3405 */ { MAD_F(0x0640cf19) /* 0.390822503 */, 17 },
+ /* 3406 */ { MAD_F(0x06416f94) /* 0.390975549 */, 17 },
+ /* 3407 */ { MAD_F(0x06421013) /* 0.391128611 */, 17 },
+
+ /* 3408 */ { MAD_F(0x0642b096) /* 0.391281687 */, 17 },
+ /* 3409 */ { MAD_F(0x0643511d) /* 0.391434778 */, 17 },
+ /* 3410 */ { MAD_F(0x0643f1a8) /* 0.391587884 */, 17 },
+ /* 3411 */ { MAD_F(0x06449237) /* 0.391741005 */, 17 },
+ /* 3412 */ { MAD_F(0x064532ca) /* 0.391894141 */, 17 },
+ /* 3413 */ { MAD_F(0x0645d361) /* 0.392047292 */, 17 },
+ /* 3414 */ { MAD_F(0x064673fc) /* 0.392200458 */, 17 },
+ /* 3415 */ { MAD_F(0x0647149c) /* 0.392353638 */, 17 },
+ /* 3416 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 17 },
+ /* 3417 */ { MAD_F(0x064855e6) /* 0.392660045 */, 17 },
+ /* 3418 */ { MAD_F(0x0648f691) /* 0.392813271 */, 17 },
+ /* 3419 */ { MAD_F(0x06499740) /* 0.392966511 */, 17 },
+ /* 3420 */ { MAD_F(0x064a37f4) /* 0.393119767 */, 17 },
+ /* 3421 */ { MAD_F(0x064ad8ab) /* 0.393273038 */, 17 },
+ /* 3422 */ { MAD_F(0x064b7966) /* 0.393426323 */, 17 },
+ /* 3423 */ { MAD_F(0x064c1a25) /* 0.393579623 */, 17 },
+
+ /* 3424 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 17 },
+ /* 3425 */ { MAD_F(0x064d5bb0) /* 0.393886269 */, 17 },
+ /* 3426 */ { MAD_F(0x064dfc7b) /* 0.394039614 */, 17 },
+ /* 3427 */ { MAD_F(0x064e9d4b) /* 0.394192974 */, 17 },
+ /* 3428 */ { MAD_F(0x064f3e1e) /* 0.394346349 */, 17 },
+ /* 3429 */ { MAD_F(0x064fdef5) /* 0.394499739 */, 17 },
+ /* 3430 */ { MAD_F(0x06507fd0) /* 0.394653144 */, 17 },
+ /* 3431 */ { MAD_F(0x065120b0) /* 0.394806564 */, 17 },
+ /* 3432 */ { MAD_F(0x0651c193) /* 0.394959999 */, 17 },
+ /* 3433 */ { MAD_F(0x0652627a) /* 0.395113448 */, 17 },
+ /* 3434 */ { MAD_F(0x06530366) /* 0.395266913 */, 17 },
+ /* 3435 */ { MAD_F(0x0653a455) /* 0.395420392 */, 17 },
+ /* 3436 */ { MAD_F(0x06544548) /* 0.395573886 */, 17 },
+ /* 3437 */ { MAD_F(0x0654e640) /* 0.395727395 */, 17 },
+ /* 3438 */ { MAD_F(0x0655873b) /* 0.395880919 */, 17 },
+ /* 3439 */ { MAD_F(0x0656283a) /* 0.396034458 */, 17 },
+
+ /* 3440 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 17 },
+ /* 3441 */ { MAD_F(0x06576a45) /* 0.396341581 */, 17 },
+ /* 3442 */ { MAD_F(0x06580b50) /* 0.396495164 */, 17 },
+ /* 3443 */ { MAD_F(0x0658ac5f) /* 0.396648763 */, 17 },
+ /* 3444 */ { MAD_F(0x06594d73) /* 0.396802376 */, 17 },
+ /* 3445 */ { MAD_F(0x0659ee8a) /* 0.396956004 */, 17 },
+ /* 3446 */ { MAD_F(0x065a8fa5) /* 0.397109647 */, 17 },
+ /* 3447 */ { MAD_F(0x065b30c4) /* 0.397263305 */, 17 },
+ /* 3448 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 17 },
+ /* 3449 */ { MAD_F(0x065c730f) /* 0.397570666 */, 17 },
+ /* 3450 */ { MAD_F(0x065d143a) /* 0.397724368 */, 17 },
+ /* 3451 */ { MAD_F(0x065db569) /* 0.397878085 */, 17 },
+ /* 3452 */ { MAD_F(0x065e569c) /* 0.398031818 */, 17 },
+ /* 3453 */ { MAD_F(0x065ef7d3) /* 0.398185565 */, 17 },
+ /* 3454 */ { MAD_F(0x065f990e) /* 0.398339326 */, 17 },
+ /* 3455 */ { MAD_F(0x06603a4e) /* 0.398493103 */, 17 },
+
+ /* 3456 */ { MAD_F(0x0660db91) /* 0.398646895 */, 17 },
+ /* 3457 */ { MAD_F(0x06617cd8) /* 0.398800701 */, 17 },
+ /* 3458 */ { MAD_F(0x06621e23) /* 0.398954522 */, 17 },
+ /* 3459 */ { MAD_F(0x0662bf72) /* 0.399108358 */, 17 },
+ /* 3460 */ { MAD_F(0x066360c5) /* 0.399262209 */, 17 },
+ /* 3461 */ { MAD_F(0x0664021c) /* 0.399416075 */, 17 },
+ /* 3462 */ { MAD_F(0x0664a377) /* 0.399569955 */, 17 },
+ /* 3463 */ { MAD_F(0x066544d6) /* 0.399723851 */, 17 },
+ /* 3464 */ { MAD_F(0x0665e639) /* 0.399877761 */, 17 },
+ /* 3465 */ { MAD_F(0x066687a0) /* 0.400031686 */, 17 },
+ /* 3466 */ { MAD_F(0x0667290b) /* 0.400185625 */, 17 },
+ /* 3467 */ { MAD_F(0x0667ca79) /* 0.400339580 */, 17 },
+ /* 3468 */ { MAD_F(0x06686bec) /* 0.400493549 */, 17 },
+ /* 3469 */ { MAD_F(0x06690d63) /* 0.400647534 */, 17 },
+ /* 3470 */ { MAD_F(0x0669aede) /* 0.400801533 */, 17 },
+ /* 3471 */ { MAD_F(0x066a505d) /* 0.400955546 */, 17 },
+
+ /* 3472 */ { MAD_F(0x066af1df) /* 0.401109575 */, 17 },
+ /* 3473 */ { MAD_F(0x066b9366) /* 0.401263618 */, 17 },
+ /* 3474 */ { MAD_F(0x066c34f1) /* 0.401417676 */, 17 },
+ /* 3475 */ { MAD_F(0x066cd67f) /* 0.401571749 */, 17 },
+ /* 3476 */ { MAD_F(0x066d7812) /* 0.401725837 */, 17 },
+ /* 3477 */ { MAD_F(0x066e19a9) /* 0.401879939 */, 17 },
+ /* 3478 */ { MAD_F(0x066ebb43) /* 0.402034056 */, 17 },
+ /* 3479 */ { MAD_F(0x066f5ce2) /* 0.402188188 */, 17 },
+ /* 3480 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 17 },
+ /* 3481 */ { MAD_F(0x0670a02a) /* 0.402496497 */, 17 },
+ /* 3482 */ { MAD_F(0x067141d5) /* 0.402650673 */, 17 },
+ /* 3483 */ { MAD_F(0x0671e383) /* 0.402804864 */, 17 },
+ /* 3484 */ { MAD_F(0x06728535) /* 0.402959070 */, 17 },
+ /* 3485 */ { MAD_F(0x067326ec) /* 0.403113291 */, 17 },
+ /* 3486 */ { MAD_F(0x0673c8a6) /* 0.403267526 */, 17 },
+ /* 3487 */ { MAD_F(0x06746a64) /* 0.403421776 */, 17 },
+
+ /* 3488 */ { MAD_F(0x06750c26) /* 0.403576041 */, 17 },
+ /* 3489 */ { MAD_F(0x0675adec) /* 0.403730320 */, 17 },
+ /* 3490 */ { MAD_F(0x06764fb6) /* 0.403884615 */, 17 },
+ /* 3491 */ { MAD_F(0x0676f184) /* 0.404038924 */, 17 },
+ /* 3492 */ { MAD_F(0x06779356) /* 0.404193247 */, 17 },
+ /* 3493 */ { MAD_F(0x0678352c) /* 0.404347586 */, 17 },
+ /* 3494 */ { MAD_F(0x0678d706) /* 0.404501939 */, 17 },
+ /* 3495 */ { MAD_F(0x067978e4) /* 0.404656307 */, 17 },
+ /* 3496 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 17 },
+ /* 3497 */ { MAD_F(0x067abcac) /* 0.404965087 */, 17 },
+ /* 3498 */ { MAD_F(0x067b5e95) /* 0.405119499 */, 17 },
+ /* 3499 */ { MAD_F(0x067c0083) /* 0.405273926 */, 17 },
+ /* 3500 */ { MAD_F(0x067ca275) /* 0.405428368 */, 17 },
+ /* 3501 */ { MAD_F(0x067d446a) /* 0.405582824 */, 17 },
+ /* 3502 */ { MAD_F(0x067de664) /* 0.405737295 */, 17 },
+ /* 3503 */ { MAD_F(0x067e8861) /* 0.405891781 */, 17 },
+
+ /* 3504 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 17 },
+ /* 3505 */ { MAD_F(0x067fcc68) /* 0.406200796 */, 17 },
+ /* 3506 */ { MAD_F(0x06806e71) /* 0.406355326 */, 17 },
+ /* 3507 */ { MAD_F(0x0681107e) /* 0.406509870 */, 17 },
+ /* 3508 */ { MAD_F(0x0681b28f) /* 0.406664429 */, 17 },
+ /* 3509 */ { MAD_F(0x068254a4) /* 0.406819003 */, 17 },
+ /* 3510 */ { MAD_F(0x0682f6bd) /* 0.406973592 */, 17 },
+ /* 3511 */ { MAD_F(0x068398da) /* 0.407128195 */, 17 },
+ /* 3512 */ { MAD_F(0x06843afb) /* 0.407282813 */, 17 },
+ /* 3513 */ { MAD_F(0x0684dd20) /* 0.407437445 */, 17 },
+ /* 3514 */ { MAD_F(0x06857f49) /* 0.407592093 */, 17 },
+ /* 3515 */ { MAD_F(0x06862176) /* 0.407746754 */, 17 },
+ /* 3516 */ { MAD_F(0x0686c3a6) /* 0.407901431 */, 17 },
+ /* 3517 */ { MAD_F(0x068765db) /* 0.408056122 */, 17 },
+ /* 3518 */ { MAD_F(0x06880814) /* 0.408210828 */, 17 },
+ /* 3519 */ { MAD_F(0x0688aa50) /* 0.408365549 */, 17 },
+
+ /* 3520 */ { MAD_F(0x06894c90) /* 0.408520284 */, 17 },
+ /* 3521 */ { MAD_F(0x0689eed5) /* 0.408675034 */, 17 },
+ /* 3522 */ { MAD_F(0x068a911d) /* 0.408829798 */, 17 },
+ /* 3523 */ { MAD_F(0x068b3369) /* 0.408984577 */, 17 },
+ /* 3524 */ { MAD_F(0x068bd5b9) /* 0.409139371 */, 17 },
+ /* 3525 */ { MAD_F(0x068c780e) /* 0.409294180 */, 17 },
+ /* 3526 */ { MAD_F(0x068d1a66) /* 0.409449003 */, 17 },
+ /* 3527 */ { MAD_F(0x068dbcc1) /* 0.409603840 */, 17 },
+ /* 3528 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 17 },
+ /* 3529 */ { MAD_F(0x068f0185) /* 0.409913560 */, 17 },
+ /* 3530 */ { MAD_F(0x068fa3ed) /* 0.410068441 */, 17 },
+ /* 3531 */ { MAD_F(0x06904658) /* 0.410223338 */, 17 },
+ /* 3532 */ { MAD_F(0x0690e8c8) /* 0.410378249 */, 17 },
+ /* 3533 */ { MAD_F(0x06918b3c) /* 0.410533174 */, 17 },
+ /* 3534 */ { MAD_F(0x06922db3) /* 0.410688114 */, 17 },
+ /* 3535 */ { MAD_F(0x0692d02e) /* 0.410843069 */, 17 },
+
+ /* 3536 */ { MAD_F(0x069372ae) /* 0.410998038 */, 17 },
+ /* 3537 */ { MAD_F(0x06941531) /* 0.411153022 */, 17 },
+ /* 3538 */ { MAD_F(0x0694b7b8) /* 0.411308021 */, 17 },
+ /* 3539 */ { MAD_F(0x06955a43) /* 0.411463034 */, 17 },
+ /* 3540 */ { MAD_F(0x0695fcd2) /* 0.411618062 */, 17 },
+ /* 3541 */ { MAD_F(0x06969f65) /* 0.411773104 */, 17 },
+ /* 3542 */ { MAD_F(0x069741fb) /* 0.411928161 */, 17 },
+ /* 3543 */ { MAD_F(0x0697e496) /* 0.412083232 */, 17 },
+ /* 3544 */ { MAD_F(0x06988735) /* 0.412238319 */, 17 },
+ /* 3545 */ { MAD_F(0x069929d7) /* 0.412393419 */, 17 },
+ /* 3546 */ { MAD_F(0x0699cc7e) /* 0.412548535 */, 17 },
+ /* 3547 */ { MAD_F(0x069a6f28) /* 0.412703664 */, 17 },
+ /* 3548 */ { MAD_F(0x069b11d6) /* 0.412858809 */, 17 },
+ /* 3549 */ { MAD_F(0x069bb489) /* 0.413013968 */, 17 },
+ /* 3550 */ { MAD_F(0x069c573f) /* 0.413169142 */, 17 },
+ /* 3551 */ { MAD_F(0x069cf9f9) /* 0.413324330 */, 17 },
+
+ /* 3552 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 17 },
+ /* 3553 */ { MAD_F(0x069e3f78) /* 0.413634750 */, 17 },
+ /* 3554 */ { MAD_F(0x069ee23e) /* 0.413789982 */, 17 },
+ /* 3555 */ { MAD_F(0x069f8508) /* 0.413945228 */, 17 },
+ /* 3556 */ { MAD_F(0x06a027d5) /* 0.414100489 */, 17 },
+ /* 3557 */ { MAD_F(0x06a0caa7) /* 0.414255765 */, 17 },
+ /* 3558 */ { MAD_F(0x06a16d7c) /* 0.414411055 */, 17 },
+ /* 3559 */ { MAD_F(0x06a21055) /* 0.414566359 */, 17 },
+ /* 3560 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 17 },
+ /* 3561 */ { MAD_F(0x06a35614) /* 0.414877012 */, 17 },
+ /* 3562 */ { MAD_F(0x06a3f8f9) /* 0.415032361 */, 17 },
+ /* 3563 */ { MAD_F(0x06a49be2) /* 0.415187723 */, 17 },
+ /* 3564 */ { MAD_F(0x06a53ece) /* 0.415343101 */, 17 },
+ /* 3565 */ { MAD_F(0x06a5e1bf) /* 0.415498493 */, 17 },
+ /* 3566 */ { MAD_F(0x06a684b4) /* 0.415653899 */, 17 },
+ /* 3567 */ { MAD_F(0x06a727ac) /* 0.415809320 */, 17 },
+
+ /* 3568 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 17 },
+ /* 3569 */ { MAD_F(0x06a86da9) /* 0.416120206 */, 17 },
+ /* 3570 */ { MAD_F(0x06a910ad) /* 0.416275670 */, 17 },
+ /* 3571 */ { MAD_F(0x06a9b3b5) /* 0.416431149 */, 17 },
+ /* 3572 */ { MAD_F(0x06aa56c1) /* 0.416586643 */, 17 },
+ /* 3573 */ { MAD_F(0x06aaf9d1) /* 0.416742151 */, 17 },
+ /* 3574 */ { MAD_F(0x06ab9ce5) /* 0.416897673 */, 17 },
+ /* 3575 */ { MAD_F(0x06ac3ffc) /* 0.417053210 */, 17 },
+ /* 3576 */ { MAD_F(0x06ace318) /* 0.417208762 */, 17 },
+ /* 3577 */ { MAD_F(0x06ad8637) /* 0.417364328 */, 17 },
+ /* 3578 */ { MAD_F(0x06ae295b) /* 0.417519909 */, 17 },
+ /* 3579 */ { MAD_F(0x06aecc82) /* 0.417675504 */, 17 },
+ /* 3580 */ { MAD_F(0x06af6fad) /* 0.417831113 */, 17 },
+ /* 3581 */ { MAD_F(0x06b012dc) /* 0.417986737 */, 17 },
+ /* 3582 */ { MAD_F(0x06b0b60f) /* 0.418142376 */, 17 },
+ /* 3583 */ { MAD_F(0x06b15946) /* 0.418298029 */, 17 },
+
+ /* 3584 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 17 },
+ /* 3585 */ { MAD_F(0x06b29fbf) /* 0.418609378 */, 17 },
+ /* 3586 */ { MAD_F(0x06b34302) /* 0.418765075 */, 17 },
+ /* 3587 */ { MAD_F(0x06b3e648) /* 0.418920786 */, 17 },
+ /* 3588 */ { MAD_F(0x06b48992) /* 0.419076511 */, 17 },
+ /* 3589 */ { MAD_F(0x06b52ce0) /* 0.419232251 */, 17 },
+ /* 3590 */ { MAD_F(0x06b5d032) /* 0.419388005 */, 17 },
+ /* 3591 */ { MAD_F(0x06b67388) /* 0.419543774 */, 17 },
+ /* 3592 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 17 },
+ /* 3593 */ { MAD_F(0x06b7ba3f) /* 0.419855355 */, 17 },
+ /* 3594 */ { MAD_F(0x06b85da1) /* 0.420011167 */, 17 },
+ /* 3595 */ { MAD_F(0x06b90106) /* 0.420166994 */, 17 },
+ /* 3596 */ { MAD_F(0x06b9a470) /* 0.420322835 */, 17 },
+ /* 3597 */ { MAD_F(0x06ba47dd) /* 0.420478690 */, 17 },
+ /* 3598 */ { MAD_F(0x06baeb4e) /* 0.420634560 */, 17 },
+ /* 3599 */ { MAD_F(0x06bb8ec3) /* 0.420790445 */, 17 },
+
+ /* 3600 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 17 },
+ /* 3601 */ { MAD_F(0x06bcd5b8) /* 0.421102257 */, 17 },
+ /* 3602 */ { MAD_F(0x06bd7939) /* 0.421258184 */, 17 },
+ /* 3603 */ { MAD_F(0x06be1cbd) /* 0.421414127 */, 17 },
+ /* 3604 */ { MAD_F(0x06bec045) /* 0.421570083 */, 17 },
+ /* 3605 */ { MAD_F(0x06bf63d1) /* 0.421726054 */, 17 },
+ /* 3606 */ { MAD_F(0x06c00761) /* 0.421882040 */, 17 },
+ /* 3607 */ { MAD_F(0x06c0aaf5) /* 0.422038039 */, 17 },
+ /* 3608 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 17 },
+ /* 3609 */ { MAD_F(0x06c1f229) /* 0.422350082 */, 17 },
+ /* 3610 */ { MAD_F(0x06c295c8) /* 0.422506125 */, 17 },
+ /* 3611 */ { MAD_F(0x06c3396c) /* 0.422662183 */, 17 },
+ /* 3612 */ { MAD_F(0x06c3dd13) /* 0.422818255 */, 17 },
+ /* 3613 */ { MAD_F(0x06c480be) /* 0.422974341 */, 17 },
+ /* 3614 */ { MAD_F(0x06c5246d) /* 0.423130442 */, 17 },
+ /* 3615 */ { MAD_F(0x06c5c820) /* 0.423286557 */, 17 },
+
+ /* 3616 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 17 },
+ /* 3617 */ { MAD_F(0x06c70f91) /* 0.423598830 */, 17 },
+ /* 3618 */ { MAD_F(0x06c7b34f) /* 0.423754988 */, 17 },
+ /* 3619 */ { MAD_F(0x06c85712) /* 0.423911161 */, 17 },
+ /* 3620 */ { MAD_F(0x06c8fad8) /* 0.424067348 */, 17 },
+ /* 3621 */ { MAD_F(0x06c99ea2) /* 0.424223550 */, 17 },
+ /* 3622 */ { MAD_F(0x06ca4270) /* 0.424379765 */, 17 },
+ /* 3623 */ { MAD_F(0x06cae641) /* 0.424535996 */, 17 },
+ /* 3624 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 17 },
+ /* 3625 */ { MAD_F(0x06cc2df0) /* 0.424848499 */, 17 },
+ /* 3626 */ { MAD_F(0x06ccd1ce) /* 0.425004772 */, 17 },
+ /* 3627 */ { MAD_F(0x06cd75af) /* 0.425161060 */, 17 },
+ /* 3628 */ { MAD_F(0x06ce1994) /* 0.425317362 */, 17 },
+ /* 3629 */ { MAD_F(0x06cebd7d) /* 0.425473678 */, 17 },
+ /* 3630 */ { MAD_F(0x06cf6169) /* 0.425630009 */, 17 },
+ /* 3631 */ { MAD_F(0x06d0055a) /* 0.425786354 */, 17 },
+
+ /* 3632 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 17 },
+ /* 3633 */ { MAD_F(0x06d14d47) /* 0.426099088 */, 17 },
+ /* 3634 */ { MAD_F(0x06d1f143) /* 0.426255476 */, 17 },
+ /* 3635 */ { MAD_F(0x06d29543) /* 0.426411878 */, 17 },
+ /* 3636 */ { MAD_F(0x06d33947) /* 0.426568295 */, 17 },
+ /* 3637 */ { MAD_F(0x06d3dd4e) /* 0.426724726 */, 17 },
+ /* 3638 */ { MAD_F(0x06d4815a) /* 0.426881172 */, 17 },
+ /* 3639 */ { MAD_F(0x06d52569) /* 0.427037632 */, 17 },
+ /* 3640 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 17 },
+ /* 3641 */ { MAD_F(0x06d66d93) /* 0.427350594 */, 17 },
+ /* 3642 */ { MAD_F(0x06d711ae) /* 0.427507097 */, 17 },
+ /* 3643 */ { MAD_F(0x06d7b5cd) /* 0.427663614 */, 17 },
+ /* 3644 */ { MAD_F(0x06d859f0) /* 0.427820146 */, 17 },
+ /* 3645 */ { MAD_F(0x06d8fe16) /* 0.427976692 */, 17 },
+ /* 3646 */ { MAD_F(0x06d9a240) /* 0.428133252 */, 17 },
+ /* 3647 */ { MAD_F(0x06da466f) /* 0.428289826 */, 17 },
+
+ /* 3648 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 17 },
+ /* 3649 */ { MAD_F(0x06db8ed6) /* 0.428603018 */, 17 },
+ /* 3650 */ { MAD_F(0x06dc3310) /* 0.428759635 */, 17 },
+ /* 3651 */ { MAD_F(0x06dcd74d) /* 0.428916267 */, 17 },
+ /* 3652 */ { MAD_F(0x06dd7b8f) /* 0.429072913 */, 17 },
+ /* 3653 */ { MAD_F(0x06de1fd4) /* 0.429229573 */, 17 },
+ /* 3654 */ { MAD_F(0x06dec41d) /* 0.429386248 */, 17 },
+ /* 3655 */ { MAD_F(0x06df686a) /* 0.429542937 */, 17 },
+ /* 3656 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 17 },
+ /* 3657 */ { MAD_F(0x06e0b10f) /* 0.429856357 */, 17 },
+ /* 3658 */ { MAD_F(0x06e15567) /* 0.430013089 */, 17 },
+ /* 3659 */ { MAD_F(0x06e1f9c4) /* 0.430169835 */, 17 },
+ /* 3660 */ { MAD_F(0x06e29e24) /* 0.430326595 */, 17 },
+ /* 3661 */ { MAD_F(0x06e34287) /* 0.430483370 */, 17 },
+ /* 3662 */ { MAD_F(0x06e3e6ef) /* 0.430640159 */, 17 },
+ /* 3663 */ { MAD_F(0x06e48b5b) /* 0.430796962 */, 17 },
+
+ /* 3664 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 17 },
+ /* 3665 */ { MAD_F(0x06e5d43d) /* 0.431110611 */, 17 },
+ /* 3666 */ { MAD_F(0x06e678b4) /* 0.431267457 */, 17 },
+ /* 3667 */ { MAD_F(0x06e71d2f) /* 0.431424317 */, 17 },
+ /* 3668 */ { MAD_F(0x06e7c1ae) /* 0.431581192 */, 17 },
+ /* 3669 */ { MAD_F(0x06e86630) /* 0.431738080 */, 17 },
+ /* 3670 */ { MAD_F(0x06e90ab7) /* 0.431894983 */, 17 },
+ /* 3671 */ { MAD_F(0x06e9af41) /* 0.432051900 */, 17 },
+ /* 3672 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 17 },
+ /* 3673 */ { MAD_F(0x06eaf860) /* 0.432365778 */, 17 },
+ /* 3674 */ { MAD_F(0x06eb9cf6) /* 0.432522737 */, 17 },
+ /* 3675 */ { MAD_F(0x06ec418f) /* 0.432679712 */, 17 },
+ /* 3676 */ { MAD_F(0x06ece62d) /* 0.432836700 */, 17 },
+ /* 3677 */ { MAD_F(0x06ed8ace) /* 0.432993703 */, 17 },
+ /* 3678 */ { MAD_F(0x06ee2f73) /* 0.433150720 */, 17 },
+ /* 3679 */ { MAD_F(0x06eed41b) /* 0.433307751 */, 17 },
+
+ /* 3680 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 17 },
+ /* 3681 */ { MAD_F(0x06f01d78) /* 0.433621856 */, 17 },
+ /* 3682 */ { MAD_F(0x06f0c22c) /* 0.433778929 */, 17 },
+ /* 3683 */ { MAD_F(0x06f166e4) /* 0.433936017 */, 17 },
+ /* 3684 */ { MAD_F(0x06f20ba0) /* 0.434093120 */, 17 },
+ /* 3685 */ { MAD_F(0x06f2b060) /* 0.434250236 */, 17 },
+ /* 3686 */ { MAD_F(0x06f35523) /* 0.434407367 */, 17 },
+ /* 3687 */ { MAD_F(0x06f3f9eb) /* 0.434564512 */, 17 },
+ /* 3688 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 17 },
+ /* 3689 */ { MAD_F(0x06f54385) /* 0.434878844 */, 17 },
+ /* 3690 */ { MAD_F(0x06f5e857) /* 0.435036032 */, 17 },
+ /* 3691 */ { MAD_F(0x06f68d2e) /* 0.435193233 */, 17 },
+ /* 3692 */ { MAD_F(0x06f73208) /* 0.435350449 */, 17 },
+ /* 3693 */ { MAD_F(0x06f7d6e6) /* 0.435507679 */, 17 },
+ /* 3694 */ { MAD_F(0x06f87bc8) /* 0.435664924 */, 17 },
+ /* 3695 */ { MAD_F(0x06f920ae) /* 0.435822182 */, 17 },
+
+ /* 3696 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 17 },
+ /* 3697 */ { MAD_F(0x06fa6a85) /* 0.436136741 */, 17 },
+ /* 3698 */ { MAD_F(0x06fb0f76) /* 0.436294042 */, 17 },
+ /* 3699 */ { MAD_F(0x06fbb46b) /* 0.436451358 */, 17 },
+ /* 3700 */ { MAD_F(0x06fc5964) /* 0.436608687 */, 17 },
+ /* 3701 */ { MAD_F(0x06fcfe60) /* 0.436766031 */, 17 },
+ /* 3702 */ { MAD_F(0x06fda361) /* 0.436923388 */, 17 },
+ /* 3703 */ { MAD_F(0x06fe4865) /* 0.437080760 */, 17 },
+ /* 3704 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 17 },
+ /* 3705 */ { MAD_F(0x06ff9279) /* 0.437395547 */, 17 },
+ /* 3706 */ { MAD_F(0x07003788) /* 0.437552961 */, 17 },
+ /* 3707 */ { MAD_F(0x0700dc9c) /* 0.437710389 */, 17 },
+ /* 3708 */ { MAD_F(0x070181b3) /* 0.437867832 */, 17 },
+ /* 3709 */ { MAD_F(0x070226ce) /* 0.438025289 */, 17 },
+ /* 3710 */ { MAD_F(0x0702cbed) /* 0.438182760 */, 17 },
+ /* 3711 */ { MAD_F(0x0703710f) /* 0.438340245 */, 17 },
+
+ /* 3712 */ { MAD_F(0x07041636) /* 0.438497744 */, 17 },
+ /* 3713 */ { MAD_F(0x0704bb60) /* 0.438655258 */, 17 },
+ /* 3714 */ { MAD_F(0x0705608e) /* 0.438812785 */, 17 },
+ /* 3715 */ { MAD_F(0x070605c0) /* 0.438970327 */, 17 },
+ /* 3716 */ { MAD_F(0x0706aaf5) /* 0.439127883 */, 17 },
+ /* 3717 */ { MAD_F(0x0707502f) /* 0.439285453 */, 17 },
+ /* 3718 */ { MAD_F(0x0707f56c) /* 0.439443037 */, 17 },
+ /* 3719 */ { MAD_F(0x07089aad) /* 0.439600635 */, 17 },
+ /* 3720 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 17 },
+ /* 3721 */ { MAD_F(0x0709e53a) /* 0.439915874 */, 17 },
+ /* 3722 */ { MAD_F(0x070a8a86) /* 0.440073515 */, 17 },
+ /* 3723 */ { MAD_F(0x070b2fd7) /* 0.440231170 */, 17 },
+ /* 3724 */ { MAD_F(0x070bd52a) /* 0.440388839 */, 17 },
+ /* 3725 */ { MAD_F(0x070c7a82) /* 0.440546522 */, 17 },
+ /* 3726 */ { MAD_F(0x070d1fde) /* 0.440704219 */, 17 },
+ /* 3727 */ { MAD_F(0x070dc53d) /* 0.440861930 */, 17 },
+
+ /* 3728 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 17 },
+ /* 3729 */ { MAD_F(0x070f1007) /* 0.441177395 */, 17 },
+ /* 3730 */ { MAD_F(0x070fb571) /* 0.441335148 */, 17 },
+ /* 3731 */ { MAD_F(0x07105ae0) /* 0.441492916 */, 17 },
+ /* 3732 */ { MAD_F(0x07110052) /* 0.441650697 */, 17 },
+ /* 3733 */ { MAD_F(0x0711a5c8) /* 0.441808493 */, 17 },
+ /* 3734 */ { MAD_F(0x07124b42) /* 0.441966303 */, 17 },
+ /* 3735 */ { MAD_F(0x0712f0bf) /* 0.442124127 */, 17 },
+ /* 3736 */ { MAD_F(0x07139641) /* 0.442281965 */, 17 },
+ /* 3737 */ { MAD_F(0x07143bc6) /* 0.442439817 */, 17 },
+ /* 3738 */ { MAD_F(0x0714e14f) /* 0.442597683 */, 17 },
+ /* 3739 */ { MAD_F(0x071586db) /* 0.442755564 */, 17 },
+ /* 3740 */ { MAD_F(0x07162c6c) /* 0.442913458 */, 17 },
+ /* 3741 */ { MAD_F(0x0716d200) /* 0.443071366 */, 17 },
+ /* 3742 */ { MAD_F(0x07177798) /* 0.443229289 */, 17 },
+ /* 3743 */ { MAD_F(0x07181d34) /* 0.443387226 */, 17 },
+
+ /* 3744 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 17 },
+ /* 3745 */ { MAD_F(0x07196877) /* 0.443703141 */, 17 },
+ /* 3746 */ { MAD_F(0x071a0e1e) /* 0.443861120 */, 17 },
+ /* 3747 */ { MAD_F(0x071ab3c9) /* 0.444019113 */, 17 },
+ /* 3748 */ { MAD_F(0x071b5977) /* 0.444177119 */, 17 },
+ /* 3749 */ { MAD_F(0x071bff2a) /* 0.444335140 */, 17 },
+ /* 3750 */ { MAD_F(0x071ca4e0) /* 0.444493175 */, 17 },
+ /* 3751 */ { MAD_F(0x071d4a9a) /* 0.444651224 */, 17 },
+ /* 3752 */ { MAD_F(0x071df058) /* 0.444809288 */, 17 },
+ /* 3753 */ { MAD_F(0x071e9619) /* 0.444967365 */, 17 },
+ /* 3754 */ { MAD_F(0x071f3bde) /* 0.445125456 */, 17 },
+ /* 3755 */ { MAD_F(0x071fe1a8) /* 0.445283561 */, 17 },
+ /* 3756 */ { MAD_F(0x07208774) /* 0.445441680 */, 17 },
+ /* 3757 */ { MAD_F(0x07212d45) /* 0.445599814 */, 17 },
+ /* 3758 */ { MAD_F(0x0721d319) /* 0.445757961 */, 17 },
+ /* 3759 */ { MAD_F(0x072278f1) /* 0.445916122 */, 17 },
+
+ /* 3760 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 17 },
+ /* 3761 */ { MAD_F(0x0723c4ad) /* 0.446232487 */, 17 },
+ /* 3762 */ { MAD_F(0x07246a90) /* 0.446390690 */, 17 },
+ /* 3763 */ { MAD_F(0x07251077) /* 0.446548908 */, 17 },
+ /* 3764 */ { MAD_F(0x0725b662) /* 0.446707139 */, 17 },
+ /* 3765 */ { MAD_F(0x07265c51) /* 0.446865385 */, 17 },
+ /* 3766 */ { MAD_F(0x07270244) /* 0.447023644 */, 17 },
+ /* 3767 */ { MAD_F(0x0727a83a) /* 0.447181918 */, 17 },
+ /* 3768 */ { MAD_F(0x07284e34) /* 0.447340205 */, 17 },
+ /* 3769 */ { MAD_F(0x0728f431) /* 0.447498507 */, 17 },
+ /* 3770 */ { MAD_F(0x07299a33) /* 0.447656822 */, 17 },
+ /* 3771 */ { MAD_F(0x072a4038) /* 0.447815152 */, 17 },
+ /* 3772 */ { MAD_F(0x072ae641) /* 0.447973495 */, 17 },
+ /* 3773 */ { MAD_F(0x072b8c4e) /* 0.448131853 */, 17 },
+ /* 3774 */ { MAD_F(0x072c325e) /* 0.448290224 */, 17 },
+ /* 3775 */ { MAD_F(0x072cd873) /* 0.448448609 */, 17 },
+
+ /* 3776 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 17 },
+ /* 3777 */ { MAD_F(0x072e24a7) /* 0.448765422 */, 17 },
+ /* 3778 */ { MAD_F(0x072ecac6) /* 0.448923850 */, 17 },
+ /* 3779 */ { MAD_F(0x072f70e9) /* 0.449082291 */, 17 },
+ /* 3780 */ { MAD_F(0x07301710) /* 0.449240746 */, 17 },
+ /* 3781 */ { MAD_F(0x0730bd3b) /* 0.449399216 */, 17 },
+ /* 3782 */ { MAD_F(0x0731636a) /* 0.449557699 */, 17 },
+ /* 3783 */ { MAD_F(0x0732099c) /* 0.449716196 */, 17 },
+ /* 3784 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 17 },
+ /* 3785 */ { MAD_F(0x0733560c) /* 0.450033233 */, 17 },
+ /* 3786 */ { MAD_F(0x0733fc49) /* 0.450191772 */, 17 },
+ /* 3787 */ { MAD_F(0x0734a28b) /* 0.450350325 */, 17 },
+ /* 3788 */ { MAD_F(0x073548d0) /* 0.450508892 */, 17 },
+ /* 3789 */ { MAD_F(0x0735ef18) /* 0.450667473 */, 17 },
+ /* 3790 */ { MAD_F(0x07369565) /* 0.450826068 */, 17 },
+ /* 3791 */ { MAD_F(0x07373bb5) /* 0.450984677 */, 17 },
+
+ /* 3792 */ { MAD_F(0x0737e209) /* 0.451143300 */, 17 },
+ /* 3793 */ { MAD_F(0x07388861) /* 0.451301937 */, 17 },
+ /* 3794 */ { MAD_F(0x07392ebc) /* 0.451460588 */, 17 },
+ /* 3795 */ { MAD_F(0x0739d51c) /* 0.451619252 */, 17 },
+ /* 3796 */ { MAD_F(0x073a7b7f) /* 0.451777931 */, 17 },
+ /* 3797 */ { MAD_F(0x073b21e5) /* 0.451936623 */, 17 },
+ /* 3798 */ { MAD_F(0x073bc850) /* 0.452095330 */, 17 },
+ /* 3799 */ { MAD_F(0x073c6ebe) /* 0.452254050 */, 17 },
+ /* 3800 */ { MAD_F(0x073d1530) /* 0.452412785 */, 17 },
+ /* 3801 */ { MAD_F(0x073dbba6) /* 0.452571533 */, 17 },
+ /* 3802 */ { MAD_F(0x073e621f) /* 0.452730295 */, 17 },
+ /* 3803 */ { MAD_F(0x073f089c) /* 0.452889071 */, 17 },
+ /* 3804 */ { MAD_F(0x073faf1d) /* 0.453047861 */, 17 },
+ /* 3805 */ { MAD_F(0x074055a2) /* 0.453206665 */, 17 },
+ /* 3806 */ { MAD_F(0x0740fc2a) /* 0.453365483 */, 17 },
+ /* 3807 */ { MAD_F(0x0741a2b6) /* 0.453524315 */, 17 },
+
+ /* 3808 */ { MAD_F(0x07424946) /* 0.453683161 */, 17 },
+ /* 3809 */ { MAD_F(0x0742efd9) /* 0.453842020 */, 17 },
+ /* 3810 */ { MAD_F(0x07439671) /* 0.454000894 */, 17 },
+ /* 3811 */ { MAD_F(0x07443d0c) /* 0.454159781 */, 17 },
+ /* 3812 */ { MAD_F(0x0744e3aa) /* 0.454318683 */, 17 },
+ /* 3813 */ { MAD_F(0x07458a4d) /* 0.454477598 */, 17 },
+ /* 3814 */ { MAD_F(0x074630f3) /* 0.454636527 */, 17 },
+ /* 3815 */ { MAD_F(0x0746d79d) /* 0.454795470 */, 17 },
+ /* 3816 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 17 },
+ /* 3817 */ { MAD_F(0x074824fc) /* 0.455113397 */, 17 },
+ /* 3818 */ { MAD_F(0x0748cbb1) /* 0.455272382 */, 17 },
+ /* 3819 */ { MAD_F(0x0749726a) /* 0.455431381 */, 17 },
+ /* 3820 */ { MAD_F(0x074a1927) /* 0.455590393 */, 17 },
+ /* 3821 */ { MAD_F(0x074abfe7) /* 0.455749419 */, 17 },
+ /* 3822 */ { MAD_F(0x074b66ab) /* 0.455908459 */, 17 },
+ /* 3823 */ { MAD_F(0x074c0d73) /* 0.456067513 */, 17 },
+
+ /* 3824 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 17 },
+ /* 3825 */ { MAD_F(0x074d5b0d) /* 0.456385663 */, 17 },
+ /* 3826 */ { MAD_F(0x074e01e0) /* 0.456544759 */, 17 },
+ /* 3827 */ { MAD_F(0x074ea8b7) /* 0.456703868 */, 17 },
+ /* 3828 */ { MAD_F(0x074f4f91) /* 0.456862992 */, 17 },
+ /* 3829 */ { MAD_F(0x074ff66f) /* 0.457022129 */, 17 },
+ /* 3830 */ { MAD_F(0x07509d51) /* 0.457181280 */, 17 },
+ /* 3831 */ { MAD_F(0x07514437) /* 0.457340445 */, 17 },
+ /* 3832 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 17 },
+ /* 3833 */ { MAD_F(0x0752920d) /* 0.457658816 */, 17 },
+ /* 3834 */ { MAD_F(0x075338fd) /* 0.457818022 */, 17 },
+ /* 3835 */ { MAD_F(0x0753dff2) /* 0.457977243 */, 17 },
+ /* 3836 */ { MAD_F(0x075486ea) /* 0.458136477 */, 17 },
+ /* 3837 */ { MAD_F(0x07552de6) /* 0.458295725 */, 17 },
+ /* 3838 */ { MAD_F(0x0755d4e5) /* 0.458454987 */, 17 },
+ /* 3839 */ { MAD_F(0x07567be8) /* 0.458614262 */, 17 },
+
+ /* 3840 */ { MAD_F(0x075722ef) /* 0.458773552 */, 17 },
+ /* 3841 */ { MAD_F(0x0757c9fa) /* 0.458932855 */, 17 },
+ /* 3842 */ { MAD_F(0x07587108) /* 0.459092172 */, 17 },
+ /* 3843 */ { MAD_F(0x0759181a) /* 0.459251503 */, 17 },
+ /* 3844 */ { MAD_F(0x0759bf30) /* 0.459410848 */, 17 },
+ /* 3845 */ { MAD_F(0x075a664a) /* 0.459570206 */, 17 },
+ /* 3846 */ { MAD_F(0x075b0d67) /* 0.459729579 */, 17 },
+ /* 3847 */ { MAD_F(0x075bb488) /* 0.459888965 */, 17 },
+ /* 3848 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 17 },
+ /* 3849 */ { MAD_F(0x075d02d5) /* 0.460207779 */, 17 },
+ /* 3850 */ { MAD_F(0x075daa01) /* 0.460367206 */, 17 },
+ /* 3851 */ { MAD_F(0x075e5130) /* 0.460526648 */, 17 },
+ /* 3852 */ { MAD_F(0x075ef864) /* 0.460686103 */, 17 },
+ /* 3853 */ { MAD_F(0x075f9f9b) /* 0.460845572 */, 17 },
+ /* 3854 */ { MAD_F(0x076046d6) /* 0.461005055 */, 17 },
+ /* 3855 */ { MAD_F(0x0760ee14) /* 0.461164552 */, 17 },
+
+ /* 3856 */ { MAD_F(0x07619557) /* 0.461324062 */, 17 },
+ /* 3857 */ { MAD_F(0x07623c9d) /* 0.461483586 */, 17 },
+ /* 3858 */ { MAD_F(0x0762e3e6) /* 0.461643124 */, 17 },
+ /* 3859 */ { MAD_F(0x07638b34) /* 0.461802676 */, 17 },
+ /* 3860 */ { MAD_F(0x07643285) /* 0.461962242 */, 17 },
+ /* 3861 */ { MAD_F(0x0764d9d9) /* 0.462121821 */, 17 },
+ /* 3862 */ { MAD_F(0x07658132) /* 0.462281414 */, 17 },
+ /* 3863 */ { MAD_F(0x0766288e) /* 0.462441021 */, 17 },
+ /* 3864 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 17 },
+ /* 3865 */ { MAD_F(0x07677751) /* 0.462760276 */, 17 },
+ /* 3866 */ { MAD_F(0x07681eb9) /* 0.462919924 */, 17 },
+ /* 3867 */ { MAD_F(0x0768c624) /* 0.463079586 */, 17 },
+ /* 3868 */ { MAD_F(0x07696d92) /* 0.463239262 */, 17 },
+ /* 3869 */ { MAD_F(0x076a1505) /* 0.463398951 */, 17 },
+ /* 3870 */ { MAD_F(0x076abc7b) /* 0.463558655 */, 17 },
+ /* 3871 */ { MAD_F(0x076b63f4) /* 0.463718372 */, 17 },
+
+ /* 3872 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 17 },
+ /* 3873 */ { MAD_F(0x076cb2f3) /* 0.464037847 */, 17 },
+ /* 3874 */ { MAD_F(0x076d5a78) /* 0.464197605 */, 17 },
+ /* 3875 */ { MAD_F(0x076e0200) /* 0.464357377 */, 17 },
+ /* 3876 */ { MAD_F(0x076ea98c) /* 0.464517163 */, 17 },
+ /* 3877 */ { MAD_F(0x076f511c) /* 0.464676962 */, 17 },
+ /* 3878 */ { MAD_F(0x076ff8b0) /* 0.464836776 */, 17 },
+ /* 3879 */ { MAD_F(0x0770a047) /* 0.464996603 */, 17 },
+ /* 3880 */ { MAD_F(0x077147e2) /* 0.465156443 */, 17 },
+ /* 3881 */ { MAD_F(0x0771ef80) /* 0.465316298 */, 17 },
+ /* 3882 */ { MAD_F(0x07729723) /* 0.465476166 */, 17 },
+ /* 3883 */ { MAD_F(0x07733ec9) /* 0.465636048 */, 17 },
+ /* 3884 */ { MAD_F(0x0773e672) /* 0.465795943 */, 17 },
+ /* 3885 */ { MAD_F(0x07748e20) /* 0.465955853 */, 17 },
+ /* 3886 */ { MAD_F(0x077535d1) /* 0.466115776 */, 17 },
+ /* 3887 */ { MAD_F(0x0775dd85) /* 0.466275713 */, 17 },
+
+ /* 3888 */ { MAD_F(0x0776853e) /* 0.466435663 */, 17 },
+ /* 3889 */ { MAD_F(0x07772cfa) /* 0.466595627 */, 17 },
+ /* 3890 */ { MAD_F(0x0777d4ba) /* 0.466755605 */, 17 },
+ /* 3891 */ { MAD_F(0x07787c7d) /* 0.466915597 */, 17 },
+ /* 3892 */ { MAD_F(0x07792444) /* 0.467075602 */, 17 },
+ /* 3893 */ { MAD_F(0x0779cc0f) /* 0.467235621 */, 17 },
+ /* 3894 */ { MAD_F(0x077a73dd) /* 0.467395654 */, 17 },
+ /* 3895 */ { MAD_F(0x077b1baf) /* 0.467555701 */, 17 },
+ /* 3896 */ { MAD_F(0x077bc385) /* 0.467715761 */, 17 },
+ /* 3897 */ { MAD_F(0x077c6b5f) /* 0.467875835 */, 17 },
+ /* 3898 */ { MAD_F(0x077d133c) /* 0.468035922 */, 17 },
+ /* 3899 */ { MAD_F(0x077dbb1d) /* 0.468196023 */, 17 },
+ /* 3900 */ { MAD_F(0x077e6301) /* 0.468356138 */, 17 },
+ /* 3901 */ { MAD_F(0x077f0ae9) /* 0.468516267 */, 17 },
+ /* 3902 */ { MAD_F(0x077fb2d5) /* 0.468676409 */, 17 },
+ /* 3903 */ { MAD_F(0x07805ac5) /* 0.468836565 */, 17 },
+
+ /* 3904 */ { MAD_F(0x078102b8) /* 0.468996735 */, 17 },
+ /* 3905 */ { MAD_F(0x0781aaaf) /* 0.469156918 */, 17 },
+ /* 3906 */ { MAD_F(0x078252aa) /* 0.469317115 */, 17 },
+ /* 3907 */ { MAD_F(0x0782faa8) /* 0.469477326 */, 17 },
+ /* 3908 */ { MAD_F(0x0783a2aa) /* 0.469637550 */, 17 },
+ /* 3909 */ { MAD_F(0x07844aaf) /* 0.469797788 */, 17 },
+ /* 3910 */ { MAD_F(0x0784f2b8) /* 0.469958040 */, 17 },
+ /* 3911 */ { MAD_F(0x07859ac5) /* 0.470118305 */, 17 },
+ /* 3912 */ { MAD_F(0x078642d6) /* 0.470278584 */, 17 },
+ /* 3913 */ { MAD_F(0x0786eaea) /* 0.470438877 */, 17 },
+ /* 3914 */ { MAD_F(0x07879302) /* 0.470599183 */, 17 },
+ /* 3915 */ { MAD_F(0x07883b1e) /* 0.470759503 */, 17 },
+ /* 3916 */ { MAD_F(0x0788e33d) /* 0.470919836 */, 17 },
+ /* 3917 */ { MAD_F(0x07898b60) /* 0.471080184 */, 17 },
+ /* 3918 */ { MAD_F(0x078a3386) /* 0.471240545 */, 17 },
+ /* 3919 */ { MAD_F(0x078adbb0) /* 0.471400919 */, 17 },
+
+ /* 3920 */ { MAD_F(0x078b83de) /* 0.471561307 */, 17 },
+ /* 3921 */ { MAD_F(0x078c2c10) /* 0.471721709 */, 17 },
+ /* 3922 */ { MAD_F(0x078cd445) /* 0.471882125 */, 17 },
+ /* 3923 */ { MAD_F(0x078d7c7e) /* 0.472042554 */, 17 },
+ /* 3924 */ { MAD_F(0x078e24ba) /* 0.472202996 */, 17 },
+ /* 3925 */ { MAD_F(0x078eccfb) /* 0.472363453 */, 17 },
+ /* 3926 */ { MAD_F(0x078f753e) /* 0.472523923 */, 17 },
+ /* 3927 */ { MAD_F(0x07901d86) /* 0.472684406 */, 17 },
+ /* 3928 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 17 },
+ /* 3929 */ { MAD_F(0x07916e20) /* 0.473005414 */, 17 },
+ /* 3930 */ { MAD_F(0x07921672) /* 0.473165939 */, 17 },
+ /* 3931 */ { MAD_F(0x0792bec8) /* 0.473326477 */, 17 },
+ /* 3932 */ { MAD_F(0x07936722) /* 0.473487029 */, 17 },
+ /* 3933 */ { MAD_F(0x07940f80) /* 0.473647594 */, 17 },
+ /* 3934 */ { MAD_F(0x0794b7e1) /* 0.473808173 */, 17 },
+ /* 3935 */ { MAD_F(0x07956045) /* 0.473968765 */, 17 },
+
+ /* 3936 */ { MAD_F(0x079608ae) /* 0.474129372 */, 17 },
+ /* 3937 */ { MAD_F(0x0796b11a) /* 0.474289991 */, 17 },
+ /* 3938 */ { MAD_F(0x0797598a) /* 0.474450625 */, 17 },
+ /* 3939 */ { MAD_F(0x079801fd) /* 0.474611272 */, 17 },
+ /* 3940 */ { MAD_F(0x0798aa74) /* 0.474771932 */, 17 },
+ /* 3941 */ { MAD_F(0x079952ee) /* 0.474932606 */, 17 },
+ /* 3942 */ { MAD_F(0x0799fb6d) /* 0.475093294 */, 17 },
+ /* 3943 */ { MAD_F(0x079aa3ef) /* 0.475253995 */, 17 },
+ /* 3944 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 17 },
+ /* 3945 */ { MAD_F(0x079bf4fd) /* 0.475575439 */, 17 },
+ /* 3946 */ { MAD_F(0x079c9d8a) /* 0.475736181 */, 17 },
+ /* 3947 */ { MAD_F(0x079d461b) /* 0.475896936 */, 17 },
+ /* 3948 */ { MAD_F(0x079deeaf) /* 0.476057705 */, 17 },
+ /* 3949 */ { MAD_F(0x079e9747) /* 0.476218488 */, 17 },
+ /* 3950 */ { MAD_F(0x079f3fe2) /* 0.476379285 */, 17 },
+ /* 3951 */ { MAD_F(0x079fe881) /* 0.476540095 */, 17 },
+
+ /* 3952 */ { MAD_F(0x07a09124) /* 0.476700918 */, 17 },
+ /* 3953 */ { MAD_F(0x07a139ca) /* 0.476861755 */, 17 },
+ /* 3954 */ { MAD_F(0x07a1e274) /* 0.477022606 */, 17 },
+ /* 3955 */ { MAD_F(0x07a28b22) /* 0.477183470 */, 17 },
+ /* 3956 */ { MAD_F(0x07a333d3) /* 0.477344348 */, 17 },
+ /* 3957 */ { MAD_F(0x07a3dc88) /* 0.477505239 */, 17 },
+ /* 3958 */ { MAD_F(0x07a48541) /* 0.477666144 */, 17 },
+ /* 3959 */ { MAD_F(0x07a52dfd) /* 0.477827062 */, 17 },
+ /* 3960 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 17 },
+ /* 3961 */ { MAD_F(0x07a67f80) /* 0.478148940 */, 17 },
+ /* 3962 */ { MAD_F(0x07a72847) /* 0.478309899 */, 17 },
+ /* 3963 */ { MAD_F(0x07a7d112) /* 0.478470871 */, 17 },
+ /* 3964 */ { MAD_F(0x07a879e1) /* 0.478631857 */, 17 },
+ /* 3965 */ { MAD_F(0x07a922b3) /* 0.478792857 */, 17 },
+ /* 3966 */ { MAD_F(0x07a9cb88) /* 0.478953870 */, 17 },
+ /* 3967 */ { MAD_F(0x07aa7462) /* 0.479114897 */, 17 },
+
+ /* 3968 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 17 },
+ /* 3969 */ { MAD_F(0x07abc61f) /* 0.479436991 */, 17 },
+ /* 3970 */ { MAD_F(0x07ac6f03) /* 0.479598058 */, 17 },
+ /* 3971 */ { MAD_F(0x07ad17eb) /* 0.479759139 */, 17 },
+ /* 3972 */ { MAD_F(0x07adc0d6) /* 0.479920233 */, 17 },
+ /* 3973 */ { MAD_F(0x07ae69c6) /* 0.480081341 */, 17 },
+ /* 3974 */ { MAD_F(0x07af12b8) /* 0.480242463 */, 17 },
+ /* 3975 */ { MAD_F(0x07afbbaf) /* 0.480403598 */, 17 },
+ /* 3976 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 17 },
+ /* 3977 */ { MAD_F(0x07b10da6) /* 0.480725908 */, 17 },
+ /* 3978 */ { MAD_F(0x07b1b6a7) /* 0.480887083 */, 17 },
+ /* 3979 */ { MAD_F(0x07b25fac) /* 0.481048272 */, 17 },
+ /* 3980 */ { MAD_F(0x07b308b5) /* 0.481209475 */, 17 },
+ /* 3981 */ { MAD_F(0x07b3b1c1) /* 0.481370691 */, 17 },
+ /* 3982 */ { MAD_F(0x07b45ad0) /* 0.481531920 */, 17 },
+ /* 3983 */ { MAD_F(0x07b503e4) /* 0.481693163 */, 17 },
+
+ /* 3984 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 17 },
+ /* 3985 */ { MAD_F(0x07b65615) /* 0.482015690 */, 17 },
+ /* 3986 */ { MAD_F(0x07b6ff33) /* 0.482176973 */, 17 },
+ /* 3987 */ { MAD_F(0x07b7a855) /* 0.482338270 */, 17 },
+ /* 3988 */ { MAD_F(0x07b8517b) /* 0.482499580 */, 17 },
+ /* 3989 */ { MAD_F(0x07b8faa4) /* 0.482660904 */, 17 },
+ /* 3990 */ { MAD_F(0x07b9a3d0) /* 0.482822242 */, 17 },
+ /* 3991 */ { MAD_F(0x07ba4d01) /* 0.482983592 */, 17 },
+ /* 3992 */ { MAD_F(0x07baf635) /* 0.483144957 */, 17 },
+ /* 3993 */ { MAD_F(0x07bb9f6c) /* 0.483306335 */, 17 },
+ /* 3994 */ { MAD_F(0x07bc48a7) /* 0.483467726 */, 17 },
+ /* 3995 */ { MAD_F(0x07bcf1e6) /* 0.483629131 */, 17 },
+ /* 3996 */ { MAD_F(0x07bd9b28) /* 0.483790549 */, 17 },
+ /* 3997 */ { MAD_F(0x07be446e) /* 0.483951980 */, 17 },
+ /* 3998 */ { MAD_F(0x07beedb8) /* 0.484113426 */, 17 },
+ /* 3999 */ { MAD_F(0x07bf9705) /* 0.484274884 */, 17 },
+
+ /* 4000 */ { MAD_F(0x07c04056) /* 0.484436356 */, 17 },
+ /* 4001 */ { MAD_F(0x07c0e9aa) /* 0.484597842 */, 17 },
+ /* 4002 */ { MAD_F(0x07c19302) /* 0.484759341 */, 17 },
+ /* 4003 */ { MAD_F(0x07c23c5e) /* 0.484920853 */, 17 },
+ /* 4004 */ { MAD_F(0x07c2e5bd) /* 0.485082379 */, 17 },
+ /* 4005 */ { MAD_F(0x07c38f20) /* 0.485243918 */, 17 },
+ /* 4006 */ { MAD_F(0x07c43887) /* 0.485405471 */, 17 },
+ /* 4007 */ { MAD_F(0x07c4e1f1) /* 0.485567037 */, 17 },
+ /* 4008 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 17 },
+ /* 4009 */ { MAD_F(0x07c634d0) /* 0.485890210 */, 17 },
+ /* 4010 */ { MAD_F(0x07c6de45) /* 0.486051817 */, 17 },
+ /* 4011 */ { MAD_F(0x07c787bd) /* 0.486213436 */, 17 },
+ /* 4012 */ { MAD_F(0x07c83139) /* 0.486375070 */, 17 },
+ /* 4013 */ { MAD_F(0x07c8dab9) /* 0.486536717 */, 17 },
+ /* 4014 */ { MAD_F(0x07c9843c) /* 0.486698377 */, 17 },
+ /* 4015 */ { MAD_F(0x07ca2dc3) /* 0.486860051 */, 17 },
+
+ /* 4016 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 17 },
+ /* 4017 */ { MAD_F(0x07cb80dc) /* 0.487183438 */, 17 },
+ /* 4018 */ { MAD_F(0x07cc2a6e) /* 0.487345152 */, 17 },
+ /* 4019 */ { MAD_F(0x07ccd403) /* 0.487506879 */, 17 },
+ /* 4020 */ { MAD_F(0x07cd7d9c) /* 0.487668620 */, 17 },
+ /* 4021 */ { MAD_F(0x07ce2739) /* 0.487830374 */, 17 },
+ /* 4022 */ { MAD_F(0x07ced0d9) /* 0.487992142 */, 17 },
+ /* 4023 */ { MAD_F(0x07cf7a7d) /* 0.488153923 */, 17 },
+ /* 4024 */ { MAD_F(0x07d02424) /* 0.488315717 */, 17 },
+ /* 4025 */ { MAD_F(0x07d0cdcf) /* 0.488477525 */, 17 },
+ /* 4026 */ { MAD_F(0x07d1777e) /* 0.488639346 */, 17 },
+ /* 4027 */ { MAD_F(0x07d22130) /* 0.488801181 */, 17 },
+ /* 4028 */ { MAD_F(0x07d2cae5) /* 0.488963029 */, 17 },
+ /* 4029 */ { MAD_F(0x07d3749f) /* 0.489124890 */, 17 },
+ /* 4030 */ { MAD_F(0x07d41e5c) /* 0.489286765 */, 17 },
+ /* 4031 */ { MAD_F(0x07d4c81c) /* 0.489448653 */, 17 },
+
+ /* 4032 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 17 },
+ /* 4033 */ { MAD_F(0x07d61ba8) /* 0.489772470 */, 17 },
+ /* 4034 */ { MAD_F(0x07d6c573) /* 0.489934398 */, 17 },
+ /* 4035 */ { MAD_F(0x07d76f42) /* 0.490096340 */, 17 },
+ /* 4036 */ { MAD_F(0x07d81915) /* 0.490258295 */, 17 },
+ /* 4037 */ { MAD_F(0x07d8c2eb) /* 0.490420263 */, 17 },
+ /* 4038 */ { MAD_F(0x07d96cc4) /* 0.490582245 */, 17 },
+ /* 4039 */ { MAD_F(0x07da16a2) /* 0.490744240 */, 17 },
+ /* 4040 */ { MAD_F(0x07dac083) /* 0.490906249 */, 17 },
+ /* 4041 */ { MAD_F(0x07db6a67) /* 0.491068271 */, 17 },
+ /* 4042 */ { MAD_F(0x07dc144f) /* 0.491230306 */, 17 },
+ /* 4043 */ { MAD_F(0x07dcbe3b) /* 0.491392355 */, 17 },
+ /* 4044 */ { MAD_F(0x07dd682a) /* 0.491554417 */, 17 },
+ /* 4045 */ { MAD_F(0x07de121d) /* 0.491716492 */, 17 },
+ /* 4046 */ { MAD_F(0x07debc13) /* 0.491878581 */, 17 },
+ /* 4047 */ { MAD_F(0x07df660d) /* 0.492040683 */, 17 },
+
+ /* 4048 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 17 },
+ /* 4049 */ { MAD_F(0x07e0ba0c) /* 0.492364928 */, 17 },
+ /* 4050 */ { MAD_F(0x07e16410) /* 0.492527070 */, 17 },
+ /* 4051 */ { MAD_F(0x07e20e19) /* 0.492689225 */, 17 },
+ /* 4052 */ { MAD_F(0x07e2b824) /* 0.492851394 */, 17 },
+ /* 4053 */ { MAD_F(0x07e36234) /* 0.493013576 */, 17 },
+ /* 4054 */ { MAD_F(0x07e40c47) /* 0.493175772 */, 17 },
+ /* 4055 */ { MAD_F(0x07e4b65e) /* 0.493337981 */, 17 },
+ /* 4056 */ { MAD_F(0x07e56078) /* 0.493500203 */, 17 },
+ /* 4057 */ { MAD_F(0x07e60a95) /* 0.493662438 */, 17 },
+ /* 4058 */ { MAD_F(0x07e6b4b7) /* 0.493824687 */, 17 },
+ /* 4059 */ { MAD_F(0x07e75edc) /* 0.493986949 */, 17 },
+ /* 4060 */ { MAD_F(0x07e80904) /* 0.494149225 */, 17 },
+ /* 4061 */ { MAD_F(0x07e8b330) /* 0.494311514 */, 17 },
+ /* 4062 */ { MAD_F(0x07e95d60) /* 0.494473816 */, 17 },
+ /* 4063 */ { MAD_F(0x07ea0793) /* 0.494636131 */, 17 },
+
+ /* 4064 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 17 },
+ /* 4065 */ { MAD_F(0x07eb5c04) /* 0.494960802 */, 17 },
+ /* 4066 */ { MAD_F(0x07ec0642) /* 0.495123158 */, 17 },
+ /* 4067 */ { MAD_F(0x07ecb084) /* 0.495285526 */, 17 },
+ /* 4068 */ { MAD_F(0x07ed5ac9) /* 0.495447908 */, 17 },
+ /* 4069 */ { MAD_F(0x07ee0512) /* 0.495610304 */, 17 },
+ /* 4070 */ { MAD_F(0x07eeaf5e) /* 0.495772712 */, 17 },
+ /* 4071 */ { MAD_F(0x07ef59ae) /* 0.495935134 */, 17 },
+ /* 4072 */ { MAD_F(0x07f00401) /* 0.496097570 */, 17 },
+ /* 4073 */ { MAD_F(0x07f0ae58) /* 0.496260018 */, 17 },
+ /* 4074 */ { MAD_F(0x07f158b3) /* 0.496422480 */, 17 },
+ /* 4075 */ { MAD_F(0x07f20311) /* 0.496584955 */, 17 },
+ /* 4076 */ { MAD_F(0x07f2ad72) /* 0.496747444 */, 17 },
+ /* 4077 */ { MAD_F(0x07f357d8) /* 0.496909945 */, 17 },
+ /* 4078 */ { MAD_F(0x07f40240) /* 0.497072460 */, 17 },
+ /* 4079 */ { MAD_F(0x07f4acad) /* 0.497234989 */, 17 },
+
+ /* 4080 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 17 },
+ /* 4081 */ { MAD_F(0x07f60190) /* 0.497560085 */, 17 },
+ /* 4082 */ { MAD_F(0x07f6ac07) /* 0.497722653 */, 17 },
+ /* 4083 */ { MAD_F(0x07f75682) /* 0.497885235 */, 17 },
+ /* 4084 */ { MAD_F(0x07f80100) /* 0.498047829 */, 17 },
+ /* 4085 */ { MAD_F(0x07f8ab82) /* 0.498210437 */, 17 },
+ /* 4086 */ { MAD_F(0x07f95607) /* 0.498373058 */, 17 },
+ /* 4087 */ { MAD_F(0x07fa0090) /* 0.498535693 */, 17 },
+ /* 4088 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 17 },
+ /* 4089 */ { MAD_F(0x07fb55ac) /* 0.498861002 */, 17 },
+ /* 4090 */ { MAD_F(0x07fc0040) /* 0.499023676 */, 17 },
+ /* 4091 */ { MAD_F(0x07fcaad7) /* 0.499186364 */, 17 },
+ /* 4092 */ { MAD_F(0x07fd5572) /* 0.499349064 */, 17 },
+ /* 4093 */ { MAD_F(0x07fe0010) /* 0.499511778 */, 17 },
+ /* 4094 */ { MAD_F(0x07feaab2) /* 0.499674506 */, 17 },
+ /* 4095 */ { MAD_F(0x07ff5557) /* 0.499837246 */, 17 },
+
+ /* 4096 */ { MAD_F(0x04000000) /* 0.250000000 */, 18 },
+ /* 4097 */ { MAD_F(0x04005556) /* 0.250081384 */, 18 },
+ /* 4098 */ { MAD_F(0x0400aaae) /* 0.250162774 */, 18 },
+ /* 4099 */ { MAD_F(0x04010008) /* 0.250244170 */, 18 },
+ /* 4100 */ { MAD_F(0x04015563) /* 0.250325574 */, 18 },
+ /* 4101 */ { MAD_F(0x0401aac1) /* 0.250406984 */, 18 },
+ /* 4102 */ { MAD_F(0x04020020) /* 0.250488400 */, 18 },
+ /* 4103 */ { MAD_F(0x04025581) /* 0.250569824 */, 18 },
+ /* 4104 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 18 },
+ /* 4105 */ { MAD_F(0x04030048) /* 0.250732690 */, 18 },
+ /* 4106 */ { MAD_F(0x040355ae) /* 0.250814133 */, 18 },
+ /* 4107 */ { MAD_F(0x0403ab16) /* 0.250895583 */, 18 },
+ /* 4108 */ { MAD_F(0x04040080) /* 0.250977039 */, 18 },
+ /* 4109 */ { MAD_F(0x040455eb) /* 0.251058502 */, 18 },
+ /* 4110 */ { MAD_F(0x0404ab59) /* 0.251139971 */, 18 },
+ /* 4111 */ { MAD_F(0x040500c8) /* 0.251221448 */, 18 },
+
+ /* 4112 */ { MAD_F(0x04055638) /* 0.251302930 */, 18 },
+ /* 4113 */ { MAD_F(0x0405abab) /* 0.251384420 */, 18 },
+ /* 4114 */ { MAD_F(0x0406011f) /* 0.251465916 */, 18 },
+ /* 4115 */ { MAD_F(0x04065696) /* 0.251547418 */, 18 },
+ /* 4116 */ { MAD_F(0x0406ac0e) /* 0.251628927 */, 18 },
+ /* 4117 */ { MAD_F(0x04070187) /* 0.251710443 */, 18 },
+ /* 4118 */ { MAD_F(0x04075703) /* 0.251791965 */, 18 },
+ /* 4119 */ { MAD_F(0x0407ac80) /* 0.251873494 */, 18 },
+ /* 4120 */ { MAD_F(0x040801ff) /* 0.251955030 */, 18 },
+ /* 4121 */ { MAD_F(0x04085780) /* 0.252036572 */, 18 },
+ /* 4122 */ { MAD_F(0x0408ad02) /* 0.252118121 */, 18 },
+ /* 4123 */ { MAD_F(0x04090287) /* 0.252199676 */, 18 },
+ /* 4124 */ { MAD_F(0x0409580d) /* 0.252281238 */, 18 },
+ /* 4125 */ { MAD_F(0x0409ad95) /* 0.252362807 */, 18 },
+ /* 4126 */ { MAD_F(0x040a031e) /* 0.252444382 */, 18 },
+ /* 4127 */ { MAD_F(0x040a58aa) /* 0.252525963 */, 18 },
+
+ /* 4128 */ { MAD_F(0x040aae37) /* 0.252607552 */, 18 },
+ /* 4129 */ { MAD_F(0x040b03c6) /* 0.252689147 */, 18 },
+ /* 4130 */ { MAD_F(0x040b5957) /* 0.252770748 */, 18 },
+ /* 4131 */ { MAD_F(0x040baee9) /* 0.252852356 */, 18 },
+ /* 4132 */ { MAD_F(0x040c047e) /* 0.252933971 */, 18 },
+ /* 4133 */ { MAD_F(0x040c5a14) /* 0.253015592 */, 18 },
+ /* 4134 */ { MAD_F(0x040cafab) /* 0.253097220 */, 18 },
+ /* 4135 */ { MAD_F(0x040d0545) /* 0.253178854 */, 18 },
+ /* 4136 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 18 },
+ /* 4137 */ { MAD_F(0x040db07d) /* 0.253342143 */, 18 },
+ /* 4138 */ { MAD_F(0x040e061c) /* 0.253423797 */, 18 },
+ /* 4139 */ { MAD_F(0x040e5bbd) /* 0.253505457 */, 18 },
+ /* 4140 */ { MAD_F(0x040eb15f) /* 0.253587125 */, 18 },
+ /* 4141 */ { MAD_F(0x040f0703) /* 0.253668799 */, 18 },
+ /* 4142 */ { MAD_F(0x040f5ca9) /* 0.253750479 */, 18 },
+ /* 4143 */ { MAD_F(0x040fb251) /* 0.253832166 */, 18 },
+
+ /* 4144 */ { MAD_F(0x041007fa) /* 0.253913860 */, 18 },
+ /* 4145 */ { MAD_F(0x04105da6) /* 0.253995560 */, 18 },
+ /* 4146 */ { MAD_F(0x0410b353) /* 0.254077266 */, 18 },
+ /* 4147 */ { MAD_F(0x04110901) /* 0.254158980 */, 18 },
+ /* 4148 */ { MAD_F(0x04115eb2) /* 0.254240700 */, 18 },
+ /* 4149 */ { MAD_F(0x0411b464) /* 0.254322426 */, 18 },
+ /* 4150 */ { MAD_F(0x04120a18) /* 0.254404159 */, 18 },
+ /* 4151 */ { MAD_F(0x04125fce) /* 0.254485899 */, 18 },
+ /* 4152 */ { MAD_F(0x0412b586) /* 0.254567645 */, 18 },
+ /* 4153 */ { MAD_F(0x04130b3f) /* 0.254649397 */, 18 },
+ /* 4154 */ { MAD_F(0x041360fa) /* 0.254731157 */, 18 },
+ /* 4155 */ { MAD_F(0x0413b6b7) /* 0.254812922 */, 18 },
+ /* 4156 */ { MAD_F(0x04140c75) /* 0.254894695 */, 18 },
+ /* 4157 */ { MAD_F(0x04146236) /* 0.254976474 */, 18 },
+ /* 4158 */ { MAD_F(0x0414b7f8) /* 0.255058259 */, 18 },
+ /* 4159 */ { MAD_F(0x04150dbc) /* 0.255140051 */, 18 },
+
+ /* 4160 */ { MAD_F(0x04156381) /* 0.255221850 */, 18 },
+ /* 4161 */ { MAD_F(0x0415b949) /* 0.255303655 */, 18 },
+ /* 4162 */ { MAD_F(0x04160f12) /* 0.255385467 */, 18 },
+ /* 4163 */ { MAD_F(0x041664dd) /* 0.255467285 */, 18 },
+ /* 4164 */ { MAD_F(0x0416baaa) /* 0.255549110 */, 18 },
+ /* 4165 */ { MAD_F(0x04171078) /* 0.255630941 */, 18 },
+ /* 4166 */ { MAD_F(0x04176648) /* 0.255712779 */, 18 },
+ /* 4167 */ { MAD_F(0x0417bc1a) /* 0.255794624 */, 18 },
+ /* 4168 */ { MAD_F(0x041811ee) /* 0.255876475 */, 18 },
+ /* 4169 */ { MAD_F(0x041867c3) /* 0.255958332 */, 18 },
+ /* 4170 */ { MAD_F(0x0418bd9b) /* 0.256040196 */, 18 },
+ /* 4171 */ { MAD_F(0x04191374) /* 0.256122067 */, 18 },
+ /* 4172 */ { MAD_F(0x0419694e) /* 0.256203944 */, 18 },
+ /* 4173 */ { MAD_F(0x0419bf2b) /* 0.256285828 */, 18 },
+ /* 4174 */ { MAD_F(0x041a1509) /* 0.256367718 */, 18 },
+ /* 4175 */ { MAD_F(0x041a6ae9) /* 0.256449615 */, 18 },
+
+ /* 4176 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 18 },
+ /* 4177 */ { MAD_F(0x041b16ae) /* 0.256613428 */, 18 },
+ /* 4178 */ { MAD_F(0x041b6c94) /* 0.256695344 */, 18 },
+ /* 4179 */ { MAD_F(0x041bc27b) /* 0.256777267 */, 18 },
+ /* 4180 */ { MAD_F(0x041c1863) /* 0.256859197 */, 18 },
+ /* 4181 */ { MAD_F(0x041c6e4e) /* 0.256941133 */, 18 },
+ /* 4182 */ { MAD_F(0x041cc43a) /* 0.257023076 */, 18 },
+ /* 4183 */ { MAD_F(0x041d1a28) /* 0.257105025 */, 18 },
+ /* 4184 */ { MAD_F(0x041d7018) /* 0.257186980 */, 18 },
+ /* 4185 */ { MAD_F(0x041dc60a) /* 0.257268942 */, 18 },
+ /* 4186 */ { MAD_F(0x041e1bfd) /* 0.257350911 */, 18 },
+ /* 4187 */ { MAD_F(0x041e71f2) /* 0.257432886 */, 18 },
+ /* 4188 */ { MAD_F(0x041ec7e9) /* 0.257514868 */, 18 },
+ /* 4189 */ { MAD_F(0x041f1de1) /* 0.257596856 */, 18 },
+ /* 4190 */ { MAD_F(0x041f73dc) /* 0.257678851 */, 18 },
+ /* 4191 */ { MAD_F(0x041fc9d8) /* 0.257760852 */, 18 },
+
+ /* 4192 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 18 },
+ /* 4193 */ { MAD_F(0x042075d5) /* 0.257924875 */, 18 },
+ /* 4194 */ { MAD_F(0x0420cbd6) /* 0.258006895 */, 18 },
+ /* 4195 */ { MAD_F(0x042121d9) /* 0.258088923 */, 18 },
+ /* 4196 */ { MAD_F(0x042177de) /* 0.258170957 */, 18 },
+ /* 4197 */ { MAD_F(0x0421cde5) /* 0.258252997 */, 18 },
+ /* 4198 */ { MAD_F(0x042223ed) /* 0.258335044 */, 18 },
+ /* 4199 */ { MAD_F(0x042279f7) /* 0.258417097 */, 18 },
+ /* 4200 */ { MAD_F(0x0422d003) /* 0.258499157 */, 18 },
+ /* 4201 */ { MAD_F(0x04232611) /* 0.258581224 */, 18 },
+ /* 4202 */ { MAD_F(0x04237c20) /* 0.258663297 */, 18 },
+ /* 4203 */ { MAD_F(0x0423d231) /* 0.258745376 */, 18 },
+ /* 4204 */ { MAD_F(0x04242844) /* 0.258827462 */, 18 },
+ /* 4205 */ { MAD_F(0x04247e58) /* 0.258909555 */, 18 },
+ /* 4206 */ { MAD_F(0x0424d46e) /* 0.258991654 */, 18 },
+ /* 4207 */ { MAD_F(0x04252a87) /* 0.259073760 */, 18 },
+
+ /* 4208 */ { MAD_F(0x042580a0) /* 0.259155872 */, 18 },
+ /* 4209 */ { MAD_F(0x0425d6bc) /* 0.259237990 */, 18 },
+ /* 4210 */ { MAD_F(0x04262cd9) /* 0.259320115 */, 18 },
+ /* 4211 */ { MAD_F(0x042682f8) /* 0.259402247 */, 18 },
+ /* 4212 */ { MAD_F(0x0426d919) /* 0.259484385 */, 18 },
+ /* 4213 */ { MAD_F(0x04272f3b) /* 0.259566529 */, 18 },
+ /* 4214 */ { MAD_F(0x04278560) /* 0.259648680 */, 18 },
+ /* 4215 */ { MAD_F(0x0427db86) /* 0.259730838 */, 18 },
+ /* 4216 */ { MAD_F(0x042831ad) /* 0.259813002 */, 18 },
+ /* 4217 */ { MAD_F(0x042887d7) /* 0.259895173 */, 18 },
+ /* 4218 */ { MAD_F(0x0428de02) /* 0.259977350 */, 18 },
+ /* 4219 */ { MAD_F(0x0429342f) /* 0.260059533 */, 18 },
+ /* 4220 */ { MAD_F(0x04298a5e) /* 0.260141723 */, 18 },
+ /* 4221 */ { MAD_F(0x0429e08e) /* 0.260223920 */, 18 },
+ /* 4222 */ { MAD_F(0x042a36c0) /* 0.260306123 */, 18 },
+ /* 4223 */ { MAD_F(0x042a8cf4) /* 0.260388332 */, 18 },
+
+ /* 4224 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 18 },
+ /* 4225 */ { MAD_F(0x042b3962) /* 0.260552771 */, 18 },
+ /* 4226 */ { MAD_F(0x042b8f9b) /* 0.260635000 */, 18 },
+ /* 4227 */ { MAD_F(0x042be5d6) /* 0.260717235 */, 18 },
+ /* 4228 */ { MAD_F(0x042c3c12) /* 0.260799477 */, 18 },
+ /* 4229 */ { MAD_F(0x042c9251) /* 0.260881725 */, 18 },
+ /* 4230 */ { MAD_F(0x042ce891) /* 0.260963980 */, 18 },
+ /* 4231 */ { MAD_F(0x042d3ed3) /* 0.261046242 */, 18 },
+ /* 4232 */ { MAD_F(0x042d9516) /* 0.261128510 */, 18 },
+ /* 4233 */ { MAD_F(0x042deb5c) /* 0.261210784 */, 18 },
+ /* 4234 */ { MAD_F(0x042e41a3) /* 0.261293065 */, 18 },
+ /* 4235 */ { MAD_F(0x042e97ec) /* 0.261375352 */, 18 },
+ /* 4236 */ { MAD_F(0x042eee36) /* 0.261457646 */, 18 },
+ /* 4237 */ { MAD_F(0x042f4482) /* 0.261539946 */, 18 },
+ /* 4238 */ { MAD_F(0x042f9ad1) /* 0.261622253 */, 18 },
+ /* 4239 */ { MAD_F(0x042ff120) /* 0.261704566 */, 18 },
+
+ /* 4240 */ { MAD_F(0x04304772) /* 0.261786886 */, 18 },
+ /* 4241 */ { MAD_F(0x04309dc5) /* 0.261869212 */, 18 },
+ /* 4242 */ { MAD_F(0x0430f41a) /* 0.261951545 */, 18 },
+ /* 4243 */ { MAD_F(0x04314a71) /* 0.262033884 */, 18 },
+ /* 4244 */ { MAD_F(0x0431a0c9) /* 0.262116229 */, 18 },
+ /* 4245 */ { MAD_F(0x0431f723) /* 0.262198581 */, 18 },
+ /* 4246 */ { MAD_F(0x04324d7f) /* 0.262280940 */, 18 },
+ /* 4247 */ { MAD_F(0x0432a3dd) /* 0.262363305 */, 18 },
+ /* 4248 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 18 },
+ /* 4249 */ { MAD_F(0x0433509e) /* 0.262528054 */, 18 },
+ /* 4250 */ { MAD_F(0x0433a701) /* 0.262610438 */, 18 },
+ /* 4251 */ { MAD_F(0x0433fd65) /* 0.262692829 */, 18 },
+ /* 4252 */ { MAD_F(0x043453cc) /* 0.262775227 */, 18 },
+ /* 4253 */ { MAD_F(0x0434aa34) /* 0.262857630 */, 18 },
+ /* 4254 */ { MAD_F(0x0435009d) /* 0.262940040 */, 18 },
+ /* 4255 */ { MAD_F(0x04355709) /* 0.263022457 */, 18 },
+
+ /* 4256 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 18 },
+ /* 4257 */ { MAD_F(0x043603e5) /* 0.263187310 */, 18 },
+ /* 4258 */ { MAD_F(0x04365a56) /* 0.263269746 */, 18 },
+ /* 4259 */ { MAD_F(0x0436b0c9) /* 0.263352188 */, 18 },
+ /* 4260 */ { MAD_F(0x0437073d) /* 0.263434637 */, 18 },
+ /* 4261 */ { MAD_F(0x04375db3) /* 0.263517093 */, 18 },
+ /* 4262 */ { MAD_F(0x0437b42a) /* 0.263599554 */, 18 },
+ /* 4263 */ { MAD_F(0x04380aa4) /* 0.263682023 */, 18 },
+ /* 4264 */ { MAD_F(0x0438611f) /* 0.263764497 */, 18 },
+ /* 4265 */ { MAD_F(0x0438b79c) /* 0.263846979 */, 18 },
+ /* 4266 */ { MAD_F(0x04390e1a) /* 0.263929466 */, 18 },
+ /* 4267 */ { MAD_F(0x0439649b) /* 0.264011960 */, 18 },
+ /* 4268 */ { MAD_F(0x0439bb1d) /* 0.264094461 */, 18 },
+ /* 4269 */ { MAD_F(0x043a11a1) /* 0.264176968 */, 18 },
+ /* 4270 */ { MAD_F(0x043a6826) /* 0.264259481 */, 18 },
+ /* 4271 */ { MAD_F(0x043abead) /* 0.264342001 */, 18 },
+
+ /* 4272 */ { MAD_F(0x043b1536) /* 0.264424527 */, 18 },
+ /* 4273 */ { MAD_F(0x043b6bc1) /* 0.264507060 */, 18 },
+ /* 4274 */ { MAD_F(0x043bc24d) /* 0.264589599 */, 18 },
+ /* 4275 */ { MAD_F(0x043c18dc) /* 0.264672145 */, 18 },
+ /* 4276 */ { MAD_F(0x043c6f6c) /* 0.264754697 */, 18 },
+ /* 4277 */ { MAD_F(0x043cc5fd) /* 0.264837255 */, 18 },
+ /* 4278 */ { MAD_F(0x043d1c91) /* 0.264919820 */, 18 },
+ /* 4279 */ { MAD_F(0x043d7326) /* 0.265002392 */, 18 },
+ /* 4280 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 18 },
+ /* 4281 */ { MAD_F(0x043e2055) /* 0.265167554 */, 18 },
+ /* 4282 */ { MAD_F(0x043e76ef) /* 0.265250144 */, 18 },
+ /* 4283 */ { MAD_F(0x043ecd8b) /* 0.265332741 */, 18 },
+ /* 4284 */ { MAD_F(0x043f2429) /* 0.265415345 */, 18 },
+ /* 4285 */ { MAD_F(0x043f7ac8) /* 0.265497955 */, 18 },
+ /* 4286 */ { MAD_F(0x043fd169) /* 0.265580571 */, 18 },
+ /* 4287 */ { MAD_F(0x0440280c) /* 0.265663194 */, 18 },
+
+ /* 4288 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 18 },
+ /* 4289 */ { MAD_F(0x0440d557) /* 0.265828459 */, 18 },
+ /* 4290 */ { MAD_F(0x04412bff) /* 0.265911101 */, 18 },
+ /* 4291 */ { MAD_F(0x044182a9) /* 0.265993749 */, 18 },
+ /* 4292 */ { MAD_F(0x0441d955) /* 0.266076404 */, 18 },
+ /* 4293 */ { MAD_F(0x04423002) /* 0.266159065 */, 18 },
+ /* 4294 */ { MAD_F(0x044286b1) /* 0.266241733 */, 18 },
+ /* 4295 */ { MAD_F(0x0442dd61) /* 0.266324407 */, 18 },
+ /* 4296 */ { MAD_F(0x04433414) /* 0.266407088 */, 18 },
+ /* 4297 */ { MAD_F(0x04438ac8) /* 0.266489775 */, 18 },
+ /* 4298 */ { MAD_F(0x0443e17e) /* 0.266572468 */, 18 },
+ /* 4299 */ { MAD_F(0x04443835) /* 0.266655168 */, 18 },
+ /* 4300 */ { MAD_F(0x04448eef) /* 0.266737874 */, 18 },
+ /* 4301 */ { MAD_F(0x0444e5aa) /* 0.266820587 */, 18 },
+ /* 4302 */ { MAD_F(0x04453c66) /* 0.266903306 */, 18 },
+ /* 4303 */ { MAD_F(0x04459325) /* 0.266986031 */, 18 },
+
+ /* 4304 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 18 },
+ /* 4305 */ { MAD_F(0x044640a7) /* 0.267151501 */, 18 },
+ /* 4306 */ { MAD_F(0x0446976a) /* 0.267234246 */, 18 },
+ /* 4307 */ { MAD_F(0x0446ee30) /* 0.267316997 */, 18 },
+ /* 4308 */ { MAD_F(0x044744f7) /* 0.267399755 */, 18 },
+ /* 4309 */ { MAD_F(0x04479bc0) /* 0.267482518 */, 18 },
+ /* 4310 */ { MAD_F(0x0447f28a) /* 0.267565289 */, 18 },
+ /* 4311 */ { MAD_F(0x04484956) /* 0.267648065 */, 18 },
+ /* 4312 */ { MAD_F(0x0448a024) /* 0.267730848 */, 18 },
+ /* 4313 */ { MAD_F(0x0448f6f4) /* 0.267813638 */, 18 },
+ /* 4314 */ { MAD_F(0x04494dc5) /* 0.267896434 */, 18 },
+ /* 4315 */ { MAD_F(0x0449a498) /* 0.267979236 */, 18 },
+ /* 4316 */ { MAD_F(0x0449fb6d) /* 0.268062045 */, 18 },
+ /* 4317 */ { MAD_F(0x044a5243) /* 0.268144860 */, 18 },
+ /* 4318 */ { MAD_F(0x044aa91c) /* 0.268227681 */, 18 },
+ /* 4319 */ { MAD_F(0x044afff6) /* 0.268310509 */, 18 },
+
+ /* 4320 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 18 },
+ /* 4321 */ { MAD_F(0x044badaf) /* 0.268476184 */, 18 },
+ /* 4322 */ { MAD_F(0x044c048e) /* 0.268559031 */, 18 },
+ /* 4323 */ { MAD_F(0x044c5b6f) /* 0.268641885 */, 18 },
+ /* 4324 */ { MAD_F(0x044cb251) /* 0.268724744 */, 18 },
+ /* 4325 */ { MAD_F(0x044d0935) /* 0.268807611 */, 18 },
+ /* 4326 */ { MAD_F(0x044d601b) /* 0.268890483 */, 18 },
+ /* 4327 */ { MAD_F(0x044db703) /* 0.268973362 */, 18 },
+ /* 4328 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 18 },
+ /* 4329 */ { MAD_F(0x044e64d7) /* 0.269139139 */, 18 },
+ /* 4330 */ { MAD_F(0x044ebbc4) /* 0.269222037 */, 18 },
+ /* 4331 */ { MAD_F(0x044f12b3) /* 0.269304942 */, 18 },
+ /* 4332 */ { MAD_F(0x044f69a3) /* 0.269387853 */, 18 },
+ /* 4333 */ { MAD_F(0x044fc095) /* 0.269470770 */, 18 },
+ /* 4334 */ { MAD_F(0x04501788) /* 0.269553694 */, 18 },
+ /* 4335 */ { MAD_F(0x04506e7e) /* 0.269636624 */, 18 },
+
+ /* 4336 */ { MAD_F(0x0450c575) /* 0.269719560 */, 18 },
+ /* 4337 */ { MAD_F(0x04511c6e) /* 0.269802503 */, 18 },
+ /* 4338 */ { MAD_F(0x04517368) /* 0.269885452 */, 18 },
+ /* 4339 */ { MAD_F(0x0451ca64) /* 0.269968408 */, 18 },
+ /* 4340 */ { MAD_F(0x04522162) /* 0.270051370 */, 18 },
+ /* 4341 */ { MAD_F(0x04527862) /* 0.270134338 */, 18 },
+ /* 4342 */ { MAD_F(0x0452cf63) /* 0.270217312 */, 18 },
+ /* 4343 */ { MAD_F(0x04532666) /* 0.270300293 */, 18 },
+ /* 4344 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 18 },
+ /* 4345 */ { MAD_F(0x0453d472) /* 0.270466275 */, 18 },
+ /* 4346 */ { MAD_F(0x04542b7a) /* 0.270549275 */, 18 },
+ /* 4347 */ { MAD_F(0x04548284) /* 0.270632281 */, 18 },
+ /* 4348 */ { MAD_F(0x0454d98f) /* 0.270715294 */, 18 },
+ /* 4349 */ { MAD_F(0x0455309c) /* 0.270798313 */, 18 },
+ /* 4350 */ { MAD_F(0x045587ab) /* 0.270881339 */, 18 },
+ /* 4351 */ { MAD_F(0x0455debc) /* 0.270964371 */, 18 },
+
+ /* 4352 */ { MAD_F(0x045635cf) /* 0.271047409 */, 18 },
+ /* 4353 */ { MAD_F(0x04568ce3) /* 0.271130454 */, 18 },
+ /* 4354 */ { MAD_F(0x0456e3f9) /* 0.271213505 */, 18 },
+ /* 4355 */ { MAD_F(0x04573b10) /* 0.271296562 */, 18 },
+ /* 4356 */ { MAD_F(0x04579229) /* 0.271379626 */, 18 },
+ /* 4357 */ { MAD_F(0x0457e944) /* 0.271462696 */, 18 },
+ /* 4358 */ { MAD_F(0x04584061) /* 0.271545772 */, 18 },
+ /* 4359 */ { MAD_F(0x0458977f) /* 0.271628855 */, 18 },
+ /* 4360 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 18 },
+ /* 4361 */ { MAD_F(0x045945c1) /* 0.271795040 */, 18 },
+ /* 4362 */ { MAD_F(0x04599ce5) /* 0.271878142 */, 18 },
+ /* 4363 */ { MAD_F(0x0459f40a) /* 0.271961250 */, 18 },
+ /* 4364 */ { MAD_F(0x045a4b31) /* 0.272044365 */, 18 },
+ /* 4365 */ { MAD_F(0x045aa259) /* 0.272127486 */, 18 },
+ /* 4366 */ { MAD_F(0x045af984) /* 0.272210613 */, 18 },
+ /* 4367 */ { MAD_F(0x045b50b0) /* 0.272293746 */, 18 },
+
+ /* 4368 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 18 },
+ /* 4369 */ { MAD_F(0x045bff0d) /* 0.272460033 */, 18 },
+ /* 4370 */ { MAD_F(0x045c563e) /* 0.272543185 */, 18 },
+ /* 4371 */ { MAD_F(0x045cad71) /* 0.272626344 */, 18 },
+ /* 4372 */ { MAD_F(0x045d04a5) /* 0.272709510 */, 18 },
+ /* 4373 */ { MAD_F(0x045d5bdc) /* 0.272792681 */, 18 },
+ /* 4374 */ { MAD_F(0x045db313) /* 0.272875859 */, 18 },
+ /* 4375 */ { MAD_F(0x045e0a4d) /* 0.272959044 */, 18 },
+ /* 4376 */ { MAD_F(0x045e6188) /* 0.273042234 */, 18 },
+ /* 4377 */ { MAD_F(0x045eb8c5) /* 0.273125431 */, 18 },
+ /* 4378 */ { MAD_F(0x045f1004) /* 0.273208635 */, 18 },
+ /* 4379 */ { MAD_F(0x045f6745) /* 0.273291844 */, 18 },
+ /* 4380 */ { MAD_F(0x045fbe87) /* 0.273375060 */, 18 },
+ /* 4381 */ { MAD_F(0x046015cb) /* 0.273458283 */, 18 },
+ /* 4382 */ { MAD_F(0x04606d10) /* 0.273541511 */, 18 },
+ /* 4383 */ { MAD_F(0x0460c457) /* 0.273624747 */, 18 },
+
+ /* 4384 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 18 },
+ /* 4385 */ { MAD_F(0x046172eb) /* 0.273791236 */, 18 },
+ /* 4386 */ { MAD_F(0x0461ca37) /* 0.273874490 */, 18 },
+ /* 4387 */ { MAD_F(0x04622185) /* 0.273957750 */, 18 },
+ /* 4388 */ { MAD_F(0x046278d5) /* 0.274041017 */, 18 },
+ /* 4389 */ { MAD_F(0x0462d026) /* 0.274124290 */, 18 },
+ /* 4390 */ { MAD_F(0x0463277a) /* 0.274207569 */, 18 },
+ /* 4391 */ { MAD_F(0x04637ece) /* 0.274290855 */, 18 },
+ /* 4392 */ { MAD_F(0x0463d625) /* 0.274374147 */, 18 },
+ /* 4393 */ { MAD_F(0x04642d7d) /* 0.274457445 */, 18 },
+ /* 4394 */ { MAD_F(0x046484d7) /* 0.274540749 */, 18 },
+ /* 4395 */ { MAD_F(0x0464dc33) /* 0.274624060 */, 18 },
+ /* 4396 */ { MAD_F(0x04653390) /* 0.274707378 */, 18 },
+ /* 4397 */ { MAD_F(0x04658aef) /* 0.274790701 */, 18 },
+ /* 4398 */ { MAD_F(0x0465e250) /* 0.274874031 */, 18 },
+ /* 4399 */ { MAD_F(0x046639b2) /* 0.274957367 */, 18 },
+
+ /* 4400 */ { MAD_F(0x04669116) /* 0.275040710 */, 18 },
+ /* 4401 */ { MAD_F(0x0466e87c) /* 0.275124059 */, 18 },
+ /* 4402 */ { MAD_F(0x04673fe3) /* 0.275207414 */, 18 },
+ /* 4403 */ { MAD_F(0x0467974d) /* 0.275290775 */, 18 },
+ /* 4404 */ { MAD_F(0x0467eeb7) /* 0.275374143 */, 18 },
+ /* 4405 */ { MAD_F(0x04684624) /* 0.275457517 */, 18 },
+ /* 4406 */ { MAD_F(0x04689d92) /* 0.275540897 */, 18 },
+ /* 4407 */ { MAD_F(0x0468f502) /* 0.275624284 */, 18 },
+ /* 4408 */ { MAD_F(0x04694c74) /* 0.275707677 */, 18 },
+ /* 4409 */ { MAD_F(0x0469a3e7) /* 0.275791076 */, 18 },
+ /* 4410 */ { MAD_F(0x0469fb5c) /* 0.275874482 */, 18 },
+ /* 4411 */ { MAD_F(0x046a52d3) /* 0.275957894 */, 18 },
+ /* 4412 */ { MAD_F(0x046aaa4b) /* 0.276041312 */, 18 },
+ /* 4413 */ { MAD_F(0x046b01c5) /* 0.276124737 */, 18 },
+ /* 4414 */ { MAD_F(0x046b5941) /* 0.276208167 */, 18 },
+ /* 4415 */ { MAD_F(0x046bb0bf) /* 0.276291605 */, 18 },
+
+ /* 4416 */ { MAD_F(0x046c083e) /* 0.276375048 */, 18 },
+ /* 4417 */ { MAD_F(0x046c5fbf) /* 0.276458498 */, 18 },
+ /* 4418 */ { MAD_F(0x046cb741) /* 0.276541954 */, 18 },
+ /* 4419 */ { MAD_F(0x046d0ec5) /* 0.276625416 */, 18 },
+ /* 4420 */ { MAD_F(0x046d664b) /* 0.276708885 */, 18 },
+ /* 4421 */ { MAD_F(0x046dbdd3) /* 0.276792360 */, 18 },
+ /* 4422 */ { MAD_F(0x046e155c) /* 0.276875841 */, 18 },
+ /* 4423 */ { MAD_F(0x046e6ce7) /* 0.276959328 */, 18 },
+ /* 4424 */ { MAD_F(0x046ec474) /* 0.277042822 */, 18 },
+ /* 4425 */ { MAD_F(0x046f1c02) /* 0.277126322 */, 18 },
+ /* 4426 */ { MAD_F(0x046f7392) /* 0.277209829 */, 18 },
+ /* 4427 */ { MAD_F(0x046fcb24) /* 0.277293341 */, 18 },
+ /* 4428 */ { MAD_F(0x047022b8) /* 0.277376860 */, 18 },
+ /* 4429 */ { MAD_F(0x04707a4d) /* 0.277460385 */, 18 },
+ /* 4430 */ { MAD_F(0x0470d1e4) /* 0.277543917 */, 18 },
+ /* 4431 */ { MAD_F(0x0471297c) /* 0.277627455 */, 18 },
+
+ /* 4432 */ { MAD_F(0x04718116) /* 0.277710999 */, 18 },
+ /* 4433 */ { MAD_F(0x0471d8b2) /* 0.277794549 */, 18 },
+ /* 4434 */ { MAD_F(0x04723050) /* 0.277878106 */, 18 },
+ /* 4435 */ { MAD_F(0x047287ef) /* 0.277961669 */, 18 },
+ /* 4436 */ { MAD_F(0x0472df90) /* 0.278045238 */, 18 },
+ /* 4437 */ { MAD_F(0x04733733) /* 0.278128813 */, 18 },
+ /* 4438 */ { MAD_F(0x04738ed7) /* 0.278212395 */, 18 },
+ /* 4439 */ { MAD_F(0x0473e67d) /* 0.278295983 */, 18 },
+ /* 4440 */ { MAD_F(0x04743e25) /* 0.278379578 */, 18 },
+ /* 4441 */ { MAD_F(0x047495ce) /* 0.278463178 */, 18 },
+ /* 4442 */ { MAD_F(0x0474ed79) /* 0.278546785 */, 18 },
+ /* 4443 */ { MAD_F(0x04754526) /* 0.278630398 */, 18 },
+ /* 4444 */ { MAD_F(0x04759cd4) /* 0.278714018 */, 18 },
+ /* 4445 */ { MAD_F(0x0475f484) /* 0.278797643 */, 18 },
+ /* 4446 */ { MAD_F(0x04764c36) /* 0.278881275 */, 18 },
+ /* 4447 */ { MAD_F(0x0476a3ea) /* 0.278964914 */, 18 },
+
+ /* 4448 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 18 },
+ /* 4449 */ { MAD_F(0x04775356) /* 0.279132209 */, 18 },
+ /* 4450 */ { MAD_F(0x0477ab0e) /* 0.279215866 */, 18 },
+ /* 4451 */ { MAD_F(0x047802c8) /* 0.279299529 */, 18 },
+ /* 4452 */ { MAD_F(0x04785a84) /* 0.279383199 */, 18 },
+ /* 4453 */ { MAD_F(0x0478b242) /* 0.279466875 */, 18 },
+ /* 4454 */ { MAD_F(0x04790a01) /* 0.279550557 */, 18 },
+ /* 4455 */ { MAD_F(0x047961c2) /* 0.279634245 */, 18 },
+ /* 4456 */ { MAD_F(0x0479b984) /* 0.279717940 */, 18 },
+ /* 4457 */ { MAD_F(0x047a1149) /* 0.279801641 */, 18 },
+ /* 4458 */ { MAD_F(0x047a690f) /* 0.279885348 */, 18 },
+ /* 4459 */ { MAD_F(0x047ac0d6) /* 0.279969061 */, 18 },
+ /* 4460 */ { MAD_F(0x047b18a0) /* 0.280052781 */, 18 },
+ /* 4461 */ { MAD_F(0x047b706b) /* 0.280136507 */, 18 },
+ /* 4462 */ { MAD_F(0x047bc837) /* 0.280220239 */, 18 },
+ /* 4463 */ { MAD_F(0x047c2006) /* 0.280303978 */, 18 },
+
+ /* 4464 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 18 },
+ /* 4465 */ { MAD_F(0x047ccfa8) /* 0.280471473 */, 18 },
+ /* 4466 */ { MAD_F(0x047d277b) /* 0.280555230 */, 18 },
+ /* 4467 */ { MAD_F(0x047d7f50) /* 0.280638994 */, 18 },
+ /* 4468 */ { MAD_F(0x047dd727) /* 0.280722764 */, 18 },
+ /* 4469 */ { MAD_F(0x047e2eff) /* 0.280806540 */, 18 },
+ /* 4470 */ { MAD_F(0x047e86d9) /* 0.280890322 */, 18 },
+ /* 4471 */ { MAD_F(0x047edeb5) /* 0.280974110 */, 18 },
+ /* 4472 */ { MAD_F(0x047f3693) /* 0.281057905 */, 18 },
+ /* 4473 */ { MAD_F(0x047f8e72) /* 0.281141706 */, 18 },
+ /* 4474 */ { MAD_F(0x047fe653) /* 0.281225513 */, 18 },
+ /* 4475 */ { MAD_F(0x04803e35) /* 0.281309326 */, 18 },
+ /* 4476 */ { MAD_F(0x04809619) /* 0.281393146 */, 18 },
+ /* 4477 */ { MAD_F(0x0480edff) /* 0.281476972 */, 18 },
+ /* 4478 */ { MAD_F(0x048145e7) /* 0.281560804 */, 18 },
+ /* 4479 */ { MAD_F(0x04819dd0) /* 0.281644643 */, 18 },
+
+ /* 4480 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 18 },
+ /* 4481 */ { MAD_F(0x04824da7) /* 0.281812338 */, 18 },
+ /* 4482 */ { MAD_F(0x0482a595) /* 0.281896195 */, 18 },
+ /* 4483 */ { MAD_F(0x0482fd85) /* 0.281980059 */, 18 },
+ /* 4484 */ { MAD_F(0x04835577) /* 0.282063928 */, 18 },
+ /* 4485 */ { MAD_F(0x0483ad6a) /* 0.282147804 */, 18 },
+ /* 4486 */ { MAD_F(0x0484055f) /* 0.282231686 */, 18 },
+ /* 4487 */ { MAD_F(0x04845d56) /* 0.282315574 */, 18 },
+ /* 4488 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 18 },
+ /* 4489 */ { MAD_F(0x04850d48) /* 0.282483370 */, 18 },
+ /* 4490 */ { MAD_F(0x04856544) /* 0.282567277 */, 18 },
+ /* 4491 */ { MAD_F(0x0485bd41) /* 0.282651190 */, 18 },
+ /* 4492 */ { MAD_F(0x04861540) /* 0.282735109 */, 18 },
+ /* 4493 */ { MAD_F(0x04866d40) /* 0.282819035 */, 18 },
+ /* 4494 */ { MAD_F(0x0486c543) /* 0.282902967 */, 18 },
+ /* 4495 */ { MAD_F(0x04871d47) /* 0.282986905 */, 18 },
+
+ /* 4496 */ { MAD_F(0x0487754c) /* 0.283070849 */, 18 },
+ /* 4497 */ { MAD_F(0x0487cd54) /* 0.283154800 */, 18 },
+ /* 4498 */ { MAD_F(0x0488255d) /* 0.283238757 */, 18 },
+ /* 4499 */ { MAD_F(0x04887d67) /* 0.283322720 */, 18 },
+ /* 4500 */ { MAD_F(0x0488d574) /* 0.283406689 */, 18 },
+ /* 4501 */ { MAD_F(0x04892d82) /* 0.283490665 */, 18 },
+ /* 4502 */ { MAD_F(0x04898591) /* 0.283574646 */, 18 },
+ /* 4503 */ { MAD_F(0x0489dda3) /* 0.283658634 */, 18 },
+ /* 4504 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 18 },
+ /* 4505 */ { MAD_F(0x048a8dca) /* 0.283826629 */, 18 },
+ /* 4506 */ { MAD_F(0x048ae5e1) /* 0.283910635 */, 18 },
+ /* 4507 */ { MAD_F(0x048b3df9) /* 0.283994648 */, 18 },
+ /* 4508 */ { MAD_F(0x048b9612) /* 0.284078667 */, 18 },
+ /* 4509 */ { MAD_F(0x048bee2e) /* 0.284162692 */, 18 },
+ /* 4510 */ { MAD_F(0x048c464b) /* 0.284246723 */, 18 },
+ /* 4511 */ { MAD_F(0x048c9e69) /* 0.284330761 */, 18 },
+
+ /* 4512 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 18 },
+ /* 4513 */ { MAD_F(0x048d4eac) /* 0.284498855 */, 18 },
+ /* 4514 */ { MAD_F(0x048da6cf) /* 0.284582911 */, 18 },
+ /* 4515 */ { MAD_F(0x048dfef5) /* 0.284666974 */, 18 },
+ /* 4516 */ { MAD_F(0x048e571c) /* 0.284751042 */, 18 },
+ /* 4517 */ { MAD_F(0x048eaf44) /* 0.284835117 */, 18 },
+ /* 4518 */ { MAD_F(0x048f076f) /* 0.284919198 */, 18 },
+ /* 4519 */ { MAD_F(0x048f5f9b) /* 0.285003285 */, 18 },
+ /* 4520 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 18 },
+ /* 4521 */ { MAD_F(0x04900ff8) /* 0.285171479 */, 18 },
+ /* 4522 */ { MAD_F(0x04906829) /* 0.285255584 */, 18 },
+ /* 4523 */ { MAD_F(0x0490c05b) /* 0.285339697 */, 18 },
+ /* 4524 */ { MAD_F(0x04911890) /* 0.285423815 */, 18 },
+ /* 4525 */ { MAD_F(0x049170c6) /* 0.285507939 */, 18 },
+ /* 4526 */ { MAD_F(0x0491c8fd) /* 0.285592070 */, 18 },
+ /* 4527 */ { MAD_F(0x04922137) /* 0.285676207 */, 18 },
+
+ /* 4528 */ { MAD_F(0x04927972) /* 0.285760350 */, 18 },
+ /* 4529 */ { MAD_F(0x0492d1ae) /* 0.285844499 */, 18 },
+ /* 4530 */ { MAD_F(0x049329ed) /* 0.285928655 */, 18 },
+ /* 4531 */ { MAD_F(0x0493822c) /* 0.286012816 */, 18 },
+ /* 4532 */ { MAD_F(0x0493da6e) /* 0.286096984 */, 18 },
+ /* 4533 */ { MAD_F(0x049432b1) /* 0.286181158 */, 18 },
+ /* 4534 */ { MAD_F(0x04948af6) /* 0.286265338 */, 18 },
+ /* 4535 */ { MAD_F(0x0494e33d) /* 0.286349525 */, 18 },
+ /* 4536 */ { MAD_F(0x04953b85) /* 0.286433717 */, 18 },
+ /* 4537 */ { MAD_F(0x049593cf) /* 0.286517916 */, 18 },
+ /* 4538 */ { MAD_F(0x0495ec1b) /* 0.286602121 */, 18 },
+ /* 4539 */ { MAD_F(0x04964468) /* 0.286686332 */, 18 },
+ /* 4540 */ { MAD_F(0x04969cb7) /* 0.286770550 */, 18 },
+ /* 4541 */ { MAD_F(0x0496f508) /* 0.286854773 */, 18 },
+ /* 4542 */ { MAD_F(0x04974d5a) /* 0.286939003 */, 18 },
+ /* 4543 */ { MAD_F(0x0497a5ae) /* 0.287023239 */, 18 },
+
+ /* 4544 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 18 },
+ /* 4545 */ { MAD_F(0x0498565a) /* 0.287191729 */, 18 },
+ /* 4546 */ { MAD_F(0x0498aeb3) /* 0.287275983 */, 18 },
+ /* 4547 */ { MAD_F(0x0499070e) /* 0.287360244 */, 18 },
+ /* 4548 */ { MAD_F(0x04995f6a) /* 0.287444511 */, 18 },
+ /* 4549 */ { MAD_F(0x0499b7c8) /* 0.287528784 */, 18 },
+ /* 4550 */ { MAD_F(0x049a1027) /* 0.287613063 */, 18 },
+ /* 4551 */ { MAD_F(0x049a6889) /* 0.287697348 */, 18 },
+ /* 4552 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 18 },
+ /* 4553 */ { MAD_F(0x049b1950) /* 0.287865937 */, 18 },
+ /* 4554 */ { MAD_F(0x049b71b6) /* 0.287950241 */, 18 },
+ /* 4555 */ { MAD_F(0x049bca1e) /* 0.288034551 */, 18 },
+ /* 4556 */ { MAD_F(0x049c2287) /* 0.288118867 */, 18 },
+ /* 4557 */ { MAD_F(0x049c7af2) /* 0.288203190 */, 18 },
+ /* 4558 */ { MAD_F(0x049cd35f) /* 0.288287518 */, 18 },
+ /* 4559 */ { MAD_F(0x049d2bce) /* 0.288371853 */, 18 },
+
+ /* 4560 */ { MAD_F(0x049d843e) /* 0.288456194 */, 18 },
+ /* 4561 */ { MAD_F(0x049ddcaf) /* 0.288540541 */, 18 },
+ /* 4562 */ { MAD_F(0x049e3523) /* 0.288624894 */, 18 },
+ /* 4563 */ { MAD_F(0x049e8d98) /* 0.288709253 */, 18 },
+ /* 4564 */ { MAD_F(0x049ee60e) /* 0.288793619 */, 18 },
+ /* 4565 */ { MAD_F(0x049f3e87) /* 0.288877990 */, 18 },
+ /* 4566 */ { MAD_F(0x049f9701) /* 0.288962368 */, 18 },
+ /* 4567 */ { MAD_F(0x049fef7c) /* 0.289046752 */, 18 },
+ /* 4568 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 18 },
+ /* 4569 */ { MAD_F(0x04a0a079) /* 0.289215538 */, 18 },
+ /* 4570 */ { MAD_F(0x04a0f8f9) /* 0.289299941 */, 18 },
+ /* 4571 */ { MAD_F(0x04a1517c) /* 0.289384349 */, 18 },
+ /* 4572 */ { MAD_F(0x04a1a9ff) /* 0.289468764 */, 18 },
+ /* 4573 */ { MAD_F(0x04a20285) /* 0.289553185 */, 18 },
+ /* 4574 */ { MAD_F(0x04a25b0c) /* 0.289637612 */, 18 },
+ /* 4575 */ { MAD_F(0x04a2b395) /* 0.289722045 */, 18 },
+
+ /* 4576 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 18 },
+ /* 4577 */ { MAD_F(0x04a364ac) /* 0.289890930 */, 18 },
+ /* 4578 */ { MAD_F(0x04a3bd3a) /* 0.289975382 */, 18 },
+ /* 4579 */ { MAD_F(0x04a415c9) /* 0.290059840 */, 18 },
+ /* 4580 */ { MAD_F(0x04a46e5a) /* 0.290144304 */, 18 },
+ /* 4581 */ { MAD_F(0x04a4c6ed) /* 0.290228774 */, 18 },
+ /* 4582 */ { MAD_F(0x04a51f81) /* 0.290313250 */, 18 },
+ /* 4583 */ { MAD_F(0x04a57818) /* 0.290397733 */, 18 },
+ /* 4584 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 18 },
+ /* 4585 */ { MAD_F(0x04a62949) /* 0.290566716 */, 18 },
+ /* 4586 */ { MAD_F(0x04a681e4) /* 0.290651217 */, 18 },
+ /* 4587 */ { MAD_F(0x04a6da80) /* 0.290735724 */, 18 },
+ /* 4588 */ { MAD_F(0x04a7331f) /* 0.290820237 */, 18 },
+ /* 4589 */ { MAD_F(0x04a78bbf) /* 0.290904756 */, 18 },
+ /* 4590 */ { MAD_F(0x04a7e460) /* 0.290989281 */, 18 },
+ /* 4591 */ { MAD_F(0x04a83d03) /* 0.291073813 */, 18 },
+
+ /* 4592 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 18 },
+ /* 4593 */ { MAD_F(0x04a8ee4f) /* 0.291242894 */, 18 },
+ /* 4594 */ { MAD_F(0x04a946f7) /* 0.291327444 */, 18 },
+ /* 4595 */ { MAD_F(0x04a99fa1) /* 0.291412001 */, 18 },
+ /* 4596 */ { MAD_F(0x04a9f84c) /* 0.291496563 */, 18 },
+ /* 4597 */ { MAD_F(0x04aa50fa) /* 0.291581131 */, 18 },
+ /* 4598 */ { MAD_F(0x04aaa9a8) /* 0.291665706 */, 18 },
+ /* 4599 */ { MAD_F(0x04ab0259) /* 0.291750286 */, 18 },
+ /* 4600 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 18 },
+ /* 4601 */ { MAD_F(0x04abb3bf) /* 0.291919466 */, 18 },
+ /* 4602 */ { MAD_F(0x04ac0c74) /* 0.292004065 */, 18 },
+ /* 4603 */ { MAD_F(0x04ac652b) /* 0.292088670 */, 18 },
+ /* 4604 */ { MAD_F(0x04acbde4) /* 0.292173281 */, 18 },
+ /* 4605 */ { MAD_F(0x04ad169e) /* 0.292257899 */, 18 },
+ /* 4606 */ { MAD_F(0x04ad6f5a) /* 0.292342522 */, 18 },
+ /* 4607 */ { MAD_F(0x04adc818) /* 0.292427152 */, 18 },
+
+ /* 4608 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 18 },
+ /* 4609 */ { MAD_F(0x04ae7998) /* 0.292596430 */, 18 },
+ /* 4610 */ { MAD_F(0x04aed25a) /* 0.292681078 */, 18 },
+ /* 4611 */ { MAD_F(0x04af2b1e) /* 0.292765732 */, 18 },
+ /* 4612 */ { MAD_F(0x04af83e4) /* 0.292850392 */, 18 },
+ /* 4613 */ { MAD_F(0x04afdcac) /* 0.292935058 */, 18 },
+ /* 4614 */ { MAD_F(0x04b03575) /* 0.293019731 */, 18 },
+ /* 4615 */ { MAD_F(0x04b08e40) /* 0.293104409 */, 18 },
+ /* 4616 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 18 },
+ /* 4617 */ { MAD_F(0x04b13fda) /* 0.293273785 */, 18 },
+ /* 4618 */ { MAD_F(0x04b198aa) /* 0.293358482 */, 18 },
+ /* 4619 */ { MAD_F(0x04b1f17b) /* 0.293443185 */, 18 },
+ /* 4620 */ { MAD_F(0x04b24a4e) /* 0.293527894 */, 18 },
+ /* 4621 */ { MAD_F(0x04b2a322) /* 0.293612609 */, 18 },
+ /* 4622 */ { MAD_F(0x04b2fbf9) /* 0.293697331 */, 18 },
+ /* 4623 */ { MAD_F(0x04b354d1) /* 0.293782058 */, 18 },
+
+ /* 4624 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 18 },
+ /* 4625 */ { MAD_F(0x04b40685) /* 0.293951532 */, 18 },
+ /* 4626 */ { MAD_F(0x04b45f62) /* 0.294036278 */, 18 },
+ /* 4627 */ { MAD_F(0x04b4b840) /* 0.294121029 */, 18 },
+ /* 4628 */ { MAD_F(0x04b51120) /* 0.294205788 */, 18 },
+ /* 4629 */ { MAD_F(0x04b56a02) /* 0.294290552 */, 18 },
+ /* 4630 */ { MAD_F(0x04b5c2e6) /* 0.294375322 */, 18 },
+ /* 4631 */ { MAD_F(0x04b61bcb) /* 0.294460098 */, 18 },
+ /* 4632 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 18 },
+ /* 4633 */ { MAD_F(0x04b6cd99) /* 0.294629669 */, 18 },
+ /* 4634 */ { MAD_F(0x04b72683) /* 0.294714464 */, 18 },
+ /* 4635 */ { MAD_F(0x04b77f6f) /* 0.294799265 */, 18 },
+ /* 4636 */ { MAD_F(0x04b7d85c) /* 0.294884072 */, 18 },
+ /* 4637 */ { MAD_F(0x04b8314b) /* 0.294968885 */, 18 },
+ /* 4638 */ { MAD_F(0x04b88a3b) /* 0.295053704 */, 18 },
+ /* 4639 */ { MAD_F(0x04b8e32d) /* 0.295138529 */, 18 },
+
+ /* 4640 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 18 },
+ /* 4641 */ { MAD_F(0x04b99516) /* 0.295308197 */, 18 },
+ /* 4642 */ { MAD_F(0x04b9ee0d) /* 0.295393041 */, 18 },
+ /* 4643 */ { MAD_F(0x04ba4706) /* 0.295477890 */, 18 },
+ /* 4644 */ { MAD_F(0x04baa000) /* 0.295562746 */, 18 },
+ /* 4645 */ { MAD_F(0x04baf8fc) /* 0.295647608 */, 18 },
+ /* 4646 */ { MAD_F(0x04bb51fa) /* 0.295732476 */, 18 },
+ /* 4647 */ { MAD_F(0x04bbaaf9) /* 0.295817349 */, 18 },
+ /* 4648 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 18 },
+ /* 4649 */ { MAD_F(0x04bc5cfc) /* 0.295987115 */, 18 },
+ /* 4650 */ { MAD_F(0x04bcb600) /* 0.296072008 */, 18 },
+ /* 4651 */ { MAD_F(0x04bd0f06) /* 0.296156906 */, 18 },
+ /* 4652 */ { MAD_F(0x04bd680d) /* 0.296241810 */, 18 },
+ /* 4653 */ { MAD_F(0x04bdc116) /* 0.296326721 */, 18 },
+ /* 4654 */ { MAD_F(0x04be1a21) /* 0.296411637 */, 18 },
+ /* 4655 */ { MAD_F(0x04be732d) /* 0.296496560 */, 18 },
+
+ /* 4656 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 18 },
+ /* 4657 */ { MAD_F(0x04bf254a) /* 0.296666423 */, 18 },
+ /* 4658 */ { MAD_F(0x04bf7e5b) /* 0.296751364 */, 18 },
+ /* 4659 */ { MAD_F(0x04bfd76e) /* 0.296836311 */, 18 },
+ /* 4660 */ { MAD_F(0x04c03083) /* 0.296921264 */, 18 },
+ /* 4661 */ { MAD_F(0x04c08999) /* 0.297006223 */, 18 },
+ /* 4662 */ { MAD_F(0x04c0e2b0) /* 0.297091188 */, 18 },
+ /* 4663 */ { MAD_F(0x04c13bca) /* 0.297176159 */, 18 },
+ /* 4664 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 18 },
+ /* 4665 */ { MAD_F(0x04c1ee01) /* 0.297346120 */, 18 },
+ /* 4666 */ { MAD_F(0x04c2471f) /* 0.297431109 */, 18 },
+ /* 4667 */ { MAD_F(0x04c2a03f) /* 0.297516105 */, 18 },
+ /* 4668 */ { MAD_F(0x04c2f960) /* 0.297601106 */, 18 },
+ /* 4669 */ { MAD_F(0x04c35283) /* 0.297686114 */, 18 },
+ /* 4670 */ { MAD_F(0x04c3aba8) /* 0.297771128 */, 18 },
+ /* 4671 */ { MAD_F(0x04c404ce) /* 0.297856147 */, 18 },
+
+ /* 4672 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 18 },
+ /* 4673 */ { MAD_F(0x04c4b720) /* 0.298026205 */, 18 },
+ /* 4674 */ { MAD_F(0x04c5104b) /* 0.298111243 */, 18 },
+ /* 4675 */ { MAD_F(0x04c56978) /* 0.298196287 */, 18 },
+ /* 4676 */ { MAD_F(0x04c5c2a7) /* 0.298281337 */, 18 },
+ /* 4677 */ { MAD_F(0x04c61bd7) /* 0.298366393 */, 18 },
+ /* 4678 */ { MAD_F(0x04c67508) /* 0.298451456 */, 18 },
+ /* 4679 */ { MAD_F(0x04c6ce3c) /* 0.298536524 */, 18 },
+ /* 4680 */ { MAD_F(0x04c72771) /* 0.298621598 */, 18 },
+ /* 4681 */ { MAD_F(0x04c780a7) /* 0.298706679 */, 18 },
+ /* 4682 */ { MAD_F(0x04c7d9df) /* 0.298791765 */, 18 },
+ /* 4683 */ { MAD_F(0x04c83319) /* 0.298876858 */, 18 },
+ /* 4684 */ { MAD_F(0x04c88c55) /* 0.298961956 */, 18 },
+ /* 4685 */ { MAD_F(0x04c8e592) /* 0.299047061 */, 18 },
+ /* 4686 */ { MAD_F(0x04c93ed1) /* 0.299132172 */, 18 },
+ /* 4687 */ { MAD_F(0x04c99811) /* 0.299217288 */, 18 },
+
+ /* 4688 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 18 },
+ /* 4689 */ { MAD_F(0x04ca4a97) /* 0.299387540 */, 18 },
+ /* 4690 */ { MAD_F(0x04caa3dc) /* 0.299472675 */, 18 },
+ /* 4691 */ { MAD_F(0x04cafd23) /* 0.299557816 */, 18 },
+ /* 4692 */ { MAD_F(0x04cb566b) /* 0.299642963 */, 18 },
+ /* 4693 */ { MAD_F(0x04cbafb5) /* 0.299728116 */, 18 },
+ /* 4694 */ { MAD_F(0x04cc0901) /* 0.299813275 */, 18 },
+ /* 4695 */ { MAD_F(0x04cc624e) /* 0.299898440 */, 18 },
+ /* 4696 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 18 },
+ /* 4697 */ { MAD_F(0x04cd14ee) /* 0.300068789 */, 18 },
+ /* 4698 */ { MAD_F(0x04cd6e40) /* 0.300153972 */, 18 },
+ /* 4699 */ { MAD_F(0x04cdc794) /* 0.300239161 */, 18 },
+ /* 4700 */ { MAD_F(0x04ce20e9) /* 0.300324357 */, 18 },
+ /* 4701 */ { MAD_F(0x04ce7a40) /* 0.300409558 */, 18 },
+ /* 4702 */ { MAD_F(0x04ced399) /* 0.300494765 */, 18 },
+ /* 4703 */ { MAD_F(0x04cf2cf3) /* 0.300579979 */, 18 },
+
+ /* 4704 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 18 },
+ /* 4705 */ { MAD_F(0x04cfdfad) /* 0.300750424 */, 18 },
+ /* 4706 */ { MAD_F(0x04d0390c) /* 0.300835656 */, 18 },
+ /* 4707 */ { MAD_F(0x04d0926d) /* 0.300920893 */, 18 },
+ /* 4708 */ { MAD_F(0x04d0ebcf) /* 0.301006137 */, 18 },
+ /* 4709 */ { MAD_F(0x04d14533) /* 0.301091387 */, 18 },
+ /* 4710 */ { MAD_F(0x04d19e99) /* 0.301176643 */, 18 },
+ /* 4711 */ { MAD_F(0x04d1f800) /* 0.301261904 */, 18 },
+ /* 4712 */ { MAD_F(0x04d25169) /* 0.301347172 */, 18 },
+ /* 4713 */ { MAD_F(0x04d2aad4) /* 0.301432446 */, 18 },
+ /* 4714 */ { MAD_F(0x04d30440) /* 0.301517726 */, 18 },
+ /* 4715 */ { MAD_F(0x04d35dae) /* 0.301603012 */, 18 },
+ /* 4716 */ { MAD_F(0x04d3b71d) /* 0.301688304 */, 18 },
+ /* 4717 */ { MAD_F(0x04d4108e) /* 0.301773602 */, 18 },
+ /* 4718 */ { MAD_F(0x04d46a01) /* 0.301858906 */, 18 },
+ /* 4719 */ { MAD_F(0x04d4c375) /* 0.301944216 */, 18 },
+
+ /* 4720 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 18 },
+ /* 4721 */ { MAD_F(0x04d57662) /* 0.302114854 */, 18 },
+ /* 4722 */ { MAD_F(0x04d5cfdb) /* 0.302200182 */, 18 },
+ /* 4723 */ { MAD_F(0x04d62956) /* 0.302285516 */, 18 },
+ /* 4724 */ { MAD_F(0x04d682d2) /* 0.302370856 */, 18 },
+ /* 4725 */ { MAD_F(0x04d6dc50) /* 0.302456203 */, 18 },
+ /* 4726 */ { MAD_F(0x04d735d0) /* 0.302541555 */, 18 },
+ /* 4727 */ { MAD_F(0x04d78f51) /* 0.302626913 */, 18 },
+ /* 4728 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 18 },
+ /* 4729 */ { MAD_F(0x04d84258) /* 0.302797648 */, 18 },
+ /* 4730 */ { MAD_F(0x04d89bde) /* 0.302883024 */, 18 },
+ /* 4731 */ { MAD_F(0x04d8f566) /* 0.302968406 */, 18 },
+ /* 4732 */ { MAD_F(0x04d94eef) /* 0.303053794 */, 18 },
+ /* 4733 */ { MAD_F(0x04d9a87a) /* 0.303139189 */, 18 },
+ /* 4734 */ { MAD_F(0x04da0207) /* 0.303224589 */, 18 },
+ /* 4735 */ { MAD_F(0x04da5b95) /* 0.303309995 */, 18 },
+
+ /* 4736 */ { MAD_F(0x04dab524) /* 0.303395408 */, 18 },
+ /* 4737 */ { MAD_F(0x04db0eb6) /* 0.303480826 */, 18 },
+ /* 4738 */ { MAD_F(0x04db6849) /* 0.303566251 */, 18 },
+ /* 4739 */ { MAD_F(0x04dbc1dd) /* 0.303651681 */, 18 },
+ /* 4740 */ { MAD_F(0x04dc1b73) /* 0.303737117 */, 18 },
+ /* 4741 */ { MAD_F(0x04dc750b) /* 0.303822560 */, 18 },
+ /* 4742 */ { MAD_F(0x04dccea5) /* 0.303908008 */, 18 },
+ /* 4743 */ { MAD_F(0x04dd2840) /* 0.303993463 */, 18 },
+ /* 4744 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 18 },
+ /* 4745 */ { MAD_F(0x04dddb7a) /* 0.304164390 */, 18 },
+ /* 4746 */ { MAD_F(0x04de351a) /* 0.304249862 */, 18 },
+ /* 4747 */ { MAD_F(0x04de8ebc) /* 0.304335340 */, 18 },
+ /* 4748 */ { MAD_F(0x04dee85f) /* 0.304420825 */, 18 },
+ /* 4749 */ { MAD_F(0x04df4203) /* 0.304506315 */, 18 },
+ /* 4750 */ { MAD_F(0x04df9baa) /* 0.304591812 */, 18 },
+ /* 4751 */ { MAD_F(0x04dff552) /* 0.304677314 */, 18 },
+
+ /* 4752 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 18 },
+ /* 4753 */ { MAD_F(0x04e0a8a6) /* 0.304848337 */, 18 },
+ /* 4754 */ { MAD_F(0x04e10253) /* 0.304933858 */, 18 },
+ /* 4755 */ { MAD_F(0x04e15c01) /* 0.305019384 */, 18 },
+ /* 4756 */ { MAD_F(0x04e1b5b1) /* 0.305104917 */, 18 },
+ /* 4757 */ { MAD_F(0x04e20f63) /* 0.305190455 */, 18 },
+ /* 4758 */ { MAD_F(0x04e26916) /* 0.305275999 */, 18 },
+ /* 4759 */ { MAD_F(0x04e2c2cb) /* 0.305361550 */, 18 },
+ /* 4760 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 18 },
+ /* 4761 */ { MAD_F(0x04e37639) /* 0.305532669 */, 18 },
+ /* 4762 */ { MAD_F(0x04e3cff3) /* 0.305618237 */, 18 },
+ /* 4763 */ { MAD_F(0x04e429ae) /* 0.305703811 */, 18 },
+ /* 4764 */ { MAD_F(0x04e4836b) /* 0.305789392 */, 18 },
+ /* 4765 */ { MAD_F(0x04e4dd29) /* 0.305874978 */, 18 },
+ /* 4766 */ { MAD_F(0x04e536e9) /* 0.305960571 */, 18 },
+ /* 4767 */ { MAD_F(0x04e590ab) /* 0.306046169 */, 18 },
+
+ /* 4768 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 18 },
+ /* 4769 */ { MAD_F(0x04e64433) /* 0.306217383 */, 18 },
+ /* 4770 */ { MAD_F(0x04e69df9) /* 0.306303000 */, 18 },
+ /* 4771 */ { MAD_F(0x04e6f7c1) /* 0.306388622 */, 18 },
+ /* 4772 */ { MAD_F(0x04e7518b) /* 0.306474250 */, 18 },
+ /* 4773 */ { MAD_F(0x04e7ab56) /* 0.306559885 */, 18 },
+ /* 4774 */ { MAD_F(0x04e80523) /* 0.306645525 */, 18 },
+ /* 4775 */ { MAD_F(0x04e85ef2) /* 0.306731171 */, 18 },
+ /* 4776 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 18 },
+ /* 4777 */ { MAD_F(0x04e91293) /* 0.306902481 */, 18 },
+ /* 4778 */ { MAD_F(0x04e96c67) /* 0.306988145 */, 18 },
+ /* 4779 */ { MAD_F(0x04e9c63b) /* 0.307073816 */, 18 },
+ /* 4780 */ { MAD_F(0x04ea2012) /* 0.307159492 */, 18 },
+ /* 4781 */ { MAD_F(0x04ea79ea) /* 0.307245174 */, 18 },
+ /* 4782 */ { MAD_F(0x04ead3c4) /* 0.307330862 */, 18 },
+ /* 4783 */ { MAD_F(0x04eb2d9f) /* 0.307416556 */, 18 },
+
+ /* 4784 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 18 },
+ /* 4785 */ { MAD_F(0x04ebe15b) /* 0.307587962 */, 18 },
+ /* 4786 */ { MAD_F(0x04ec3b3b) /* 0.307673674 */, 18 },
+ /* 4787 */ { MAD_F(0x04ec951c) /* 0.307759392 */, 18 },
+ /* 4788 */ { MAD_F(0x04ecef00) /* 0.307845115 */, 18 },
+ /* 4789 */ { MAD_F(0x04ed48e5) /* 0.307930845 */, 18 },
+ /* 4790 */ { MAD_F(0x04eda2cb) /* 0.308016581 */, 18 },
+ /* 4791 */ { MAD_F(0x04edfcb3) /* 0.308102323 */, 18 },
+ /* 4792 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 18 },
+ /* 4793 */ { MAD_F(0x04eeb088) /* 0.308273824 */, 18 },
+ /* 4794 */ { MAD_F(0x04ef0a75) /* 0.308359584 */, 18 },
+ /* 4795 */ { MAD_F(0x04ef6464) /* 0.308445350 */, 18 },
+ /* 4796 */ { MAD_F(0x04efbe54) /* 0.308531121 */, 18 },
+ /* 4797 */ { MAD_F(0x04f01846) /* 0.308616899 */, 18 },
+ /* 4798 */ { MAD_F(0x04f07239) /* 0.308702682 */, 18 },
+ /* 4799 */ { MAD_F(0x04f0cc2e) /* 0.308788472 */, 18 },
+
+ /* 4800 */ { MAD_F(0x04f12624) /* 0.308874267 */, 18 },
+ /* 4801 */ { MAD_F(0x04f1801d) /* 0.308960068 */, 18 },
+ /* 4802 */ { MAD_F(0x04f1da16) /* 0.309045876 */, 18 },
+ /* 4803 */ { MAD_F(0x04f23412) /* 0.309131689 */, 18 },
+ /* 4804 */ { MAD_F(0x04f28e0f) /* 0.309217508 */, 18 },
+ /* 4805 */ { MAD_F(0x04f2e80d) /* 0.309303334 */, 18 },
+ /* 4806 */ { MAD_F(0x04f3420d) /* 0.309389165 */, 18 },
+ /* 4807 */ { MAD_F(0x04f39c0f) /* 0.309475002 */, 18 },
+ /* 4808 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 18 },
+ /* 4809 */ { MAD_F(0x04f45017) /* 0.309646694 */, 18 },
+ /* 4810 */ { MAD_F(0x04f4aa1e) /* 0.309732549 */, 18 },
+ /* 4811 */ { MAD_F(0x04f50426) /* 0.309818410 */, 18 },
+ /* 4812 */ { MAD_F(0x04f55e30) /* 0.309904277 */, 18 },
+ /* 4813 */ { MAD_F(0x04f5b83b) /* 0.309990150 */, 18 },
+ /* 4814 */ { MAD_F(0x04f61248) /* 0.310076028 */, 18 },
+ /* 4815 */ { MAD_F(0x04f66c56) /* 0.310161913 */, 18 },
+
+ /* 4816 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 18 },
+ /* 4817 */ { MAD_F(0x04f72078) /* 0.310333700 */, 18 },
+ /* 4818 */ { MAD_F(0x04f77a8b) /* 0.310419603 */, 18 },
+ /* 4819 */ { MAD_F(0x04f7d4a0) /* 0.310505511 */, 18 },
+ /* 4820 */ { MAD_F(0x04f82eb7) /* 0.310591426 */, 18 },
+ /* 4821 */ { MAD_F(0x04f888cf) /* 0.310677346 */, 18 },
+ /* 4822 */ { MAD_F(0x04f8e2e9) /* 0.310763272 */, 18 },
+ /* 4823 */ { MAD_F(0x04f93d04) /* 0.310849205 */, 18 },
+ /* 4824 */ { MAD_F(0x04f99721) /* 0.310935143 */, 18 },
+ /* 4825 */ { MAD_F(0x04f9f13f) /* 0.311021087 */, 18 },
+ /* 4826 */ { MAD_F(0x04fa4b5f) /* 0.311107037 */, 18 },
+ /* 4827 */ { MAD_F(0x04faa581) /* 0.311192993 */, 18 },
+ /* 4828 */ { MAD_F(0x04faffa4) /* 0.311278955 */, 18 },
+ /* 4829 */ { MAD_F(0x04fb59c9) /* 0.311364923 */, 18 },
+ /* 4830 */ { MAD_F(0x04fbb3ef) /* 0.311450897 */, 18 },
+ /* 4831 */ { MAD_F(0x04fc0e17) /* 0.311536877 */, 18 },
+
+ /* 4832 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 18 },
+ /* 4833 */ { MAD_F(0x04fcc26c) /* 0.311708854 */, 18 },
+ /* 4834 */ { MAD_F(0x04fd1c99) /* 0.311794851 */, 18 },
+ /* 4835 */ { MAD_F(0x04fd76c7) /* 0.311880855 */, 18 },
+ /* 4836 */ { MAD_F(0x04fdd0f7) /* 0.311966864 */, 18 },
+ /* 4837 */ { MAD_F(0x04fe2b29) /* 0.312052880 */, 18 },
+ /* 4838 */ { MAD_F(0x04fe855c) /* 0.312138901 */, 18 },
+ /* 4839 */ { MAD_F(0x04fedf91) /* 0.312224928 */, 18 },
+ /* 4840 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 18 },
+ /* 4841 */ { MAD_F(0x04ff93ff) /* 0.312397000 */, 18 },
+ /* 4842 */ { MAD_F(0x04ffee38) /* 0.312483045 */, 18 },
+ /* 4843 */ { MAD_F(0x05004874) /* 0.312569096 */, 18 },
+ /* 4844 */ { MAD_F(0x0500a2b0) /* 0.312655153 */, 18 },
+ /* 4845 */ { MAD_F(0x0500fcef) /* 0.312741216 */, 18 },
+ /* 4846 */ { MAD_F(0x0501572e) /* 0.312827284 */, 18 },
+ /* 4847 */ { MAD_F(0x0501b170) /* 0.312913359 */, 18 },
+
+ /* 4848 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 18 },
+ /* 4849 */ { MAD_F(0x050265f8) /* 0.313085526 */, 18 },
+ /* 4850 */ { MAD_F(0x0502c03e) /* 0.313171618 */, 18 },
+ /* 4851 */ { MAD_F(0x05031a86) /* 0.313257716 */, 18 },
+ /* 4852 */ { MAD_F(0x050374cf) /* 0.313343820 */, 18 },
+ /* 4853 */ { MAD_F(0x0503cf1a) /* 0.313429931 */, 18 },
+ /* 4854 */ { MAD_F(0x05042967) /* 0.313516047 */, 18 },
+ /* 4855 */ { MAD_F(0x050483b5) /* 0.313602168 */, 18 },
+ /* 4856 */ { MAD_F(0x0504de05) /* 0.313688296 */, 18 },
+ /* 4857 */ { MAD_F(0x05053856) /* 0.313774430 */, 18 },
+ /* 4858 */ { MAD_F(0x050592a9) /* 0.313860570 */, 18 },
+ /* 4859 */ { MAD_F(0x0505ecfd) /* 0.313946715 */, 18 },
+ /* 4860 */ { MAD_F(0x05064754) /* 0.314032867 */, 18 },
+ /* 4861 */ { MAD_F(0x0506a1ab) /* 0.314119024 */, 18 },
+ /* 4862 */ { MAD_F(0x0506fc04) /* 0.314205187 */, 18 },
+ /* 4863 */ { MAD_F(0x0507565f) /* 0.314291357 */, 18 },
+
+ /* 4864 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 18 },
+ /* 4865 */ { MAD_F(0x05080b1a) /* 0.314463713 */, 18 },
+ /* 4866 */ { MAD_F(0x05086579) /* 0.314549900 */, 18 },
+ /* 4867 */ { MAD_F(0x0508bfdb) /* 0.314636092 */, 18 },
+ /* 4868 */ { MAD_F(0x05091a3d) /* 0.314722291 */, 18 },
+ /* 4869 */ { MAD_F(0x050974a2) /* 0.314808496 */, 18 },
+ /* 4870 */ { MAD_F(0x0509cf08) /* 0.314894706 */, 18 },
+ /* 4871 */ { MAD_F(0x050a296f) /* 0.314980923 */, 18 },
+ /* 4872 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 18 },
+ /* 4873 */ { MAD_F(0x050ade43) /* 0.315153373 */, 18 },
+ /* 4874 */ { MAD_F(0x050b38af) /* 0.315239607 */, 18 },
+ /* 4875 */ { MAD_F(0x050b931d) /* 0.315325847 */, 18 },
+ /* 4876 */ { MAD_F(0x050bed8d) /* 0.315412093 */, 18 },
+ /* 4877 */ { MAD_F(0x050c47fe) /* 0.315498345 */, 18 },
+ /* 4878 */ { MAD_F(0x050ca271) /* 0.315584603 */, 18 },
+ /* 4879 */ { MAD_F(0x050cfce5) /* 0.315670866 */, 18 },
+
+ /* 4880 */ { MAD_F(0x050d575b) /* 0.315757136 */, 18 },
+ /* 4881 */ { MAD_F(0x050db1d2) /* 0.315843411 */, 18 },
+ /* 4882 */ { MAD_F(0x050e0c4b) /* 0.315929693 */, 18 },
+ /* 4883 */ { MAD_F(0x050e66c5) /* 0.316015980 */, 18 },
+ /* 4884 */ { MAD_F(0x050ec141) /* 0.316102273 */, 18 },
+ /* 4885 */ { MAD_F(0x050f1bbf) /* 0.316188572 */, 18 },
+ /* 4886 */ { MAD_F(0x050f763e) /* 0.316274877 */, 18 },
+ /* 4887 */ { MAD_F(0x050fd0bf) /* 0.316361187 */, 18 },
+ /* 4888 */ { MAD_F(0x05102b42) /* 0.316447504 */, 18 },
+ /* 4889 */ { MAD_F(0x051085c6) /* 0.316533826 */, 18 },
+ /* 4890 */ { MAD_F(0x0510e04b) /* 0.316620155 */, 18 },
+ /* 4891 */ { MAD_F(0x05113ad3) /* 0.316706489 */, 18 },
+ /* 4892 */ { MAD_F(0x0511955b) /* 0.316792829 */, 18 },
+ /* 4893 */ { MAD_F(0x0511efe6) /* 0.316879175 */, 18 },
+ /* 4894 */ { MAD_F(0x05124a72) /* 0.316965527 */, 18 },
+ /* 4895 */ { MAD_F(0x0512a4ff) /* 0.317051885 */, 18 },
+
+ /* 4896 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 18 },
+ /* 4897 */ { MAD_F(0x05135a1f) /* 0.317224618 */, 18 },
+ /* 4898 */ { MAD_F(0x0513b4b1) /* 0.317310994 */, 18 },
+ /* 4899 */ { MAD_F(0x05140f45) /* 0.317397375 */, 18 },
+ /* 4900 */ { MAD_F(0x051469da) /* 0.317483762 */, 18 },
+ /* 4901 */ { MAD_F(0x0514c471) /* 0.317570155 */, 18 },
+ /* 4902 */ { MAD_F(0x05151f0a) /* 0.317656554 */, 18 },
+ /* 4903 */ { MAD_F(0x051579a4) /* 0.317742959 */, 18 },
+ /* 4904 */ { MAD_F(0x0515d440) /* 0.317829370 */, 18 },
+ /* 4905 */ { MAD_F(0x05162edd) /* 0.317915786 */, 18 },
+ /* 4906 */ { MAD_F(0x0516897c) /* 0.318002209 */, 18 },
+ /* 4907 */ { MAD_F(0x0516e41c) /* 0.318088637 */, 18 },
+ /* 4908 */ { MAD_F(0x05173ebe) /* 0.318175071 */, 18 },
+ /* 4909 */ { MAD_F(0x05179962) /* 0.318261511 */, 18 },
+ /* 4910 */ { MAD_F(0x0517f407) /* 0.318347957 */, 18 },
+ /* 4911 */ { MAD_F(0x05184eae) /* 0.318434409 */, 18 },
+
+ /* 4912 */ { MAD_F(0x0518a956) /* 0.318520867 */, 18 },
+ /* 4913 */ { MAD_F(0x05190400) /* 0.318607330 */, 18 },
+ /* 4914 */ { MAD_F(0x05195eab) /* 0.318693800 */, 18 },
+ /* 4915 */ { MAD_F(0x0519b958) /* 0.318780275 */, 18 },
+ /* 4916 */ { MAD_F(0x051a1407) /* 0.318866756 */, 18 },
+ /* 4917 */ { MAD_F(0x051a6eb7) /* 0.318953243 */, 18 },
+ /* 4918 */ { MAD_F(0x051ac969) /* 0.319039736 */, 18 },
+ /* 4919 */ { MAD_F(0x051b241c) /* 0.319126235 */, 18 },
+ /* 4920 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 18 },
+ /* 4921 */ { MAD_F(0x051bd987) /* 0.319299250 */, 18 },
+ /* 4922 */ { MAD_F(0x051c3440) /* 0.319385766 */, 18 },
+ /* 4923 */ { MAD_F(0x051c8ef9) /* 0.319472288 */, 18 },
+ /* 4924 */ { MAD_F(0x051ce9b4) /* 0.319558816 */, 18 },
+ /* 4925 */ { MAD_F(0x051d4471) /* 0.319645350 */, 18 },
+ /* 4926 */ { MAD_F(0x051d9f2f) /* 0.319731890 */, 18 },
+ /* 4927 */ { MAD_F(0x051df9ef) /* 0.319818435 */, 18 },
+
+ /* 4928 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 18 },
+ /* 4929 */ { MAD_F(0x051eaf74) /* 0.319991544 */, 18 },
+ /* 4930 */ { MAD_F(0x051f0a38) /* 0.320078107 */, 18 },
+ /* 4931 */ { MAD_F(0x051f64ff) /* 0.320164676 */, 18 },
+ /* 4932 */ { MAD_F(0x051fbfc6) /* 0.320251251 */, 18 },
+ /* 4933 */ { MAD_F(0x05201a90) /* 0.320337832 */, 18 },
+ /* 4934 */ { MAD_F(0x0520755b) /* 0.320424419 */, 18 },
+ /* 4935 */ { MAD_F(0x0520d027) /* 0.320511011 */, 18 },
+ /* 4936 */ { MAD_F(0x05212af5) /* 0.320597609 */, 18 },
+ /* 4937 */ { MAD_F(0x052185c5) /* 0.320684213 */, 18 },
+ /* 4938 */ { MAD_F(0x0521e096) /* 0.320770823 */, 18 },
+ /* 4939 */ { MAD_F(0x05223b69) /* 0.320857439 */, 18 },
+ /* 4940 */ { MAD_F(0x0522963d) /* 0.320944061 */, 18 },
+ /* 4941 */ { MAD_F(0x0522f113) /* 0.321030688 */, 18 },
+ /* 4942 */ { MAD_F(0x05234bea) /* 0.321117322 */, 18 },
+ /* 4943 */ { MAD_F(0x0523a6c3) /* 0.321203961 */, 18 },
+
+ /* 4944 */ { MAD_F(0x0524019e) /* 0.321290606 */, 18 },
+ /* 4945 */ { MAD_F(0x05245c7a) /* 0.321377257 */, 18 },
+ /* 4946 */ { MAD_F(0x0524b758) /* 0.321463913 */, 18 },
+ /* 4947 */ { MAD_F(0x05251237) /* 0.321550576 */, 18 },
+ /* 4948 */ { MAD_F(0x05256d18) /* 0.321637244 */, 18 },
+ /* 4949 */ { MAD_F(0x0525c7fb) /* 0.321723919 */, 18 },
+ /* 4950 */ { MAD_F(0x052622df) /* 0.321810599 */, 18 },
+ /* 4951 */ { MAD_F(0x05267dc4) /* 0.321897285 */, 18 },
+ /* 4952 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 18 },
+ /* 4953 */ { MAD_F(0x05273394) /* 0.322070674 */, 18 },
+ /* 4954 */ { MAD_F(0x05278e7e) /* 0.322157377 */, 18 },
+ /* 4955 */ { MAD_F(0x0527e96a) /* 0.322244087 */, 18 },
+ /* 4956 */ { MAD_F(0x05284457) /* 0.322330802 */, 18 },
+ /* 4957 */ { MAD_F(0x05289f46) /* 0.322417523 */, 18 },
+ /* 4958 */ { MAD_F(0x0528fa37) /* 0.322504249 */, 18 },
+ /* 4959 */ { MAD_F(0x05295529) /* 0.322590982 */, 18 },
+
+ /* 4960 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 18 },
+ /* 4961 */ { MAD_F(0x052a0b12) /* 0.322764465 */, 18 },
+ /* 4962 */ { MAD_F(0x052a6609) /* 0.322851215 */, 18 },
+ /* 4963 */ { MAD_F(0x052ac101) /* 0.322937971 */, 18 },
+ /* 4964 */ { MAD_F(0x052b1bfb) /* 0.323024732 */, 18 },
+ /* 4965 */ { MAD_F(0x052b76f7) /* 0.323111500 */, 18 },
+ /* 4966 */ { MAD_F(0x052bd1f4) /* 0.323198273 */, 18 },
+ /* 4967 */ { MAD_F(0x052c2cf2) /* 0.323285052 */, 18 },
+ /* 4968 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 18 },
+ /* 4969 */ { MAD_F(0x052ce2f4) /* 0.323458628 */, 18 },
+ /* 4970 */ { MAD_F(0x052d3df7) /* 0.323545425 */, 18 },
+ /* 4971 */ { MAD_F(0x052d98fc) /* 0.323632227 */, 18 },
+ /* 4972 */ { MAD_F(0x052df403) /* 0.323719036 */, 18 },
+ /* 4973 */ { MAD_F(0x052e4f0b) /* 0.323805850 */, 18 },
+ /* 4974 */ { MAD_F(0x052eaa14) /* 0.323892670 */, 18 },
+ /* 4975 */ { MAD_F(0x052f051f) /* 0.323979496 */, 18 },
+
+ /* 4976 */ { MAD_F(0x052f602c) /* 0.324066327 */, 18 },
+ /* 4977 */ { MAD_F(0x052fbb3a) /* 0.324153165 */, 18 },
+ /* 4978 */ { MAD_F(0x0530164a) /* 0.324240008 */, 18 },
+ /* 4979 */ { MAD_F(0x0530715b) /* 0.324326857 */, 18 },
+ /* 4980 */ { MAD_F(0x0530cc6e) /* 0.324413712 */, 18 },
+ /* 4981 */ { MAD_F(0x05312783) /* 0.324500572 */, 18 },
+ /* 4982 */ { MAD_F(0x05318299) /* 0.324587439 */, 18 },
+ /* 4983 */ { MAD_F(0x0531ddb0) /* 0.324674311 */, 18 },
+ /* 4984 */ { MAD_F(0x053238ca) /* 0.324761189 */, 18 },
+ /* 4985 */ { MAD_F(0x053293e4) /* 0.324848073 */, 18 },
+ /* 4986 */ { MAD_F(0x0532ef01) /* 0.324934963 */, 18 },
+ /* 4987 */ { MAD_F(0x05334a1e) /* 0.325021858 */, 18 },
+ /* 4988 */ { MAD_F(0x0533a53e) /* 0.325108760 */, 18 },
+ /* 4989 */ { MAD_F(0x0534005f) /* 0.325195667 */, 18 },
+ /* 4990 */ { MAD_F(0x05345b81) /* 0.325282580 */, 18 },
+ /* 4991 */ { MAD_F(0x0534b6a5) /* 0.325369498 */, 18 },
+
+ /* 4992 */ { MAD_F(0x053511cb) /* 0.325456423 */, 18 },
+ /* 4993 */ { MAD_F(0x05356cf2) /* 0.325543353 */, 18 },
+ /* 4994 */ { MAD_F(0x0535c81b) /* 0.325630290 */, 18 },
+ /* 4995 */ { MAD_F(0x05362345) /* 0.325717232 */, 18 },
+ /* 4996 */ { MAD_F(0x05367e71) /* 0.325804179 */, 18 },
+ /* 4997 */ { MAD_F(0x0536d99f) /* 0.325891133 */, 18 },
+ /* 4998 */ { MAD_F(0x053734ce) /* 0.325978092 */, 18 },
+ /* 4999 */ { MAD_F(0x05378ffe) /* 0.326065057 */, 18 },
+ /* 5000 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 18 },
+ /* 5001 */ { MAD_F(0x05384664) /* 0.326239005 */, 18 },
+ /* 5002 */ { MAD_F(0x0538a199) /* 0.326325988 */, 18 },
+ /* 5003 */ { MAD_F(0x0538fcd0) /* 0.326412976 */, 18 },
+ /* 5004 */ { MAD_F(0x05395808) /* 0.326499970 */, 18 },
+ /* 5005 */ { MAD_F(0x0539b342) /* 0.326586970 */, 18 },
+ /* 5006 */ { MAD_F(0x053a0e7d) /* 0.326673976 */, 18 },
+ /* 5007 */ { MAD_F(0x053a69ba) /* 0.326760988 */, 18 },
+
+ /* 5008 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 18 },
+ /* 5009 */ { MAD_F(0x053b2039) /* 0.326935028 */, 18 },
+ /* 5010 */ { MAD_F(0x053b7b7b) /* 0.327022057 */, 18 },
+ /* 5011 */ { MAD_F(0x053bd6be) /* 0.327109092 */, 18 },
+ /* 5012 */ { MAD_F(0x053c3203) /* 0.327196132 */, 18 },
+ /* 5013 */ { MAD_F(0x053c8d49) /* 0.327283178 */, 18 },
+ /* 5014 */ { MAD_F(0x053ce891) /* 0.327370231 */, 18 },
+ /* 5015 */ { MAD_F(0x053d43da) /* 0.327457288 */, 18 },
+ /* 5016 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 18 },
+ /* 5017 */ { MAD_F(0x053dfa72) /* 0.327631421 */, 18 },
+ /* 5018 */ { MAD_F(0x053e55c0) /* 0.327718497 */, 18 },
+ /* 5019 */ { MAD_F(0x053eb10f) /* 0.327805578 */, 18 },
+ /* 5020 */ { MAD_F(0x053f0c61) /* 0.327892665 */, 18 },
+ /* 5021 */ { MAD_F(0x053f67b3) /* 0.327979757 */, 18 },
+ /* 5022 */ { MAD_F(0x053fc308) /* 0.328066855 */, 18 },
+ /* 5023 */ { MAD_F(0x05401e5e) /* 0.328153960 */, 18 },
+
+ /* 5024 */ { MAD_F(0x054079b5) /* 0.328241070 */, 18 },
+ /* 5025 */ { MAD_F(0x0540d50e) /* 0.328328185 */, 18 },
+ /* 5026 */ { MAD_F(0x05413068) /* 0.328415307 */, 18 },
+ /* 5027 */ { MAD_F(0x05418bc4) /* 0.328502434 */, 18 },
+ /* 5028 */ { MAD_F(0x0541e722) /* 0.328589567 */, 18 },
+ /* 5029 */ { MAD_F(0x05424281) /* 0.328676706 */, 18 },
+ /* 5030 */ { MAD_F(0x05429de2) /* 0.328763850 */, 18 },
+ /* 5031 */ { MAD_F(0x0542f944) /* 0.328851001 */, 18 },
+ /* 5032 */ { MAD_F(0x054354a8) /* 0.328938157 */, 18 },
+ /* 5033 */ { MAD_F(0x0543b00d) /* 0.329025319 */, 18 },
+ /* 5034 */ { MAD_F(0x05440b74) /* 0.329112486 */, 18 },
+ /* 5035 */ { MAD_F(0x054466dd) /* 0.329199660 */, 18 },
+ /* 5036 */ { MAD_F(0x0544c247) /* 0.329286839 */, 18 },
+ /* 5037 */ { MAD_F(0x05451db2) /* 0.329374024 */, 18 },
+ /* 5038 */ { MAD_F(0x0545791f) /* 0.329461215 */, 18 },
+ /* 5039 */ { MAD_F(0x0545d48e) /* 0.329548411 */, 18 },
+
+ /* 5040 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 18 },
+ /* 5041 */ { MAD_F(0x05468b70) /* 0.329722822 */, 18 },
+ /* 5042 */ { MAD_F(0x0546e6e3) /* 0.329810036 */, 18 },
+ /* 5043 */ { MAD_F(0x05474258) /* 0.329897255 */, 18 },
+ /* 5044 */ { MAD_F(0x05479dce) /* 0.329984481 */, 18 },
+ /* 5045 */ { MAD_F(0x0547f946) /* 0.330071712 */, 18 },
+ /* 5046 */ { MAD_F(0x054854c0) /* 0.330158949 */, 18 },
+ /* 5047 */ { MAD_F(0x0548b03b) /* 0.330246191 */, 18 },
+ /* 5048 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 18 },
+ /* 5049 */ { MAD_F(0x05496735) /* 0.330420694 */, 18 },
+ /* 5050 */ { MAD_F(0x0549c2b5) /* 0.330507954 */, 18 },
+ /* 5051 */ { MAD_F(0x054a1e36) /* 0.330595220 */, 18 },
+ /* 5052 */ { MAD_F(0x054a79b9) /* 0.330682491 */, 18 },
+ /* 5053 */ { MAD_F(0x054ad53d) /* 0.330769768 */, 18 },
+ /* 5054 */ { MAD_F(0x054b30c3) /* 0.330857051 */, 18 },
+ /* 5055 */ { MAD_F(0x054b8c4b) /* 0.330944340 */, 18 },
+
+ /* 5056 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 18 },
+ /* 5057 */ { MAD_F(0x054c435e) /* 0.331118935 */, 18 },
+ /* 5058 */ { MAD_F(0x054c9eea) /* 0.331206241 */, 18 },
+ /* 5059 */ { MAD_F(0x054cfa78) /* 0.331293553 */, 18 },
+ /* 5060 */ { MAD_F(0x054d5607) /* 0.331380870 */, 18 },
+ /* 5061 */ { MAD_F(0x054db197) /* 0.331468193 */, 18 },
+ /* 5062 */ { MAD_F(0x054e0d2a) /* 0.331555522 */, 18 },
+ /* 5063 */ { MAD_F(0x054e68bd) /* 0.331642857 */, 18 },
+ /* 5064 */ { MAD_F(0x054ec453) /* 0.331730198 */, 18 },
+ /* 5065 */ { MAD_F(0x054f1fe9) /* 0.331817544 */, 18 },
+ /* 5066 */ { MAD_F(0x054f7b82) /* 0.331904896 */, 18 },
+ /* 5067 */ { MAD_F(0x054fd71c) /* 0.331992254 */, 18 },
+ /* 5068 */ { MAD_F(0x055032b7) /* 0.332079617 */, 18 },
+ /* 5069 */ { MAD_F(0x05508e54) /* 0.332166986 */, 18 },
+ /* 5070 */ { MAD_F(0x0550e9f3) /* 0.332254361 */, 18 },
+ /* 5071 */ { MAD_F(0x05514593) /* 0.332341742 */, 18 },
+
+ /* 5072 */ { MAD_F(0x0551a134) /* 0.332429129 */, 18 },
+ /* 5073 */ { MAD_F(0x0551fcd8) /* 0.332516521 */, 18 },
+ /* 5074 */ { MAD_F(0x0552587c) /* 0.332603919 */, 18 },
+ /* 5075 */ { MAD_F(0x0552b423) /* 0.332691323 */, 18 },
+ /* 5076 */ { MAD_F(0x05530fca) /* 0.332778732 */, 18 },
+ /* 5077 */ { MAD_F(0x05536b74) /* 0.332866147 */, 18 },
+ /* 5078 */ { MAD_F(0x0553c71f) /* 0.332953568 */, 18 },
+ /* 5079 */ { MAD_F(0x055422cb) /* 0.333040995 */, 18 },
+ /* 5080 */ { MAD_F(0x05547e79) /* 0.333128427 */, 18 },
+ /* 5081 */ { MAD_F(0x0554da29) /* 0.333215865 */, 18 },
+ /* 5082 */ { MAD_F(0x055535da) /* 0.333303309 */, 18 },
+ /* 5083 */ { MAD_F(0x0555918c) /* 0.333390759 */, 18 },
+ /* 5084 */ { MAD_F(0x0555ed40) /* 0.333478214 */, 18 },
+ /* 5085 */ { MAD_F(0x055648f6) /* 0.333565675 */, 18 },
+ /* 5086 */ { MAD_F(0x0556a4ad) /* 0.333653142 */, 18 },
+ /* 5087 */ { MAD_F(0x05570066) /* 0.333740615 */, 18 },
+
+ /* 5088 */ { MAD_F(0x05575c20) /* 0.333828093 */, 18 },
+ /* 5089 */ { MAD_F(0x0557b7dc) /* 0.333915577 */, 18 },
+ /* 5090 */ { MAD_F(0x05581399) /* 0.334003067 */, 18 },
+ /* 5091 */ { MAD_F(0x05586f58) /* 0.334090562 */, 18 },
+ /* 5092 */ { MAD_F(0x0558cb19) /* 0.334178063 */, 18 },
+ /* 5093 */ { MAD_F(0x055926db) /* 0.334265570 */, 18 },
+ /* 5094 */ { MAD_F(0x0559829e) /* 0.334353083 */, 18 },
+ /* 5095 */ { MAD_F(0x0559de63) /* 0.334440601 */, 18 },
+ /* 5096 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 18 },
+ /* 5097 */ { MAD_F(0x055a95f2) /* 0.334615655 */, 18 },
+ /* 5098 */ { MAD_F(0x055af1bb) /* 0.334703191 */, 18 },
+ /* 5099 */ { MAD_F(0x055b4d87) /* 0.334790732 */, 18 },
+ /* 5100 */ { MAD_F(0x055ba953) /* 0.334878279 */, 18 },
+ /* 5101 */ { MAD_F(0x055c0522) /* 0.334965832 */, 18 },
+ /* 5102 */ { MAD_F(0x055c60f1) /* 0.335053391 */, 18 },
+ /* 5103 */ { MAD_F(0x055cbcc3) /* 0.335140955 */, 18 },
+
+ /* 5104 */ { MAD_F(0x055d1896) /* 0.335228525 */, 18 },
+ /* 5105 */ { MAD_F(0x055d746a) /* 0.335316100 */, 18 },
+ /* 5106 */ { MAD_F(0x055dd040) /* 0.335403682 */, 18 },
+ /* 5107 */ { MAD_F(0x055e2c17) /* 0.335491269 */, 18 },
+ /* 5108 */ { MAD_F(0x055e87f0) /* 0.335578861 */, 18 },
+ /* 5109 */ { MAD_F(0x055ee3cb) /* 0.335666460 */, 18 },
+ /* 5110 */ { MAD_F(0x055f3fa7) /* 0.335754064 */, 18 },
+ /* 5111 */ { MAD_F(0x055f9b85) /* 0.335841674 */, 18 },
+ /* 5112 */ { MAD_F(0x055ff764) /* 0.335929290 */, 18 },
+ /* 5113 */ { MAD_F(0x05605344) /* 0.336016911 */, 18 },
+ /* 5114 */ { MAD_F(0x0560af27) /* 0.336104538 */, 18 },
+ /* 5115 */ { MAD_F(0x05610b0a) /* 0.336192171 */, 18 },
+ /* 5116 */ { MAD_F(0x056166f0) /* 0.336279809 */, 18 },
+ /* 5117 */ { MAD_F(0x0561c2d7) /* 0.336367453 */, 18 },
+ /* 5118 */ { MAD_F(0x05621ebf) /* 0.336455103 */, 18 },
+ /* 5119 */ { MAD_F(0x05627aa9) /* 0.336542759 */, 18 },
+
+ /* 5120 */ { MAD_F(0x0562d694) /* 0.336630420 */, 18 },
+ /* 5121 */ { MAD_F(0x05633281) /* 0.336718087 */, 18 },
+ /* 5122 */ { MAD_F(0x05638e70) /* 0.336805760 */, 18 },
+ /* 5123 */ { MAD_F(0x0563ea60) /* 0.336893439 */, 18 },
+ /* 5124 */ { MAD_F(0x05644651) /* 0.336981123 */, 18 },
+ /* 5125 */ { MAD_F(0x0564a244) /* 0.337068813 */, 18 },
+ /* 5126 */ { MAD_F(0x0564fe39) /* 0.337156508 */, 18 },
+ /* 5127 */ { MAD_F(0x05655a2f) /* 0.337244209 */, 18 },
+ /* 5128 */ { MAD_F(0x0565b627) /* 0.337331916 */, 18 },
+ /* 5129 */ { MAD_F(0x05661220) /* 0.337419629 */, 18 },
+ /* 5130 */ { MAD_F(0x05666e1a) /* 0.337507347 */, 18 },
+ /* 5131 */ { MAD_F(0x0566ca17) /* 0.337595071 */, 18 },
+ /* 5132 */ { MAD_F(0x05672614) /* 0.337682801 */, 18 },
+ /* 5133 */ { MAD_F(0x05678214) /* 0.337770537 */, 18 },
+ /* 5134 */ { MAD_F(0x0567de15) /* 0.337858278 */, 18 },
+ /* 5135 */ { MAD_F(0x05683a17) /* 0.337946025 */, 18 },
+
+ /* 5136 */ { MAD_F(0x0568961b) /* 0.338033777 */, 18 },
+ /* 5137 */ { MAD_F(0x0568f220) /* 0.338121535 */, 18 },
+ /* 5138 */ { MAD_F(0x05694e27) /* 0.338209299 */, 18 },
+ /* 5139 */ { MAD_F(0x0569aa30) /* 0.338297069 */, 18 },
+ /* 5140 */ { MAD_F(0x056a063a) /* 0.338384844 */, 18 },
+ /* 5141 */ { MAD_F(0x056a6245) /* 0.338472625 */, 18 },
+ /* 5142 */ { MAD_F(0x056abe52) /* 0.338560412 */, 18 },
+ /* 5143 */ { MAD_F(0x056b1a61) /* 0.338648204 */, 18 },
+ /* 5144 */ { MAD_F(0x056b7671) /* 0.338736002 */, 18 },
+ /* 5145 */ { MAD_F(0x056bd283) /* 0.338823806 */, 18 },
+ /* 5146 */ { MAD_F(0x056c2e96) /* 0.338911616 */, 18 },
+ /* 5147 */ { MAD_F(0x056c8aab) /* 0.338999431 */, 18 },
+ /* 5148 */ { MAD_F(0x056ce6c1) /* 0.339087252 */, 18 },
+ /* 5149 */ { MAD_F(0x056d42d9) /* 0.339175078 */, 18 },
+ /* 5150 */ { MAD_F(0x056d9ef2) /* 0.339262910 */, 18 },
+ /* 5151 */ { MAD_F(0x056dfb0d) /* 0.339350748 */, 18 },
+
+ /* 5152 */ { MAD_F(0x056e5729) /* 0.339438592 */, 18 },
+ /* 5153 */ { MAD_F(0x056eb347) /* 0.339526441 */, 18 },
+ /* 5154 */ { MAD_F(0x056f0f66) /* 0.339614296 */, 18 },
+ /* 5155 */ { MAD_F(0x056f6b87) /* 0.339702157 */, 18 },
+ /* 5156 */ { MAD_F(0x056fc7aa) /* 0.339790023 */, 18 },
+ /* 5157 */ { MAD_F(0x057023cd) /* 0.339877895 */, 18 },
+ /* 5158 */ { MAD_F(0x05707ff3) /* 0.339965773 */, 18 },
+ /* 5159 */ { MAD_F(0x0570dc1a) /* 0.340053656 */, 18 },
+ /* 5160 */ { MAD_F(0x05713843) /* 0.340141545 */, 18 },
+ /* 5161 */ { MAD_F(0x0571946d) /* 0.340229440 */, 18 },
+ /* 5162 */ { MAD_F(0x0571f098) /* 0.340317340 */, 18 },
+ /* 5163 */ { MAD_F(0x05724cc5) /* 0.340405246 */, 18 },
+ /* 5164 */ { MAD_F(0x0572a8f4) /* 0.340493158 */, 18 },
+ /* 5165 */ { MAD_F(0x05730524) /* 0.340581075 */, 18 },
+ /* 5166 */ { MAD_F(0x05736156) /* 0.340668999 */, 18 },
+ /* 5167 */ { MAD_F(0x0573bd89) /* 0.340756927 */, 18 },
+
+ /* 5168 */ { MAD_F(0x057419be) /* 0.340844862 */, 18 },
+ /* 5169 */ { MAD_F(0x057475f4) /* 0.340932802 */, 18 },
+ /* 5170 */ { MAD_F(0x0574d22c) /* 0.341020748 */, 18 },
+ /* 5171 */ { MAD_F(0x05752e65) /* 0.341108699 */, 18 },
+ /* 5172 */ { MAD_F(0x05758aa0) /* 0.341196656 */, 18 },
+ /* 5173 */ { MAD_F(0x0575e6dc) /* 0.341284619 */, 18 },
+ /* 5174 */ { MAD_F(0x0576431a) /* 0.341372587 */, 18 },
+ /* 5175 */ { MAD_F(0x05769f59) /* 0.341460562 */, 18 },
+ /* 5176 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 18 },
+ /* 5177 */ { MAD_F(0x057757dd) /* 0.341636527 */, 18 },
+ /* 5178 */ { MAD_F(0x0577b421) /* 0.341724518 */, 18 },
+ /* 5179 */ { MAD_F(0x05781066) /* 0.341812515 */, 18 },
+ /* 5180 */ { MAD_F(0x05786cad) /* 0.341900517 */, 18 },
+ /* 5181 */ { MAD_F(0x0578c8f5) /* 0.341988525 */, 18 },
+ /* 5182 */ { MAD_F(0x0579253f) /* 0.342076539 */, 18 },
+ /* 5183 */ { MAD_F(0x0579818b) /* 0.342164558 */, 18 },
+
+ /* 5184 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 18 },
+ /* 5185 */ { MAD_F(0x057a3a27) /* 0.342340614 */, 18 },
+ /* 5186 */ { MAD_F(0x057a9677) /* 0.342428651 */, 18 },
+ /* 5187 */ { MAD_F(0x057af2c8) /* 0.342516693 */, 18 },
+ /* 5188 */ { MAD_F(0x057b4f1c) /* 0.342604741 */, 18 },
+ /* 5189 */ { MAD_F(0x057bab70) /* 0.342692794 */, 18 },
+ /* 5190 */ { MAD_F(0x057c07c6) /* 0.342780853 */, 18 },
+ /* 5191 */ { MAD_F(0x057c641e) /* 0.342868918 */, 18 },
+ /* 5192 */ { MAD_F(0x057cc077) /* 0.342956988 */, 18 },
+ /* 5193 */ { MAD_F(0x057d1cd2) /* 0.343045064 */, 18 },
+ /* 5194 */ { MAD_F(0x057d792e) /* 0.343133146 */, 18 },
+ /* 5195 */ { MAD_F(0x057dd58c) /* 0.343221233 */, 18 },
+ /* 5196 */ { MAD_F(0x057e31eb) /* 0.343309326 */, 18 },
+ /* 5197 */ { MAD_F(0x057e8e4c) /* 0.343397425 */, 18 },
+ /* 5198 */ { MAD_F(0x057eeaae) /* 0.343485529 */, 18 },
+ /* 5199 */ { MAD_F(0x057f4712) /* 0.343573639 */, 18 },
+
+ /* 5200 */ { MAD_F(0x057fa378) /* 0.343661754 */, 18 },
+ /* 5201 */ { MAD_F(0x057fffde) /* 0.343749876 */, 18 },
+ /* 5202 */ { MAD_F(0x05805c47) /* 0.343838003 */, 18 },
+ /* 5203 */ { MAD_F(0x0580b8b1) /* 0.343926135 */, 18 },
+ /* 5204 */ { MAD_F(0x0581151c) /* 0.344014273 */, 18 },
+ /* 5205 */ { MAD_F(0x05817189) /* 0.344102417 */, 18 },
+ /* 5206 */ { MAD_F(0x0581cdf7) /* 0.344190566 */, 18 },
+ /* 5207 */ { MAD_F(0x05822a67) /* 0.344278722 */, 18 },
+ /* 5208 */ { MAD_F(0x058286d9) /* 0.344366882 */, 18 },
+ /* 5209 */ { MAD_F(0x0582e34c) /* 0.344455049 */, 18 },
+ /* 5210 */ { MAD_F(0x05833fc0) /* 0.344543221 */, 18 },
+ /* 5211 */ { MAD_F(0x05839c36) /* 0.344631398 */, 18 },
+ /* 5212 */ { MAD_F(0x0583f8ae) /* 0.344719582 */, 18 },
+ /* 5213 */ { MAD_F(0x05845527) /* 0.344807771 */, 18 },
+ /* 5214 */ { MAD_F(0x0584b1a1) /* 0.344895965 */, 18 },
+ /* 5215 */ { MAD_F(0x05850e1e) /* 0.344984165 */, 18 },
+
+ /* 5216 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 18 },
+ /* 5217 */ { MAD_F(0x0585c71a) /* 0.345160583 */, 18 },
+ /* 5218 */ { MAD_F(0x0586239b) /* 0.345248800 */, 18 },
+ /* 5219 */ { MAD_F(0x0586801d) /* 0.345337023 */, 18 },
+ /* 5220 */ { MAD_F(0x0586dca1) /* 0.345425251 */, 18 },
+ /* 5221 */ { MAD_F(0x05873926) /* 0.345513485 */, 18 },
+ /* 5222 */ { MAD_F(0x058795ac) /* 0.345601725 */, 18 },
+ /* 5223 */ { MAD_F(0x0587f235) /* 0.345689970 */, 18 },
+ /* 5224 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 18 },
+ /* 5225 */ { MAD_F(0x0588ab49) /* 0.345866478 */, 18 },
+ /* 5226 */ { MAD_F(0x058907d6) /* 0.345954740 */, 18 },
+ /* 5227 */ { MAD_F(0x05896464) /* 0.346043008 */, 18 },
+ /* 5228 */ { MAD_F(0x0589c0f4) /* 0.346131281 */, 18 },
+ /* 5229 */ { MAD_F(0x058a1d85) /* 0.346219560 */, 18 },
+ /* 5230 */ { MAD_F(0x058a7a18) /* 0.346307845 */, 18 },
+ /* 5231 */ { MAD_F(0x058ad6ac) /* 0.346396135 */, 18 },
+
+ /* 5232 */ { MAD_F(0x058b3342) /* 0.346484431 */, 18 },
+ /* 5233 */ { MAD_F(0x058b8fd9) /* 0.346572733 */, 18 },
+ /* 5234 */ { MAD_F(0x058bec72) /* 0.346661040 */, 18 },
+ /* 5235 */ { MAD_F(0x058c490c) /* 0.346749353 */, 18 },
+ /* 5236 */ { MAD_F(0x058ca5a8) /* 0.346837671 */, 18 },
+ /* 5237 */ { MAD_F(0x058d0246) /* 0.346925996 */, 18 },
+ /* 5238 */ { MAD_F(0x058d5ee4) /* 0.347014325 */, 18 },
+ /* 5239 */ { MAD_F(0x058dbb85) /* 0.347102661 */, 18 },
+ /* 5240 */ { MAD_F(0x058e1827) /* 0.347191002 */, 18 },
+ /* 5241 */ { MAD_F(0x058e74ca) /* 0.347279348 */, 18 },
+ /* 5242 */ { MAD_F(0x058ed16f) /* 0.347367700 */, 18 },
+ /* 5243 */ { MAD_F(0x058f2e15) /* 0.347456058 */, 18 },
+ /* 5244 */ { MAD_F(0x058f8abd) /* 0.347544422 */, 18 },
+ /* 5245 */ { MAD_F(0x058fe766) /* 0.347632791 */, 18 },
+ /* 5246 */ { MAD_F(0x05904411) /* 0.347721165 */, 18 },
+ /* 5247 */ { MAD_F(0x0590a0be) /* 0.347809546 */, 18 },
+
+ /* 5248 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 18 },
+ /* 5249 */ { MAD_F(0x05915a1b) /* 0.347986323 */, 18 },
+ /* 5250 */ { MAD_F(0x0591b6cc) /* 0.348074720 */, 18 },
+ /* 5251 */ { MAD_F(0x0592137e) /* 0.348163123 */, 18 },
+ /* 5252 */ { MAD_F(0x05927032) /* 0.348251531 */, 18 },
+ /* 5253 */ { MAD_F(0x0592cce8) /* 0.348339945 */, 18 },
+ /* 5254 */ { MAD_F(0x0593299f) /* 0.348428365 */, 18 },
+ /* 5255 */ { MAD_F(0x05938657) /* 0.348516790 */, 18 },
+ /* 5256 */ { MAD_F(0x0593e311) /* 0.348605221 */, 18 },
+ /* 5257 */ { MAD_F(0x05943fcd) /* 0.348693657 */, 18 },
+ /* 5258 */ { MAD_F(0x05949c8a) /* 0.348782099 */, 18 },
+ /* 5259 */ { MAD_F(0x0594f948) /* 0.348870547 */, 18 },
+ /* 5260 */ { MAD_F(0x05955608) /* 0.348959000 */, 18 },
+ /* 5261 */ { MAD_F(0x0595b2ca) /* 0.349047459 */, 18 },
+ /* 5262 */ { MAD_F(0x05960f8c) /* 0.349135923 */, 18 },
+ /* 5263 */ { MAD_F(0x05966c51) /* 0.349224393 */, 18 },
+
+ /* 5264 */ { MAD_F(0x0596c917) /* 0.349312869 */, 18 },
+ /* 5265 */ { MAD_F(0x059725de) /* 0.349401350 */, 18 },
+ /* 5266 */ { MAD_F(0x059782a7) /* 0.349489837 */, 18 },
+ /* 5267 */ { MAD_F(0x0597df72) /* 0.349578329 */, 18 },
+ /* 5268 */ { MAD_F(0x05983c3e) /* 0.349666827 */, 18 },
+ /* 5269 */ { MAD_F(0x0598990c) /* 0.349755331 */, 18 },
+ /* 5270 */ { MAD_F(0x0598f5db) /* 0.349843840 */, 18 },
+ /* 5271 */ { MAD_F(0x059952ab) /* 0.349932355 */, 18 },
+ /* 5272 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 18 },
+ /* 5273 */ { MAD_F(0x059a0c51) /* 0.350109402 */, 18 },
+ /* 5274 */ { MAD_F(0x059a6926) /* 0.350197933 */, 18 },
+ /* 5275 */ { MAD_F(0x059ac5fc) /* 0.350286470 */, 18 },
+ /* 5276 */ { MAD_F(0x059b22d4) /* 0.350375013 */, 18 },
+ /* 5277 */ { MAD_F(0x059b7fae) /* 0.350463562 */, 18 },
+ /* 5278 */ { MAD_F(0x059bdc89) /* 0.350552116 */, 18 },
+ /* 5279 */ { MAD_F(0x059c3965) /* 0.350640675 */, 18 },
+
+ /* 5280 */ { MAD_F(0x059c9643) /* 0.350729240 */, 18 },
+ /* 5281 */ { MAD_F(0x059cf323) /* 0.350817811 */, 18 },
+ /* 5282 */ { MAD_F(0x059d5004) /* 0.350906388 */, 18 },
+ /* 5283 */ { MAD_F(0x059dace6) /* 0.350994970 */, 18 },
+ /* 5284 */ { MAD_F(0x059e09cb) /* 0.351083557 */, 18 },
+ /* 5285 */ { MAD_F(0x059e66b0) /* 0.351172150 */, 18 },
+ /* 5286 */ { MAD_F(0x059ec397) /* 0.351260749 */, 18 },
+ /* 5287 */ { MAD_F(0x059f2080) /* 0.351349353 */, 18 },
+ /* 5288 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 18 },
+ /* 5289 */ { MAD_F(0x059fda55) /* 0.351526579 */, 18 },
+ /* 5290 */ { MAD_F(0x05a03742) /* 0.351615200 */, 18 },
+ /* 5291 */ { MAD_F(0x05a09431) /* 0.351703827 */, 18 },
+ /* 5292 */ { MAD_F(0x05a0f121) /* 0.351792459 */, 18 },
+ /* 5293 */ { MAD_F(0x05a14e12) /* 0.351881097 */, 18 },
+ /* 5294 */ { MAD_F(0x05a1ab05) /* 0.351969740 */, 18 },
+ /* 5295 */ { MAD_F(0x05a207fa) /* 0.352058389 */, 18 },
+
+ /* 5296 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 18 },
+ /* 5297 */ { MAD_F(0x05a2c1e7) /* 0.352235704 */, 18 },
+ /* 5298 */ { MAD_F(0x05a31ee1) /* 0.352324369 */, 18 },
+ /* 5299 */ { MAD_F(0x05a37bdb) /* 0.352413041 */, 18 },
+ /* 5300 */ { MAD_F(0x05a3d8d7) /* 0.352501718 */, 18 },
+ /* 5301 */ { MAD_F(0x05a435d5) /* 0.352590400 */, 18 },
+ /* 5302 */ { MAD_F(0x05a492d4) /* 0.352679088 */, 18 },
+ /* 5303 */ { MAD_F(0x05a4efd4) /* 0.352767782 */, 18 },
+ /* 5304 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 18 },
+ /* 5305 */ { MAD_F(0x05a5a9da) /* 0.352945186 */, 18 },
+ /* 5306 */ { MAD_F(0x05a606df) /* 0.353033896 */, 18 },
+ /* 5307 */ { MAD_F(0x05a663e5) /* 0.353122612 */, 18 },
+ /* 5308 */ { MAD_F(0x05a6c0ed) /* 0.353211333 */, 18 },
+ /* 5309 */ { MAD_F(0x05a71df7) /* 0.353300061 */, 18 },
+ /* 5310 */ { MAD_F(0x05a77b02) /* 0.353388793 */, 18 },
+ /* 5311 */ { MAD_F(0x05a7d80e) /* 0.353477531 */, 18 },
+
+ /* 5312 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 18 },
+ /* 5313 */ { MAD_F(0x05a8922c) /* 0.353655024 */, 18 },
+ /* 5314 */ { MAD_F(0x05a8ef3c) /* 0.353743779 */, 18 },
+ /* 5315 */ { MAD_F(0x05a94c4f) /* 0.353832540 */, 18 },
+ /* 5316 */ { MAD_F(0x05a9a963) /* 0.353921306 */, 18 },
+ /* 5317 */ { MAD_F(0x05aa0678) /* 0.354010077 */, 18 },
+ /* 5318 */ { MAD_F(0x05aa638f) /* 0.354098855 */, 18 },
+ /* 5319 */ { MAD_F(0x05aac0a8) /* 0.354187637 */, 18 },
+ /* 5320 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 18 },
+ /* 5321 */ { MAD_F(0x05ab7add) /* 0.354365220 */, 18 },
+ /* 5322 */ { MAD_F(0x05abd7fa) /* 0.354454019 */, 18 },
+ /* 5323 */ { MAD_F(0x05ac3518) /* 0.354542824 */, 18 },
+ /* 5324 */ { MAD_F(0x05ac9238) /* 0.354631635 */, 18 },
+ /* 5325 */ { MAD_F(0x05acef5a) /* 0.354720451 */, 18 },
+ /* 5326 */ { MAD_F(0x05ad4c7d) /* 0.354809272 */, 18 },
+ /* 5327 */ { MAD_F(0x05ada9a1) /* 0.354898100 */, 18 },
+
+ /* 5328 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 18 },
+ /* 5329 */ { MAD_F(0x05ae63ee) /* 0.355075771 */, 18 },
+ /* 5330 */ { MAD_F(0x05aec117) /* 0.355164615 */, 18 },
+ /* 5331 */ { MAD_F(0x05af1e41) /* 0.355253464 */, 18 },
+ /* 5332 */ { MAD_F(0x05af7b6d) /* 0.355342319 */, 18 },
+ /* 5333 */ { MAD_F(0x05afd89b) /* 0.355431180 */, 18 },
+ /* 5334 */ { MAD_F(0x05b035c9) /* 0.355520046 */, 18 },
+ /* 5335 */ { MAD_F(0x05b092fa) /* 0.355608917 */, 18 },
+ /* 5336 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 18 },
+ /* 5337 */ { MAD_F(0x05b14d5f) /* 0.355786677 */, 18 },
+ /* 5338 */ { MAD_F(0x05b1aa94) /* 0.355875566 */, 18 },
+ /* 5339 */ { MAD_F(0x05b207ca) /* 0.355964460 */, 18 },
+ /* 5340 */ { MAD_F(0x05b26502) /* 0.356053359 */, 18 },
+ /* 5341 */ { MAD_F(0x05b2c23b) /* 0.356142264 */, 18 },
+ /* 5342 */ { MAD_F(0x05b31f76) /* 0.356231175 */, 18 },
+ /* 5343 */ { MAD_F(0x05b37cb2) /* 0.356320091 */, 18 },
+
+ /* 5344 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 18 },
+ /* 5345 */ { MAD_F(0x05b4372f) /* 0.356497940 */, 18 },
+ /* 5346 */ { MAD_F(0x05b4946f) /* 0.356586872 */, 18 },
+ /* 5347 */ { MAD_F(0x05b4f1b2) /* 0.356675811 */, 18 },
+ /* 5348 */ { MAD_F(0x05b54ef5) /* 0.356764754 */, 18 },
+ /* 5349 */ { MAD_F(0x05b5ac3a) /* 0.356853704 */, 18 },
+ /* 5350 */ { MAD_F(0x05b60981) /* 0.356942659 */, 18 },
+ /* 5351 */ { MAD_F(0x05b666c9) /* 0.357031619 */, 18 },
+ /* 5352 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 18 },
+ /* 5353 */ { MAD_F(0x05b7215e) /* 0.357209557 */, 18 },
+ /* 5354 */ { MAD_F(0x05b77eab) /* 0.357298534 */, 18 },
+ /* 5355 */ { MAD_F(0x05b7dbf9) /* 0.357387516 */, 18 },
+ /* 5356 */ { MAD_F(0x05b83948) /* 0.357476504 */, 18 },
+ /* 5357 */ { MAD_F(0x05b89699) /* 0.357565498 */, 18 },
+ /* 5358 */ { MAD_F(0x05b8f3ec) /* 0.357654497 */, 18 },
+ /* 5359 */ { MAD_F(0x05b95140) /* 0.357743502 */, 18 },
+
+ /* 5360 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 18 },
+ /* 5361 */ { MAD_F(0x05ba0bec) /* 0.357921528 */, 18 },
+ /* 5362 */ { MAD_F(0x05ba6945) /* 0.358010550 */, 18 },
+ /* 5363 */ { MAD_F(0x05bac69f) /* 0.358099576 */, 18 },
+ /* 5364 */ { MAD_F(0x05bb23fa) /* 0.358188609 */, 18 },
+ /* 5365 */ { MAD_F(0x05bb8157) /* 0.358277647 */, 18 },
+ /* 5366 */ { MAD_F(0x05bbdeb6) /* 0.358366690 */, 18 },
+ /* 5367 */ { MAD_F(0x05bc3c16) /* 0.358455739 */, 18 },
+ /* 5368 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 18 },
+ /* 5369 */ { MAD_F(0x05bcf6da) /* 0.358633854 */, 18 },
+ /* 5370 */ { MAD_F(0x05bd543e) /* 0.358722920 */, 18 },
+ /* 5371 */ { MAD_F(0x05bdb1a4) /* 0.358811991 */, 18 },
+ /* 5372 */ { MAD_F(0x05be0f0b) /* 0.358901067 */, 18 },
+ /* 5373 */ { MAD_F(0x05be6c74) /* 0.358990150 */, 18 },
+ /* 5374 */ { MAD_F(0x05bec9df) /* 0.359079237 */, 18 },
+ /* 5375 */ { MAD_F(0x05bf274a) /* 0.359168331 */, 18 },
+
+ /* 5376 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 18 },
+ /* 5377 */ { MAD_F(0x05bfe226) /* 0.359346534 */, 18 },
+ /* 5378 */ { MAD_F(0x05c03f97) /* 0.359435644 */, 18 },
+ /* 5379 */ { MAD_F(0x05c09d08) /* 0.359524759 */, 18 },
+ /* 5380 */ { MAD_F(0x05c0fa7c) /* 0.359613880 */, 18 },
+ /* 5381 */ { MAD_F(0x05c157f0) /* 0.359703006 */, 18 },
+ /* 5382 */ { MAD_F(0x05c1b566) /* 0.359792138 */, 18 },
+ /* 5383 */ { MAD_F(0x05c212de) /* 0.359881276 */, 18 },
+ /* 5384 */ { MAD_F(0x05c27057) /* 0.359970419 */, 18 },
+ /* 5385 */ { MAD_F(0x05c2cdd2) /* 0.360059567 */, 18 },
+ /* 5386 */ { MAD_F(0x05c32b4e) /* 0.360148721 */, 18 },
+ /* 5387 */ { MAD_F(0x05c388cb) /* 0.360237881 */, 18 },
+ /* 5388 */ { MAD_F(0x05c3e64b) /* 0.360327046 */, 18 },
+ /* 5389 */ { MAD_F(0x05c443cb) /* 0.360416216 */, 18 },
+ /* 5390 */ { MAD_F(0x05c4a14d) /* 0.360505392 */, 18 },
+ /* 5391 */ { MAD_F(0x05c4fed1) /* 0.360594574 */, 18 },
+
+ /* 5392 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 18 },
+ /* 5393 */ { MAD_F(0x05c5b9dc) /* 0.360772953 */, 18 },
+ /* 5394 */ { MAD_F(0x05c61764) /* 0.360862152 */, 18 },
+ /* 5395 */ { MAD_F(0x05c674ed) /* 0.360951355 */, 18 },
+ /* 5396 */ { MAD_F(0x05c6d278) /* 0.361040564 */, 18 },
+ /* 5397 */ { MAD_F(0x05c73005) /* 0.361129779 */, 18 },
+ /* 5398 */ { MAD_F(0x05c78d93) /* 0.361218999 */, 18 },
+ /* 5399 */ { MAD_F(0x05c7eb22) /* 0.361308225 */, 18 },
+ /* 5400 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 18 },
+ /* 5401 */ { MAD_F(0x05c8a645) /* 0.361486693 */, 18 },
+ /* 5402 */ { MAD_F(0x05c903d9) /* 0.361575935 */, 18 },
+ /* 5403 */ { MAD_F(0x05c9616e) /* 0.361665183 */, 18 },
+ /* 5404 */ { MAD_F(0x05c9bf05) /* 0.361754436 */, 18 },
+ /* 5405 */ { MAD_F(0x05ca1c9d) /* 0.361843695 */, 18 },
+ /* 5406 */ { MAD_F(0x05ca7a37) /* 0.361932959 */, 18 },
+ /* 5407 */ { MAD_F(0x05cad7d2) /* 0.362022229 */, 18 },
+
+ /* 5408 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 18 },
+ /* 5409 */ { MAD_F(0x05cb930d) /* 0.362200785 */, 18 },
+ /* 5410 */ { MAD_F(0x05cbf0ac) /* 0.362290071 */, 18 },
+ /* 5411 */ { MAD_F(0x05cc4e4d) /* 0.362379362 */, 18 },
+ /* 5412 */ { MAD_F(0x05ccabf0) /* 0.362468660 */, 18 },
+ /* 5413 */ { MAD_F(0x05cd0994) /* 0.362557962 */, 18 },
+ /* 5414 */ { MAD_F(0x05cd6739) /* 0.362647271 */, 18 },
+ /* 5415 */ { MAD_F(0x05cdc4e0) /* 0.362736584 */, 18 },
+ /* 5416 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 18 },
+ /* 5417 */ { MAD_F(0x05ce8033) /* 0.362915228 */, 18 },
+ /* 5418 */ { MAD_F(0x05ceddde) /* 0.363004559 */, 18 },
+ /* 5419 */ { MAD_F(0x05cf3b8b) /* 0.363093894 */, 18 },
+ /* 5420 */ { MAD_F(0x05cf9939) /* 0.363183236 */, 18 },
+ /* 5421 */ { MAD_F(0x05cff6e9) /* 0.363272582 */, 18 },
+ /* 5422 */ { MAD_F(0x05d0549a) /* 0.363361935 */, 18 },
+ /* 5423 */ { MAD_F(0x05d0b24d) /* 0.363451292 */, 18 },
+
+ /* 5424 */ { MAD_F(0x05d11001) /* 0.363540655 */, 18 },
+ /* 5425 */ { MAD_F(0x05d16db7) /* 0.363630024 */, 18 },
+ /* 5426 */ { MAD_F(0x05d1cb6e) /* 0.363719398 */, 18 },
+ /* 5427 */ { MAD_F(0x05d22927) /* 0.363808778 */, 18 },
+ /* 5428 */ { MAD_F(0x05d286e1) /* 0.363898163 */, 18 },
+ /* 5429 */ { MAD_F(0x05d2e49d) /* 0.363987554 */, 18 },
+ /* 5430 */ { MAD_F(0x05d3425a) /* 0.364076950 */, 18 },
+ /* 5431 */ { MAD_F(0x05d3a018) /* 0.364166352 */, 18 },
+ /* 5432 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 18 },
+ /* 5433 */ { MAD_F(0x05d45b9a) /* 0.364345171 */, 18 },
+ /* 5434 */ { MAD_F(0x05d4b95d) /* 0.364434589 */, 18 },
+ /* 5435 */ { MAD_F(0x05d51721) /* 0.364524013 */, 18 },
+ /* 5436 */ { MAD_F(0x05d574e7) /* 0.364613442 */, 18 },
+ /* 5437 */ { MAD_F(0x05d5d2af) /* 0.364702877 */, 18 },
+ /* 5438 */ { MAD_F(0x05d63078) /* 0.364792317 */, 18 },
+ /* 5439 */ { MAD_F(0x05d68e42) /* 0.364881762 */, 18 },
+
+ /* 5440 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 18 },
+ /* 5441 */ { MAD_F(0x05d749db) /* 0.365060669 */, 18 },
+ /* 5442 */ { MAD_F(0x05d7a7aa) /* 0.365150131 */, 18 },
+ /* 5443 */ { MAD_F(0x05d8057a) /* 0.365239599 */, 18 },
+ /* 5444 */ { MAD_F(0x05d8634c) /* 0.365329072 */, 18 },
+ /* 5445 */ { MAD_F(0x05d8c11f) /* 0.365418550 */, 18 },
+ /* 5446 */ { MAD_F(0x05d91ef4) /* 0.365508034 */, 18 },
+ /* 5447 */ { MAD_F(0x05d97cca) /* 0.365597523 */, 18 },
+ /* 5448 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 18 },
+ /* 5449 */ { MAD_F(0x05da387a) /* 0.365776518 */, 18 },
+ /* 5450 */ { MAD_F(0x05da9655) /* 0.365866024 */, 18 },
+ /* 5451 */ { MAD_F(0x05daf431) /* 0.365955536 */, 18 },
+ /* 5452 */ { MAD_F(0x05db520e) /* 0.366045052 */, 18 },
+ /* 5453 */ { MAD_F(0x05dbafed) /* 0.366134574 */, 18 },
+ /* 5454 */ { MAD_F(0x05dc0dce) /* 0.366224102 */, 18 },
+ /* 5455 */ { MAD_F(0x05dc6baf) /* 0.366313635 */, 18 },
+
+ /* 5456 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 18 },
+ /* 5457 */ { MAD_F(0x05dd2778) /* 0.366492718 */, 18 },
+ /* 5458 */ { MAD_F(0x05dd855e) /* 0.366582267 */, 18 },
+ /* 5459 */ { MAD_F(0x05dde346) /* 0.366671822 */, 18 },
+ /* 5460 */ { MAD_F(0x05de412f) /* 0.366761383 */, 18 },
+ /* 5461 */ { MAD_F(0x05de9f1a) /* 0.366850949 */, 18 },
+ /* 5462 */ { MAD_F(0x05defd06) /* 0.366940520 */, 18 },
+ /* 5463 */ { MAD_F(0x05df5af3) /* 0.367030097 */, 18 },
+ /* 5464 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 18 },
+ /* 5465 */ { MAD_F(0x05e016d3) /* 0.367209267 */, 18 },
+ /* 5466 */ { MAD_F(0x05e074c5) /* 0.367298861 */, 18 },
+ /* 5467 */ { MAD_F(0x05e0d2b8) /* 0.367388459 */, 18 },
+ /* 5468 */ { MAD_F(0x05e130ad) /* 0.367478064 */, 18 },
+ /* 5469 */ { MAD_F(0x05e18ea4) /* 0.367567673 */, 18 },
+ /* 5470 */ { MAD_F(0x05e1ec9c) /* 0.367657288 */, 18 },
+ /* 5471 */ { MAD_F(0x05e24a95) /* 0.367746909 */, 18 },
+
+ /* 5472 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 18 },
+ /* 5473 */ { MAD_F(0x05e3068c) /* 0.367926167 */, 18 },
+ /* 5474 */ { MAD_F(0x05e3648a) /* 0.368015804 */, 18 },
+ /* 5475 */ { MAD_F(0x05e3c289) /* 0.368105446 */, 18 },
+ /* 5476 */ { MAD_F(0x05e4208a) /* 0.368195094 */, 18 },
+ /* 5477 */ { MAD_F(0x05e47e8c) /* 0.368284747 */, 18 },
+ /* 5478 */ { MAD_F(0x05e4dc8f) /* 0.368374406 */, 18 },
+ /* 5479 */ { MAD_F(0x05e53a94) /* 0.368464070 */, 18 },
+ /* 5480 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 18 },
+ /* 5481 */ { MAD_F(0x05e5f6a3) /* 0.368643415 */, 18 },
+ /* 5482 */ { MAD_F(0x05e654ac) /* 0.368733096 */, 18 },
+ /* 5483 */ { MAD_F(0x05e6b2b7) /* 0.368822782 */, 18 },
+ /* 5484 */ { MAD_F(0x05e710c4) /* 0.368912473 */, 18 },
+ /* 5485 */ { MAD_F(0x05e76ed2) /* 0.369002170 */, 18 },
+ /* 5486 */ { MAD_F(0x05e7cce1) /* 0.369091873 */, 18 },
+ /* 5487 */ { MAD_F(0x05e82af2) /* 0.369181581 */, 18 },
+
+ /* 5488 */ { MAD_F(0x05e88904) /* 0.369271294 */, 18 },
+ /* 5489 */ { MAD_F(0x05e8e718) /* 0.369361013 */, 18 },
+ /* 5490 */ { MAD_F(0x05e9452d) /* 0.369450737 */, 18 },
+ /* 5491 */ { MAD_F(0x05e9a343) /* 0.369540467 */, 18 },
+ /* 5492 */ { MAD_F(0x05ea015c) /* 0.369630202 */, 18 },
+ /* 5493 */ { MAD_F(0x05ea5f75) /* 0.369719942 */, 18 },
+ /* 5494 */ { MAD_F(0x05eabd90) /* 0.369809688 */, 18 },
+ /* 5495 */ { MAD_F(0x05eb1bad) /* 0.369899440 */, 18 },
+ /* 5496 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 18 },
+ /* 5497 */ { MAD_F(0x05ebd7ea) /* 0.370078959 */, 18 },
+ /* 5498 */ { MAD_F(0x05ec360b) /* 0.370168727 */, 18 },
+ /* 5499 */ { MAD_F(0x05ec942d) /* 0.370258500 */, 18 },
+ /* 5500 */ { MAD_F(0x05ecf251) /* 0.370348279 */, 18 },
+ /* 5501 */ { MAD_F(0x05ed5076) /* 0.370438063 */, 18 },
+ /* 5502 */ { MAD_F(0x05edae9d) /* 0.370527853 */, 18 },
+ /* 5503 */ { MAD_F(0x05ee0cc5) /* 0.370617648 */, 18 },
+
+ /* 5504 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 18 },
+ /* 5505 */ { MAD_F(0x05eec91a) /* 0.370797254 */, 18 },
+ /* 5506 */ { MAD_F(0x05ef2746) /* 0.370887065 */, 18 },
+ /* 5507 */ { MAD_F(0x05ef8574) /* 0.370976882 */, 18 },
+ /* 5508 */ { MAD_F(0x05efe3a4) /* 0.371066704 */, 18 },
+ /* 5509 */ { MAD_F(0x05f041d5) /* 0.371156532 */, 18 },
+ /* 5510 */ { MAD_F(0x05f0a007) /* 0.371246365 */, 18 },
+ /* 5511 */ { MAD_F(0x05f0fe3b) /* 0.371336203 */, 18 },
+ /* 5512 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 18 },
+ /* 5513 */ { MAD_F(0x05f1baa7) /* 0.371515897 */, 18 },
+ /* 5514 */ { MAD_F(0x05f218df) /* 0.371605751 */, 18 },
+ /* 5515 */ { MAD_F(0x05f27719) /* 0.371695612 */, 18 },
+ /* 5516 */ { MAD_F(0x05f2d554) /* 0.371785477 */, 18 },
+ /* 5517 */ { MAD_F(0x05f33390) /* 0.371875348 */, 18 },
+ /* 5518 */ { MAD_F(0x05f391cf) /* 0.371965225 */, 18 },
+ /* 5519 */ { MAD_F(0x05f3f00e) /* 0.372055107 */, 18 },
+
+ /* 5520 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 18 },
+ /* 5521 */ { MAD_F(0x05f4ac91) /* 0.372234887 */, 18 },
+ /* 5522 */ { MAD_F(0x05f50ad5) /* 0.372324785 */, 18 },
+ /* 5523 */ { MAD_F(0x05f5691b) /* 0.372414689 */, 18 },
+ /* 5524 */ { MAD_F(0x05f5c761) /* 0.372504598 */, 18 },
+ /* 5525 */ { MAD_F(0x05f625aa) /* 0.372594513 */, 18 },
+ /* 5526 */ { MAD_F(0x05f683f3) /* 0.372684433 */, 18 },
+ /* 5527 */ { MAD_F(0x05f6e23f) /* 0.372774358 */, 18 },
+ /* 5528 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 18 },
+ /* 5529 */ { MAD_F(0x05f79ed9) /* 0.372954225 */, 18 },
+ /* 5530 */ { MAD_F(0x05f7fd29) /* 0.373044167 */, 18 },
+ /* 5531 */ { MAD_F(0x05f85b7a) /* 0.373134114 */, 18 },
+ /* 5532 */ { MAD_F(0x05f8b9cc) /* 0.373224066 */, 18 },
+ /* 5533 */ { MAD_F(0x05f91820) /* 0.373314024 */, 18 },
+ /* 5534 */ { MAD_F(0x05f97675) /* 0.373403987 */, 18 },
+ /* 5535 */ { MAD_F(0x05f9d4cc) /* 0.373493956 */, 18 },
+
+ /* 5536 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 18 },
+ /* 5537 */ { MAD_F(0x05fa917e) /* 0.373673910 */, 18 },
+ /* 5538 */ { MAD_F(0x05faefd9) /* 0.373763895 */, 18 },
+ /* 5539 */ { MAD_F(0x05fb4e36) /* 0.373853885 */, 18 },
+ /* 5540 */ { MAD_F(0x05fbac94) /* 0.373943881 */, 18 },
+ /* 5541 */ { MAD_F(0x05fc0af3) /* 0.374033882 */, 18 },
+ /* 5542 */ { MAD_F(0x05fc6954) /* 0.374123889 */, 18 },
+ /* 5543 */ { MAD_F(0x05fcc7b7) /* 0.374213901 */, 18 },
+ /* 5544 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 18 },
+ /* 5545 */ { MAD_F(0x05fd8480) /* 0.374393941 */, 18 },
+ /* 5546 */ { MAD_F(0x05fde2e7) /* 0.374483970 */, 18 },
+ /* 5547 */ { MAD_F(0x05fe414f) /* 0.374574003 */, 18 },
+ /* 5548 */ { MAD_F(0x05fe9fb9) /* 0.374664042 */, 18 },
+ /* 5549 */ { MAD_F(0x05fefe24) /* 0.374754087 */, 18 },
+ /* 5550 */ { MAD_F(0x05ff5c91) /* 0.374844137 */, 18 },
+ /* 5551 */ { MAD_F(0x05ffbaff) /* 0.374934192 */, 18 },
+
+ /* 5552 */ { MAD_F(0x0600196e) /* 0.375024253 */, 18 },
+ /* 5553 */ { MAD_F(0x060077df) /* 0.375114319 */, 18 },
+ /* 5554 */ { MAD_F(0x0600d651) /* 0.375204391 */, 18 },
+ /* 5555 */ { MAD_F(0x060134c5) /* 0.375294468 */, 18 },
+ /* 5556 */ { MAD_F(0x0601933b) /* 0.375384550 */, 18 },
+ /* 5557 */ { MAD_F(0x0601f1b1) /* 0.375474638 */, 18 },
+ /* 5558 */ { MAD_F(0x0602502a) /* 0.375564731 */, 18 },
+ /* 5559 */ { MAD_F(0x0602aea3) /* 0.375654830 */, 18 },
+ /* 5560 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 18 },
+ /* 5561 */ { MAD_F(0x06036b9b) /* 0.375835043 */, 18 },
+ /* 5562 */ { MAD_F(0x0603ca19) /* 0.375925158 */, 18 },
+ /* 5563 */ { MAD_F(0x06042898) /* 0.376015278 */, 18 },
+ /* 5564 */ { MAD_F(0x06048719) /* 0.376105404 */, 18 },
+ /* 5565 */ { MAD_F(0x0604e59c) /* 0.376195535 */, 18 },
+ /* 5566 */ { MAD_F(0x0605441f) /* 0.376285671 */, 18 },
+ /* 5567 */ { MAD_F(0x0605a2a5) /* 0.376375813 */, 18 },
+
+ /* 5568 */ { MAD_F(0x0606012b) /* 0.376465960 */, 18 },
+ /* 5569 */ { MAD_F(0x06065fb4) /* 0.376556113 */, 18 },
+ /* 5570 */ { MAD_F(0x0606be3d) /* 0.376646271 */, 18 },
+ /* 5571 */ { MAD_F(0x06071cc8) /* 0.376736434 */, 18 },
+ /* 5572 */ { MAD_F(0x06077b55) /* 0.376826603 */, 18 },
+ /* 5573 */ { MAD_F(0x0607d9e3) /* 0.376916777 */, 18 },
+ /* 5574 */ { MAD_F(0x06083872) /* 0.377006957 */, 18 },
+ /* 5575 */ { MAD_F(0x06089703) /* 0.377097141 */, 18 },
+ /* 5576 */ { MAD_F(0x0608f595) /* 0.377187332 */, 18 },
+ /* 5577 */ { MAD_F(0x06095429) /* 0.377277528 */, 18 },
+ /* 5578 */ { MAD_F(0x0609b2be) /* 0.377367729 */, 18 },
+ /* 5579 */ { MAD_F(0x060a1155) /* 0.377457935 */, 18 },
+ /* 5580 */ { MAD_F(0x060a6fed) /* 0.377548147 */, 18 },
+ /* 5581 */ { MAD_F(0x060ace86) /* 0.377638364 */, 18 },
+ /* 5582 */ { MAD_F(0x060b2d21) /* 0.377728587 */, 18 },
+ /* 5583 */ { MAD_F(0x060b8bbe) /* 0.377818815 */, 18 },
+
+ /* 5584 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 18 },
+ /* 5585 */ { MAD_F(0x060c48fb) /* 0.377999288 */, 18 },
+ /* 5586 */ { MAD_F(0x060ca79c) /* 0.378089532 */, 18 },
+ /* 5587 */ { MAD_F(0x060d063e) /* 0.378179781 */, 18 },
+ /* 5588 */ { MAD_F(0x060d64e1) /* 0.378270036 */, 18 },
+ /* 5589 */ { MAD_F(0x060dc387) /* 0.378360297 */, 18 },
+ /* 5590 */ { MAD_F(0x060e222d) /* 0.378450563 */, 18 },
+ /* 5591 */ { MAD_F(0x060e80d5) /* 0.378540834 */, 18 },
+ /* 5592 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 18 },
+ /* 5593 */ { MAD_F(0x060f3e29) /* 0.378721392 */, 18 },
+ /* 5594 */ { MAD_F(0x060f9cd6) /* 0.378811680 */, 18 },
+ /* 5595 */ { MAD_F(0x060ffb83) /* 0.378901972 */, 18 },
+ /* 5596 */ { MAD_F(0x06105a33) /* 0.378992270 */, 18 },
+ /* 5597 */ { MAD_F(0x0610b8e3) /* 0.379082574 */, 18 },
+ /* 5598 */ { MAD_F(0x06111795) /* 0.379172883 */, 18 },
+ /* 5599 */ { MAD_F(0x06117649) /* 0.379263197 */, 18 },
+
+ /* 5600 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 18 },
+ /* 5601 */ { MAD_F(0x061233b4) /* 0.379443841 */, 18 },
+ /* 5602 */ { MAD_F(0x0612926c) /* 0.379534172 */, 18 },
+ /* 5603 */ { MAD_F(0x0612f125) /* 0.379624507 */, 18 },
+ /* 5604 */ { MAD_F(0x06134fe0) /* 0.379714848 */, 18 },
+ /* 5605 */ { MAD_F(0x0613ae9c) /* 0.379805195 */, 18 },
+ /* 5606 */ { MAD_F(0x06140d5a) /* 0.379895547 */, 18 },
+ /* 5607 */ { MAD_F(0x06146c19) /* 0.379985904 */, 18 },
+ /* 5608 */ { MAD_F(0x0614cada) /* 0.380076266 */, 18 },
+ /* 5609 */ { MAD_F(0x0615299c) /* 0.380166634 */, 18 },
+ /* 5610 */ { MAD_F(0x0615885f) /* 0.380257008 */, 18 },
+ /* 5611 */ { MAD_F(0x0615e724) /* 0.380347386 */, 18 },
+ /* 5612 */ { MAD_F(0x061645ea) /* 0.380437770 */, 18 },
+ /* 5613 */ { MAD_F(0x0616a4b2) /* 0.380528160 */, 18 },
+ /* 5614 */ { MAD_F(0x0617037b) /* 0.380618555 */, 18 },
+ /* 5615 */ { MAD_F(0x06176246) /* 0.380708955 */, 18 },
+
+ /* 5616 */ { MAD_F(0x0617c112) /* 0.380799360 */, 18 },
+ /* 5617 */ { MAD_F(0x06181fdf) /* 0.380889771 */, 18 },
+ /* 5618 */ { MAD_F(0x06187eae) /* 0.380980187 */, 18 },
+ /* 5619 */ { MAD_F(0x0618dd7e) /* 0.381070609 */, 18 },
+ /* 5620 */ { MAD_F(0x06193c50) /* 0.381161036 */, 18 },
+ /* 5621 */ { MAD_F(0x06199b24) /* 0.381251468 */, 18 },
+ /* 5622 */ { MAD_F(0x0619f9f8) /* 0.381341906 */, 18 },
+ /* 5623 */ { MAD_F(0x061a58ce) /* 0.381432349 */, 18 },
+ /* 5624 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 18 },
+ /* 5625 */ { MAD_F(0x061b167f) /* 0.381613251 */, 18 },
+ /* 5626 */ { MAD_F(0x061b7559) /* 0.381703711 */, 18 },
+ /* 5627 */ { MAD_F(0x061bd435) /* 0.381794175 */, 18 },
+ /* 5628 */ { MAD_F(0x061c3313) /* 0.381884645 */, 18 },
+ /* 5629 */ { MAD_F(0x061c91f1) /* 0.381975120 */, 18 },
+ /* 5630 */ { MAD_F(0x061cf0d2) /* 0.382065601 */, 18 },
+ /* 5631 */ { MAD_F(0x061d4fb3) /* 0.382156087 */, 18 },
+
+ /* 5632 */ { MAD_F(0x061dae96) /* 0.382246578 */, 18 },
+ /* 5633 */ { MAD_F(0x061e0d7b) /* 0.382337075 */, 18 },
+ /* 5634 */ { MAD_F(0x061e6c61) /* 0.382427577 */, 18 },
+ /* 5635 */ { MAD_F(0x061ecb48) /* 0.382518084 */, 18 },
+ /* 5636 */ { MAD_F(0x061f2a31) /* 0.382608597 */, 18 },
+ /* 5637 */ { MAD_F(0x061f891b) /* 0.382699115 */, 18 },
+ /* 5638 */ { MAD_F(0x061fe807) /* 0.382789638 */, 18 },
+ /* 5639 */ { MAD_F(0x062046f4) /* 0.382880167 */, 18 },
+ /* 5640 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 18 },
+ /* 5641 */ { MAD_F(0x062104d3) /* 0.383061241 */, 18 },
+ /* 5642 */ { MAD_F(0x062163c4) /* 0.383151786 */, 18 },
+ /* 5643 */ { MAD_F(0x0621c2b7) /* 0.383242336 */, 18 },
+ /* 5644 */ { MAD_F(0x062221ab) /* 0.383332891 */, 18 },
+ /* 5645 */ { MAD_F(0x062280a1) /* 0.383423452 */, 18 },
+ /* 5646 */ { MAD_F(0x0622df98) /* 0.383514018 */, 18 },
+ /* 5647 */ { MAD_F(0x06233e91) /* 0.383604590 */, 18 },
+
+ /* 5648 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 18 },
+ /* 5649 */ { MAD_F(0x0623fc86) /* 0.383785749 */, 18 },
+ /* 5650 */ { MAD_F(0x06245b83) /* 0.383876337 */, 18 },
+ /* 5651 */ { MAD_F(0x0624ba82) /* 0.383966930 */, 18 },
+ /* 5652 */ { MAD_F(0x06251981) /* 0.384057528 */, 18 },
+ /* 5653 */ { MAD_F(0x06257883) /* 0.384148132 */, 18 },
+ /* 5654 */ { MAD_F(0x0625d785) /* 0.384238741 */, 18 },
+ /* 5655 */ { MAD_F(0x06263689) /* 0.384329355 */, 18 },
+ /* 5656 */ { MAD_F(0x0626958f) /* 0.384419975 */, 18 },
+ /* 5657 */ { MAD_F(0x0626f496) /* 0.384510600 */, 18 },
+ /* 5658 */ { MAD_F(0x0627539e) /* 0.384601230 */, 18 },
+ /* 5659 */ { MAD_F(0x0627b2a8) /* 0.384691866 */, 18 },
+ /* 5660 */ { MAD_F(0x062811b3) /* 0.384782507 */, 18 },
+ /* 5661 */ { MAD_F(0x062870c0) /* 0.384873153 */, 18 },
+ /* 5662 */ { MAD_F(0x0628cfce) /* 0.384963805 */, 18 },
+ /* 5663 */ { MAD_F(0x06292ede) /* 0.385054462 */, 18 },
+
+ /* 5664 */ { MAD_F(0x06298def) /* 0.385145124 */, 18 },
+ /* 5665 */ { MAD_F(0x0629ed01) /* 0.385235792 */, 18 },
+ /* 5666 */ { MAD_F(0x062a4c15) /* 0.385326465 */, 18 },
+ /* 5667 */ { MAD_F(0x062aab2a) /* 0.385417143 */, 18 },
+ /* 5668 */ { MAD_F(0x062b0a41) /* 0.385507827 */, 18 },
+ /* 5669 */ { MAD_F(0x062b6959) /* 0.385598516 */, 18 },
+ /* 5670 */ { MAD_F(0x062bc873) /* 0.385689211 */, 18 },
+ /* 5671 */ { MAD_F(0x062c278e) /* 0.385779910 */, 18 },
+ /* 5672 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 18 },
+ /* 5673 */ { MAD_F(0x062ce5c8) /* 0.385961326 */, 18 },
+ /* 5674 */ { MAD_F(0x062d44e8) /* 0.386052041 */, 18 },
+ /* 5675 */ { MAD_F(0x062da408) /* 0.386142762 */, 18 },
+ /* 5676 */ { MAD_F(0x062e032a) /* 0.386233489 */, 18 },
+ /* 5677 */ { MAD_F(0x062e624e) /* 0.386324221 */, 18 },
+ /* 5678 */ { MAD_F(0x062ec173) /* 0.386414958 */, 18 },
+ /* 5679 */ { MAD_F(0x062f209a) /* 0.386505700 */, 18 },
+
+ /* 5680 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 18 },
+ /* 5681 */ { MAD_F(0x062fdeeb) /* 0.386687201 */, 18 },
+ /* 5682 */ { MAD_F(0x06303e16) /* 0.386777959 */, 18 },
+ /* 5683 */ { MAD_F(0x06309d42) /* 0.386868723 */, 18 },
+ /* 5684 */ { MAD_F(0x0630fc6f) /* 0.386959492 */, 18 },
+ /* 5685 */ { MAD_F(0x06315b9e) /* 0.387050266 */, 18 },
+ /* 5686 */ { MAD_F(0x0631bacf) /* 0.387141045 */, 18 },
+ /* 5687 */ { MAD_F(0x06321a01) /* 0.387231830 */, 18 },
+ /* 5688 */ { MAD_F(0x06327934) /* 0.387322621 */, 18 },
+ /* 5689 */ { MAD_F(0x0632d869) /* 0.387413416 */, 18 },
+ /* 5690 */ { MAD_F(0x0633379f) /* 0.387504217 */, 18 },
+ /* 5691 */ { MAD_F(0x063396d7) /* 0.387595023 */, 18 },
+ /* 5692 */ { MAD_F(0x0633f610) /* 0.387685835 */, 18 },
+ /* 5693 */ { MAD_F(0x0634554a) /* 0.387776652 */, 18 },
+ /* 5694 */ { MAD_F(0x0634b486) /* 0.387867474 */, 18 },
+ /* 5695 */ { MAD_F(0x063513c3) /* 0.387958301 */, 18 },
+
+ /* 5696 */ { MAD_F(0x06357302) /* 0.388049134 */, 18 },
+ /* 5697 */ { MAD_F(0x0635d242) /* 0.388139972 */, 18 },
+ /* 5698 */ { MAD_F(0x06363184) /* 0.388230816 */, 18 },
+ /* 5699 */ { MAD_F(0x063690c7) /* 0.388321665 */, 18 },
+ /* 5700 */ { MAD_F(0x0636f00b) /* 0.388412519 */, 18 },
+ /* 5701 */ { MAD_F(0x06374f51) /* 0.388503378 */, 18 },
+ /* 5702 */ { MAD_F(0x0637ae99) /* 0.388594243 */, 18 },
+ /* 5703 */ { MAD_F(0x06380de1) /* 0.388685113 */, 18 },
+ /* 5704 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 18 },
+ /* 5705 */ { MAD_F(0x0638cc77) /* 0.388866869 */, 18 },
+ /* 5706 */ { MAD_F(0x06392bc4) /* 0.388957755 */, 18 },
+ /* 5707 */ { MAD_F(0x06398b12) /* 0.389048646 */, 18 },
+ /* 5708 */ { MAD_F(0x0639ea62) /* 0.389139542 */, 18 },
+ /* 5709 */ { MAD_F(0x063a49b4) /* 0.389230444 */, 18 },
+ /* 5710 */ { MAD_F(0x063aa906) /* 0.389321352 */, 18 },
+ /* 5711 */ { MAD_F(0x063b085a) /* 0.389412264 */, 18 },
+
+ /* 5712 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 18 },
+ /* 5713 */ { MAD_F(0x063bc707) /* 0.389594105 */, 18 },
+ /* 5714 */ { MAD_F(0x063c265f) /* 0.389685033 */, 18 },
+ /* 5715 */ { MAD_F(0x063c85b9) /* 0.389775967 */, 18 },
+ /* 5716 */ { MAD_F(0x063ce514) /* 0.389866906 */, 18 },
+ /* 5717 */ { MAD_F(0x063d4471) /* 0.389957850 */, 18 },
+ /* 5718 */ { MAD_F(0x063da3cf) /* 0.390048800 */, 18 },
+ /* 5719 */ { MAD_F(0x063e032f) /* 0.390139755 */, 18 },
+ /* 5720 */ { MAD_F(0x063e6290) /* 0.390230715 */, 18 },
+ /* 5721 */ { MAD_F(0x063ec1f2) /* 0.390321681 */, 18 },
+ /* 5722 */ { MAD_F(0x063f2156) /* 0.390412651 */, 18 },
+ /* 5723 */ { MAD_F(0x063f80bb) /* 0.390503628 */, 18 },
+ /* 5724 */ { MAD_F(0x063fe022) /* 0.390594609 */, 18 },
+ /* 5725 */ { MAD_F(0x06403f8a) /* 0.390685596 */, 18 },
+ /* 5726 */ { MAD_F(0x06409ef3) /* 0.390776588 */, 18 },
+ /* 5727 */ { MAD_F(0x0640fe5e) /* 0.390867585 */, 18 },
+
+ /* 5728 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 18 },
+ /* 5729 */ { MAD_F(0x0641bd38) /* 0.391049596 */, 18 },
+ /* 5730 */ { MAD_F(0x06421ca7) /* 0.391140609 */, 18 },
+ /* 5731 */ { MAD_F(0x06427c18) /* 0.391231627 */, 18 },
+ /* 5732 */ { MAD_F(0x0642db8a) /* 0.391322651 */, 18 },
+ /* 5733 */ { MAD_F(0x06433afd) /* 0.391413680 */, 18 },
+ /* 5734 */ { MAD_F(0x06439a72) /* 0.391504714 */, 18 },
+ /* 5735 */ { MAD_F(0x0643f9e9) /* 0.391595754 */, 18 },
+ /* 5736 */ { MAD_F(0x06445960) /* 0.391686799 */, 18 },
+ /* 5737 */ { MAD_F(0x0644b8d9) /* 0.391777849 */, 18 },
+ /* 5738 */ { MAD_F(0x06451854) /* 0.391868905 */, 18 },
+ /* 5739 */ { MAD_F(0x064577d0) /* 0.391959966 */, 18 },
+ /* 5740 */ { MAD_F(0x0645d74d) /* 0.392051032 */, 18 },
+ /* 5741 */ { MAD_F(0x064636cc) /* 0.392142103 */, 18 },
+ /* 5742 */ { MAD_F(0x0646964c) /* 0.392233180 */, 18 },
+ /* 5743 */ { MAD_F(0x0646f5ce) /* 0.392324262 */, 18 },
+
+ /* 5744 */ { MAD_F(0x06475551) /* 0.392415349 */, 18 },
+ /* 5745 */ { MAD_F(0x0647b4d5) /* 0.392506442 */, 18 },
+ /* 5746 */ { MAD_F(0x0648145b) /* 0.392597540 */, 18 },
+ /* 5747 */ { MAD_F(0x064873e3) /* 0.392688643 */, 18 },
+ /* 5748 */ { MAD_F(0x0648d36b) /* 0.392779751 */, 18 },
+ /* 5749 */ { MAD_F(0x064932f6) /* 0.392870865 */, 18 },
+ /* 5750 */ { MAD_F(0x06499281) /* 0.392961984 */, 18 },
+ /* 5751 */ { MAD_F(0x0649f20e) /* 0.393053108 */, 18 },
+ /* 5752 */ { MAD_F(0x064a519c) /* 0.393144238 */, 18 },
+ /* 5753 */ { MAD_F(0x064ab12c) /* 0.393235372 */, 18 },
+ /* 5754 */ { MAD_F(0x064b10be) /* 0.393326513 */, 18 },
+ /* 5755 */ { MAD_F(0x064b7050) /* 0.393417658 */, 18 },
+ /* 5756 */ { MAD_F(0x064bcfe4) /* 0.393508809 */, 18 },
+ /* 5757 */ { MAD_F(0x064c2f7a) /* 0.393599965 */, 18 },
+ /* 5758 */ { MAD_F(0x064c8f11) /* 0.393691126 */, 18 },
+ /* 5759 */ { MAD_F(0x064ceea9) /* 0.393782292 */, 18 },
+
+ /* 5760 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 18 },
+ /* 5761 */ { MAD_F(0x064dadde) /* 0.393964641 */, 18 },
+ /* 5762 */ { MAD_F(0x064e0d7a) /* 0.394055823 */, 18 },
+ /* 5763 */ { MAD_F(0x064e6d18) /* 0.394147011 */, 18 },
+ /* 5764 */ { MAD_F(0x064eccb8) /* 0.394238204 */, 18 },
+ /* 5765 */ { MAD_F(0x064f2c59) /* 0.394329402 */, 18 },
+ /* 5766 */ { MAD_F(0x064f8bfb) /* 0.394420605 */, 18 },
+ /* 5767 */ { MAD_F(0x064feb9e) /* 0.394511814 */, 18 },
+ /* 5768 */ { MAD_F(0x06504b44) /* 0.394603028 */, 18 },
+ /* 5769 */ { MAD_F(0x0650aaea) /* 0.394694247 */, 18 },
+ /* 5770 */ { MAD_F(0x06510a92) /* 0.394785472 */, 18 },
+ /* 5771 */ { MAD_F(0x06516a3b) /* 0.394876702 */, 18 },
+ /* 5772 */ { MAD_F(0x0651c9e6) /* 0.394967937 */, 18 },
+ /* 5773 */ { MAD_F(0x06522992) /* 0.395059177 */, 18 },
+ /* 5774 */ { MAD_F(0x06528940) /* 0.395150423 */, 18 },
+ /* 5775 */ { MAD_F(0x0652e8ef) /* 0.395241673 */, 18 },
+
+ /* 5776 */ { MAD_F(0x0653489f) /* 0.395332930 */, 18 },
+ /* 5777 */ { MAD_F(0x0653a851) /* 0.395424191 */, 18 },
+ /* 5778 */ { MAD_F(0x06540804) /* 0.395515458 */, 18 },
+ /* 5779 */ { MAD_F(0x065467b9) /* 0.395606730 */, 18 },
+ /* 5780 */ { MAD_F(0x0654c76f) /* 0.395698007 */, 18 },
+ /* 5781 */ { MAD_F(0x06552726) /* 0.395789289 */, 18 },
+ /* 5782 */ { MAD_F(0x065586df) /* 0.395880577 */, 18 },
+ /* 5783 */ { MAD_F(0x0655e699) /* 0.395971870 */, 18 },
+ /* 5784 */ { MAD_F(0x06564655) /* 0.396063168 */, 18 },
+ /* 5785 */ { MAD_F(0x0656a612) /* 0.396154472 */, 18 },
+ /* 5786 */ { MAD_F(0x065705d0) /* 0.396245780 */, 18 },
+ /* 5787 */ { MAD_F(0x06576590) /* 0.396337094 */, 18 },
+ /* 5788 */ { MAD_F(0x0657c552) /* 0.396428414 */, 18 },
+ /* 5789 */ { MAD_F(0x06582514) /* 0.396519738 */, 18 },
+ /* 5790 */ { MAD_F(0x065884d9) /* 0.396611068 */, 18 },
+ /* 5791 */ { MAD_F(0x0658e49e) /* 0.396702403 */, 18 },
+
+ /* 5792 */ { MAD_F(0x06594465) /* 0.396793743 */, 18 },
+ /* 5793 */ { MAD_F(0x0659a42e) /* 0.396885089 */, 18 },
+ /* 5794 */ { MAD_F(0x065a03f7) /* 0.396976440 */, 18 },
+ /* 5795 */ { MAD_F(0x065a63c3) /* 0.397067796 */, 18 },
+ /* 5796 */ { MAD_F(0x065ac38f) /* 0.397159157 */, 18 },
+ /* 5797 */ { MAD_F(0x065b235d) /* 0.397250524 */, 18 },
+ /* 5798 */ { MAD_F(0x065b832d) /* 0.397341896 */, 18 },
+ /* 5799 */ { MAD_F(0x065be2fe) /* 0.397433273 */, 18 },
+ /* 5800 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 18 },
+ /* 5801 */ { MAD_F(0x065ca2a3) /* 0.397616043 */, 18 },
+ /* 5802 */ { MAD_F(0x065d0279) /* 0.397707436 */, 18 },
+ /* 5803 */ { MAD_F(0x065d624f) /* 0.397798834 */, 18 },
+ /* 5804 */ { MAD_F(0x065dc227) /* 0.397890237 */, 18 },
+ /* 5805 */ { MAD_F(0x065e2200) /* 0.397981646 */, 18 },
+ /* 5806 */ { MAD_F(0x065e81db) /* 0.398073059 */, 18 },
+ /* 5807 */ { MAD_F(0x065ee1b7) /* 0.398164479 */, 18 },
+
+ /* 5808 */ { MAD_F(0x065f4195) /* 0.398255903 */, 18 },
+ /* 5809 */ { MAD_F(0x065fa174) /* 0.398347333 */, 18 },
+ /* 5810 */ { MAD_F(0x06600154) /* 0.398438767 */, 18 },
+ /* 5811 */ { MAD_F(0x06606136) /* 0.398530207 */, 18 },
+ /* 5812 */ { MAD_F(0x0660c119) /* 0.398621653 */, 18 },
+ /* 5813 */ { MAD_F(0x066120fd) /* 0.398713103 */, 18 },
+ /* 5814 */ { MAD_F(0x066180e3) /* 0.398804559 */, 18 },
+ /* 5815 */ { MAD_F(0x0661e0cb) /* 0.398896020 */, 18 },
+ /* 5816 */ { MAD_F(0x066240b4) /* 0.398987487 */, 18 },
+ /* 5817 */ { MAD_F(0x0662a09e) /* 0.399078958 */, 18 },
+ /* 5818 */ { MAD_F(0x06630089) /* 0.399170435 */, 18 },
+ /* 5819 */ { MAD_F(0x06636077) /* 0.399261917 */, 18 },
+ /* 5820 */ { MAD_F(0x0663c065) /* 0.399353404 */, 18 },
+ /* 5821 */ { MAD_F(0x06642055) /* 0.399444897 */, 18 },
+ /* 5822 */ { MAD_F(0x06648046) /* 0.399536395 */, 18 },
+ /* 5823 */ { MAD_F(0x0664e039) /* 0.399627898 */, 18 },
+
+ /* 5824 */ { MAD_F(0x0665402d) /* 0.399719406 */, 18 },
+ /* 5825 */ { MAD_F(0x0665a022) /* 0.399810919 */, 18 },
+ /* 5826 */ { MAD_F(0x06660019) /* 0.399902438 */, 18 },
+ /* 5827 */ { MAD_F(0x06666011) /* 0.399993962 */, 18 },
+ /* 5828 */ { MAD_F(0x0666c00b) /* 0.400085491 */, 18 },
+ /* 5829 */ { MAD_F(0x06672006) /* 0.400177026 */, 18 },
+ /* 5830 */ { MAD_F(0x06678003) /* 0.400268565 */, 18 },
+ /* 5831 */ { MAD_F(0x0667e000) /* 0.400360110 */, 18 },
+ /* 5832 */ { MAD_F(0x06684000) /* 0.400451660 */, 18 },
+ /* 5833 */ { MAD_F(0x0668a000) /* 0.400543216 */, 18 },
+ /* 5834 */ { MAD_F(0x06690003) /* 0.400634776 */, 18 },
+ /* 5835 */ { MAD_F(0x06696006) /* 0.400726342 */, 18 },
+ /* 5836 */ { MAD_F(0x0669c00b) /* 0.400817913 */, 18 },
+ /* 5837 */ { MAD_F(0x066a2011) /* 0.400909489 */, 18 },
+ /* 5838 */ { MAD_F(0x066a8019) /* 0.401001071 */, 18 },
+ /* 5839 */ { MAD_F(0x066ae022) /* 0.401092657 */, 18 },
+
+ /* 5840 */ { MAD_F(0x066b402d) /* 0.401184249 */, 18 },
+ /* 5841 */ { MAD_F(0x066ba039) /* 0.401275847 */, 18 },
+ /* 5842 */ { MAD_F(0x066c0046) /* 0.401367449 */, 18 },
+ /* 5843 */ { MAD_F(0x066c6055) /* 0.401459057 */, 18 },
+ /* 5844 */ { MAD_F(0x066cc065) /* 0.401550670 */, 18 },
+ /* 5845 */ { MAD_F(0x066d2076) /* 0.401642288 */, 18 },
+ /* 5846 */ { MAD_F(0x066d8089) /* 0.401733911 */, 18 },
+ /* 5847 */ { MAD_F(0x066de09e) /* 0.401825540 */, 18 },
+ /* 5848 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 18 },
+ /* 5849 */ { MAD_F(0x066ea0cb) /* 0.402008812 */, 18 },
+ /* 5850 */ { MAD_F(0x066f00e3) /* 0.402100457 */, 18 },
+ /* 5851 */ { MAD_F(0x066f60fd) /* 0.402192106 */, 18 },
+ /* 5852 */ { MAD_F(0x066fc118) /* 0.402283761 */, 18 },
+ /* 5853 */ { MAD_F(0x06702135) /* 0.402375420 */, 18 },
+ /* 5854 */ { MAD_F(0x06708153) /* 0.402467086 */, 18 },
+ /* 5855 */ { MAD_F(0x0670e173) /* 0.402558756 */, 18 },
+
+ /* 5856 */ { MAD_F(0x06714194) /* 0.402650431 */, 18 },
+ /* 5857 */ { MAD_F(0x0671a1b6) /* 0.402742112 */, 18 },
+ /* 5858 */ { MAD_F(0x067201da) /* 0.402833798 */, 18 },
+ /* 5859 */ { MAD_F(0x067261ff) /* 0.402925489 */, 18 },
+ /* 5860 */ { MAD_F(0x0672c226) /* 0.403017186 */, 18 },
+ /* 5861 */ { MAD_F(0x0673224e) /* 0.403108887 */, 18 },
+ /* 5862 */ { MAD_F(0x06738277) /* 0.403200594 */, 18 },
+ /* 5863 */ { MAD_F(0x0673e2a2) /* 0.403292306 */, 18 },
+ /* 5864 */ { MAD_F(0x067442ce) /* 0.403384024 */, 18 },
+ /* 5865 */ { MAD_F(0x0674a2fc) /* 0.403475746 */, 18 },
+ /* 5866 */ { MAD_F(0x0675032b) /* 0.403567474 */, 18 },
+ /* 5867 */ { MAD_F(0x0675635b) /* 0.403659207 */, 18 },
+ /* 5868 */ { MAD_F(0x0675c38d) /* 0.403750945 */, 18 },
+ /* 5869 */ { MAD_F(0x067623c0) /* 0.403842688 */, 18 },
+ /* 5870 */ { MAD_F(0x067683f4) /* 0.403934437 */, 18 },
+ /* 5871 */ { MAD_F(0x0676e42a) /* 0.404026190 */, 18 },
+
+ /* 5872 */ { MAD_F(0x06774462) /* 0.404117949 */, 18 },
+ /* 5873 */ { MAD_F(0x0677a49b) /* 0.404209714 */, 18 },
+ /* 5874 */ { MAD_F(0x067804d5) /* 0.404301483 */, 18 },
+ /* 5875 */ { MAD_F(0x06786510) /* 0.404393258 */, 18 },
+ /* 5876 */ { MAD_F(0x0678c54d) /* 0.404485037 */, 18 },
+ /* 5877 */ { MAD_F(0x0679258c) /* 0.404576822 */, 18 },
+ /* 5878 */ { MAD_F(0x067985cb) /* 0.404668613 */, 18 },
+ /* 5879 */ { MAD_F(0x0679e60c) /* 0.404760408 */, 18 },
+ /* 5880 */ { MAD_F(0x067a464f) /* 0.404852209 */, 18 },
+ /* 5881 */ { MAD_F(0x067aa693) /* 0.404944014 */, 18 },
+ /* 5882 */ { MAD_F(0x067b06d8) /* 0.405035825 */, 18 },
+ /* 5883 */ { MAD_F(0x067b671f) /* 0.405127642 */, 18 },
+ /* 5884 */ { MAD_F(0x067bc767) /* 0.405219463 */, 18 },
+ /* 5885 */ { MAD_F(0x067c27b1) /* 0.405311290 */, 18 },
+ /* 5886 */ { MAD_F(0x067c87fc) /* 0.405403122 */, 18 },
+ /* 5887 */ { MAD_F(0x067ce848) /* 0.405494959 */, 18 },
+
+ /* 5888 */ { MAD_F(0x067d4896) /* 0.405586801 */, 18 },
+ /* 5889 */ { MAD_F(0x067da8e5) /* 0.405678648 */, 18 },
+ /* 5890 */ { MAD_F(0x067e0935) /* 0.405770501 */, 18 },
+ /* 5891 */ { MAD_F(0x067e6987) /* 0.405862359 */, 18 },
+ /* 5892 */ { MAD_F(0x067ec9da) /* 0.405954222 */, 18 },
+ /* 5893 */ { MAD_F(0x067f2a2f) /* 0.406046090 */, 18 },
+ /* 5894 */ { MAD_F(0x067f8a85) /* 0.406137963 */, 18 },
+ /* 5895 */ { MAD_F(0x067feadd) /* 0.406229842 */, 18 },
+ /* 5896 */ { MAD_F(0x06804b36) /* 0.406321726 */, 18 },
+ /* 5897 */ { MAD_F(0x0680ab90) /* 0.406413615 */, 18 },
+ /* 5898 */ { MAD_F(0x06810beb) /* 0.406505509 */, 18 },
+ /* 5899 */ { MAD_F(0x06816c49) /* 0.406597408 */, 18 },
+ /* 5900 */ { MAD_F(0x0681cca7) /* 0.406689313 */, 18 },
+ /* 5901 */ { MAD_F(0x06822d07) /* 0.406781223 */, 18 },
+ /* 5902 */ { MAD_F(0x06828d68) /* 0.406873138 */, 18 },
+ /* 5903 */ { MAD_F(0x0682edcb) /* 0.406965058 */, 18 },
+
+ /* 5904 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 18 },
+ /* 5905 */ { MAD_F(0x0683ae94) /* 0.407148914 */, 18 },
+ /* 5906 */ { MAD_F(0x06840efb) /* 0.407240850 */, 18 },
+ /* 5907 */ { MAD_F(0x06846f63) /* 0.407332791 */, 18 },
+ /* 5908 */ { MAD_F(0x0684cfcd) /* 0.407424737 */, 18 },
+ /* 5909 */ { MAD_F(0x06853038) /* 0.407516688 */, 18 },
+ /* 5910 */ { MAD_F(0x068590a4) /* 0.407608645 */, 18 },
+ /* 5911 */ { MAD_F(0x0685f112) /* 0.407700606 */, 18 },
+ /* 5912 */ { MAD_F(0x06865181) /* 0.407792573 */, 18 },
+ /* 5913 */ { MAD_F(0x0686b1f2) /* 0.407884545 */, 18 },
+ /* 5914 */ { MAD_F(0x06871264) /* 0.407976522 */, 18 },
+ /* 5915 */ { MAD_F(0x068772d7) /* 0.408068505 */, 18 },
+ /* 5916 */ { MAD_F(0x0687d34c) /* 0.408160492 */, 18 },
+ /* 5917 */ { MAD_F(0x068833c2) /* 0.408252485 */, 18 },
+ /* 5918 */ { MAD_F(0x06889439) /* 0.408344483 */, 18 },
+ /* 5919 */ { MAD_F(0x0688f4b2) /* 0.408436486 */, 18 },
+
+ /* 5920 */ { MAD_F(0x0689552c) /* 0.408528495 */, 18 },
+ /* 5921 */ { MAD_F(0x0689b5a8) /* 0.408620508 */, 18 },
+ /* 5922 */ { MAD_F(0x068a1625) /* 0.408712527 */, 18 },
+ /* 5923 */ { MAD_F(0x068a76a4) /* 0.408804551 */, 18 },
+ /* 5924 */ { MAD_F(0x068ad724) /* 0.408896580 */, 18 },
+ /* 5925 */ { MAD_F(0x068b37a5) /* 0.408988614 */, 18 },
+ /* 5926 */ { MAD_F(0x068b9827) /* 0.409080653 */, 18 },
+ /* 5927 */ { MAD_F(0x068bf8ac) /* 0.409172698 */, 18 },
+ /* 5928 */ { MAD_F(0x068c5931) /* 0.409264748 */, 18 },
+ /* 5929 */ { MAD_F(0x068cb9b8) /* 0.409356803 */, 18 },
+ /* 5930 */ { MAD_F(0x068d1a40) /* 0.409448863 */, 18 },
+ /* 5931 */ { MAD_F(0x068d7aca) /* 0.409540928 */, 18 },
+ /* 5932 */ { MAD_F(0x068ddb54) /* 0.409632999 */, 18 },
+ /* 5933 */ { MAD_F(0x068e3be1) /* 0.409725074 */, 18 },
+ /* 5934 */ { MAD_F(0x068e9c6f) /* 0.409817155 */, 18 },
+ /* 5935 */ { MAD_F(0x068efcfe) /* 0.409909241 */, 18 },
+
+ /* 5936 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 18 },
+ /* 5937 */ { MAD_F(0x068fbe20) /* 0.410093428 */, 18 },
+ /* 5938 */ { MAD_F(0x06901eb4) /* 0.410185530 */, 18 },
+ /* 5939 */ { MAD_F(0x06907f48) /* 0.410277637 */, 18 },
+ /* 5940 */ { MAD_F(0x0690dfde) /* 0.410369748 */, 18 },
+ /* 5941 */ { MAD_F(0x06914076) /* 0.410461865 */, 18 },
+ /* 5942 */ { MAD_F(0x0691a10f) /* 0.410553988 */, 18 },
+ /* 5943 */ { MAD_F(0x069201a9) /* 0.410646115 */, 18 },
+ /* 5944 */ { MAD_F(0x06926245) /* 0.410738247 */, 18 },
+ /* 5945 */ { MAD_F(0x0692c2e2) /* 0.410830385 */, 18 },
+ /* 5946 */ { MAD_F(0x06932380) /* 0.410922528 */, 18 },
+ /* 5947 */ { MAD_F(0x06938420) /* 0.411014676 */, 18 },
+ /* 5948 */ { MAD_F(0x0693e4c1) /* 0.411106829 */, 18 },
+ /* 5949 */ { MAD_F(0x06944563) /* 0.411198987 */, 18 },
+ /* 5950 */ { MAD_F(0x0694a607) /* 0.411291151 */, 18 },
+ /* 5951 */ { MAD_F(0x069506ad) /* 0.411383320 */, 18 },
+
+ /* 5952 */ { MAD_F(0x06956753) /* 0.411475493 */, 18 },
+ /* 5953 */ { MAD_F(0x0695c7fc) /* 0.411567672 */, 18 },
+ /* 5954 */ { MAD_F(0x069628a5) /* 0.411659857 */, 18 },
+ /* 5955 */ { MAD_F(0x06968950) /* 0.411752046 */, 18 },
+ /* 5956 */ { MAD_F(0x0696e9fc) /* 0.411844240 */, 18 },
+ /* 5957 */ { MAD_F(0x06974aaa) /* 0.411936440 */, 18 },
+ /* 5958 */ { MAD_F(0x0697ab59) /* 0.412028645 */, 18 },
+ /* 5959 */ { MAD_F(0x06980c09) /* 0.412120855 */, 18 },
+ /* 5960 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 18 },
+ /* 5961 */ { MAD_F(0x0698cd6e) /* 0.412305290 */, 18 },
+ /* 5962 */ { MAD_F(0x06992e23) /* 0.412397516 */, 18 },
+ /* 5963 */ { MAD_F(0x06998ed9) /* 0.412489746 */, 18 },
+ /* 5964 */ { MAD_F(0x0699ef90) /* 0.412581982 */, 18 },
+ /* 5965 */ { MAD_F(0x069a5049) /* 0.412674223 */, 18 },
+ /* 5966 */ { MAD_F(0x069ab103) /* 0.412766469 */, 18 },
+ /* 5967 */ { MAD_F(0x069b11bf) /* 0.412858720 */, 18 },
+
+ /* 5968 */ { MAD_F(0x069b727b) /* 0.412950976 */, 18 },
+ /* 5969 */ { MAD_F(0x069bd33a) /* 0.413043238 */, 18 },
+ /* 5970 */ { MAD_F(0x069c33f9) /* 0.413135505 */, 18 },
+ /* 5971 */ { MAD_F(0x069c94ba) /* 0.413227776 */, 18 },
+ /* 5972 */ { MAD_F(0x069cf57d) /* 0.413320053 */, 18 },
+ /* 5973 */ { MAD_F(0x069d5641) /* 0.413412335 */, 18 },
+ /* 5974 */ { MAD_F(0x069db706) /* 0.413504623 */, 18 },
+ /* 5975 */ { MAD_F(0x069e17cc) /* 0.413596915 */, 18 },
+ /* 5976 */ { MAD_F(0x069e7894) /* 0.413689213 */, 18 },
+ /* 5977 */ { MAD_F(0x069ed95e) /* 0.413781515 */, 18 },
+ /* 5978 */ { MAD_F(0x069f3a28) /* 0.413873823 */, 18 },
+ /* 5979 */ { MAD_F(0x069f9af4) /* 0.413966136 */, 18 },
+ /* 5980 */ { MAD_F(0x069ffbc2) /* 0.414058454 */, 18 },
+ /* 5981 */ { MAD_F(0x06a05c91) /* 0.414150778 */, 18 },
+ /* 5982 */ { MAD_F(0x06a0bd61) /* 0.414243106 */, 18 },
+ /* 5983 */ { MAD_F(0x06a11e32) /* 0.414335440 */, 18 },
+
+ /* 5984 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 18 },
+ /* 5985 */ { MAD_F(0x06a1dfda) /* 0.414520122 */, 18 },
+ /* 5986 */ { MAD_F(0x06a240b0) /* 0.414612471 */, 18 },
+ /* 5987 */ { MAD_F(0x06a2a187) /* 0.414704826 */, 18 },
+ /* 5988 */ { MAD_F(0x06a3025f) /* 0.414797185 */, 18 },
+ /* 5989 */ { MAD_F(0x06a36339) /* 0.414889549 */, 18 },
+ /* 5990 */ { MAD_F(0x06a3c414) /* 0.414981919 */, 18 },
+ /* 5991 */ { MAD_F(0x06a424f1) /* 0.415074294 */, 18 },
+ /* 5992 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 18 },
+ /* 5993 */ { MAD_F(0x06a4e6ae) /* 0.415259059 */, 18 },
+ /* 5994 */ { MAD_F(0x06a5478f) /* 0.415351449 */, 18 },
+ /* 5995 */ { MAD_F(0x06a5a871) /* 0.415443844 */, 18 },
+ /* 5996 */ { MAD_F(0x06a60955) /* 0.415536244 */, 18 },
+ /* 5997 */ { MAD_F(0x06a66a3a) /* 0.415628650 */, 18 },
+ /* 5998 */ { MAD_F(0x06a6cb20) /* 0.415721061 */, 18 },
+ /* 5999 */ { MAD_F(0x06a72c08) /* 0.415813476 */, 18 },
+
+ /* 6000 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 18 },
+ /* 6001 */ { MAD_F(0x06a7eddb) /* 0.415998324 */, 18 },
+ /* 6002 */ { MAD_F(0x06a84ec7) /* 0.416090755 */, 18 },
+ /* 6003 */ { MAD_F(0x06a8afb4) /* 0.416183191 */, 18 },
+ /* 6004 */ { MAD_F(0x06a910a3) /* 0.416275633 */, 18 },
+ /* 6005 */ { MAD_F(0x06a97193) /* 0.416368079 */, 18 },
+ /* 6006 */ { MAD_F(0x06a9d284) /* 0.416460531 */, 18 },
+ /* 6007 */ { MAD_F(0x06aa3377) /* 0.416552988 */, 18 },
+ /* 6008 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 18 },
+ /* 6009 */ { MAD_F(0x06aaf561) /* 0.416737917 */, 18 },
+ /* 6010 */ { MAD_F(0x06ab5657) /* 0.416830389 */, 18 },
+ /* 6011 */ { MAD_F(0x06abb750) /* 0.416922867 */, 18 },
+ /* 6012 */ { MAD_F(0x06ac1849) /* 0.417015349 */, 18 },
+ /* 6013 */ { MAD_F(0x06ac7944) /* 0.417107837 */, 18 },
+ /* 6014 */ { MAD_F(0x06acda41) /* 0.417200330 */, 18 },
+ /* 6015 */ { MAD_F(0x06ad3b3e) /* 0.417292828 */, 18 },
+
+ /* 6016 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 18 },
+ /* 6017 */ { MAD_F(0x06adfd3e) /* 0.417477839 */, 18 },
+ /* 6018 */ { MAD_F(0x06ae5e40) /* 0.417570352 */, 18 },
+ /* 6019 */ { MAD_F(0x06aebf43) /* 0.417662871 */, 18 },
+ /* 6020 */ { MAD_F(0x06af2047) /* 0.417755394 */, 18 },
+ /* 6021 */ { MAD_F(0x06af814d) /* 0.417847923 */, 18 },
+ /* 6022 */ { MAD_F(0x06afe255) /* 0.417940457 */, 18 },
+ /* 6023 */ { MAD_F(0x06b0435e) /* 0.418032996 */, 18 },
+ /* 6024 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 18 },
+ /* 6025 */ { MAD_F(0x06b10573) /* 0.418218089 */, 18 },
+ /* 6026 */ { MAD_F(0x06b16680) /* 0.418310643 */, 18 },
+ /* 6027 */ { MAD_F(0x06b1c78e) /* 0.418403203 */, 18 },
+ /* 6028 */ { MAD_F(0x06b2289e) /* 0.418495767 */, 18 },
+ /* 6029 */ { MAD_F(0x06b289af) /* 0.418588337 */, 18 },
+ /* 6030 */ { MAD_F(0x06b2eac1) /* 0.418680911 */, 18 },
+ /* 6031 */ { MAD_F(0x06b34bd5) /* 0.418773491 */, 18 },
+
+ /* 6032 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 18 },
+ /* 6033 */ { MAD_F(0x06b40e00) /* 0.418958666 */, 18 },
+ /* 6034 */ { MAD_F(0x06b46f18) /* 0.419051262 */, 18 },
+ /* 6035 */ { MAD_F(0x06b4d031) /* 0.419143862 */, 18 },
+ /* 6036 */ { MAD_F(0x06b5314c) /* 0.419236467 */, 18 },
+ /* 6037 */ { MAD_F(0x06b59268) /* 0.419329078 */, 18 },
+ /* 6038 */ { MAD_F(0x06b5f385) /* 0.419421694 */, 18 },
+ /* 6039 */ { MAD_F(0x06b654a4) /* 0.419514314 */, 18 },
+ /* 6040 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 18 },
+ /* 6041 */ { MAD_F(0x06b716e6) /* 0.419699571 */, 18 },
+ /* 6042 */ { MAD_F(0x06b77808) /* 0.419792208 */, 18 },
+ /* 6043 */ { MAD_F(0x06b7d92d) /* 0.419884849 */, 18 },
+ /* 6044 */ { MAD_F(0x06b83a52) /* 0.419977495 */, 18 },
+ /* 6045 */ { MAD_F(0x06b89b79) /* 0.420070147 */, 18 },
+ /* 6046 */ { MAD_F(0x06b8fca1) /* 0.420162803 */, 18 },
+ /* 6047 */ { MAD_F(0x06b95dcb) /* 0.420255465 */, 18 },
+
+ /* 6048 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 18 },
+ /* 6049 */ { MAD_F(0x06ba2023) /* 0.420440803 */, 18 },
+ /* 6050 */ { MAD_F(0x06ba8150) /* 0.420533481 */, 18 },
+ /* 6051 */ { MAD_F(0x06bae280) /* 0.420626163 */, 18 },
+ /* 6052 */ { MAD_F(0x06bb43b0) /* 0.420718850 */, 18 },
+ /* 6053 */ { MAD_F(0x06bba4e2) /* 0.420811542 */, 18 },
+ /* 6054 */ { MAD_F(0x06bc0615) /* 0.420904240 */, 18 },
+ /* 6055 */ { MAD_F(0x06bc674a) /* 0.420996942 */, 18 },
+ /* 6056 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 18 },
+ /* 6057 */ { MAD_F(0x06bd29b7) /* 0.421182362 */, 18 },
+ /* 6058 */ { MAD_F(0x06bd8af0) /* 0.421275080 */, 18 },
+ /* 6059 */ { MAD_F(0x06bdec2a) /* 0.421367803 */, 18 },
+ /* 6060 */ { MAD_F(0x06be4d66) /* 0.421460531 */, 18 },
+ /* 6061 */ { MAD_F(0x06beaea3) /* 0.421553264 */, 18 },
+ /* 6062 */ { MAD_F(0x06bf0fe1) /* 0.421646003 */, 18 },
+ /* 6063 */ { MAD_F(0x06bf7120) /* 0.421738746 */, 18 },
+
+ /* 6064 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 18 },
+ /* 6065 */ { MAD_F(0x06c033a4) /* 0.421924248 */, 18 },
+ /* 6066 */ { MAD_F(0x06c094e7) /* 0.422017007 */, 18 },
+ /* 6067 */ { MAD_F(0x06c0f62c) /* 0.422109770 */, 18 },
+ /* 6068 */ { MAD_F(0x06c15773) /* 0.422202539 */, 18 },
+ /* 6069 */ { MAD_F(0x06c1b8bb) /* 0.422295313 */, 18 },
+ /* 6070 */ { MAD_F(0x06c21a04) /* 0.422388092 */, 18 },
+ /* 6071 */ { MAD_F(0x06c27b4e) /* 0.422480876 */, 18 },
+ /* 6072 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 18 },
+ /* 6073 */ { MAD_F(0x06c33de8) /* 0.422666460 */, 18 },
+ /* 6074 */ { MAD_F(0x06c39f36) /* 0.422759259 */, 18 },
+ /* 6075 */ { MAD_F(0x06c40086) /* 0.422852064 */, 18 },
+ /* 6076 */ { MAD_F(0x06c461d8) /* 0.422944873 */, 18 },
+ /* 6077 */ { MAD_F(0x06c4c32a) /* 0.423037688 */, 18 },
+ /* 6078 */ { MAD_F(0x06c5247f) /* 0.423130508 */, 18 },
+ /* 6079 */ { MAD_F(0x06c585d4) /* 0.423223333 */, 18 },
+
+ /* 6080 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 18 },
+ /* 6081 */ { MAD_F(0x06c64883) /* 0.423408997 */, 18 },
+ /* 6082 */ { MAD_F(0x06c6a9dd) /* 0.423501838 */, 18 },
+ /* 6083 */ { MAD_F(0x06c70b38) /* 0.423594683 */, 18 },
+ /* 6084 */ { MAD_F(0x06c76c94) /* 0.423687533 */, 18 },
+ /* 6085 */ { MAD_F(0x06c7cdf2) /* 0.423780389 */, 18 },
+ /* 6086 */ { MAD_F(0x06c82f51) /* 0.423873249 */, 18 },
+ /* 6087 */ { MAD_F(0x06c890b1) /* 0.423966115 */, 18 },
+ /* 6088 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 18 },
+ /* 6089 */ { MAD_F(0x06c95376) /* 0.424151861 */, 18 },
+ /* 6090 */ { MAD_F(0x06c9b4da) /* 0.424244742 */, 18 },
+ /* 6091 */ { MAD_F(0x06ca1640) /* 0.424337628 */, 18 },
+ /* 6092 */ { MAD_F(0x06ca77a8) /* 0.424430519 */, 18 },
+ /* 6093 */ { MAD_F(0x06cad910) /* 0.424523415 */, 18 },
+ /* 6094 */ { MAD_F(0x06cb3a7a) /* 0.424616316 */, 18 },
+ /* 6095 */ { MAD_F(0x06cb9be5) /* 0.424709222 */, 18 },
+
+ /* 6096 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 18 },
+ /* 6097 */ { MAD_F(0x06cc5ec0) /* 0.424895050 */, 18 },
+ /* 6098 */ { MAD_F(0x06ccc030) /* 0.424987971 */, 18 },
+ /* 6099 */ { MAD_F(0x06cd21a0) /* 0.425080898 */, 18 },
+ /* 6100 */ { MAD_F(0x06cd8313) /* 0.425173829 */, 18 },
+ /* 6101 */ { MAD_F(0x06cde486) /* 0.425266766 */, 18 },
+ /* 6102 */ { MAD_F(0x06ce45fb) /* 0.425359708 */, 18 },
+ /* 6103 */ { MAD_F(0x06cea771) /* 0.425452655 */, 18 },
+ /* 6104 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 18 },
+ /* 6105 */ { MAD_F(0x06cf6a62) /* 0.425638564 */, 18 },
+ /* 6106 */ { MAD_F(0x06cfcbdc) /* 0.425731526 */, 18 },
+ /* 6107 */ { MAD_F(0x06d02d58) /* 0.425824493 */, 18 },
+ /* 6108 */ { MAD_F(0x06d08ed5) /* 0.425917465 */, 18 },
+ /* 6109 */ { MAD_F(0x06d0f053) /* 0.426010443 */, 18 },
+ /* 6110 */ { MAD_F(0x06d151d3) /* 0.426103425 */, 18 },
+ /* 6111 */ { MAD_F(0x06d1b354) /* 0.426196412 */, 18 },
+
+ /* 6112 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 18 },
+ /* 6113 */ { MAD_F(0x06d2765a) /* 0.426382403 */, 18 },
+ /* 6114 */ { MAD_F(0x06d2d7e0) /* 0.426475405 */, 18 },
+ /* 6115 */ { MAD_F(0x06d33966) /* 0.426568413 */, 18 },
+ /* 6116 */ { MAD_F(0x06d39aee) /* 0.426661426 */, 18 },
+ /* 6117 */ { MAD_F(0x06d3fc77) /* 0.426754444 */, 18 },
+ /* 6118 */ { MAD_F(0x06d45e02) /* 0.426847467 */, 18 },
+ /* 6119 */ { MAD_F(0x06d4bf8e) /* 0.426940495 */, 18 },
+ /* 6120 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 18 },
+ /* 6121 */ { MAD_F(0x06d582aa) /* 0.427126566 */, 18 },
+ /* 6122 */ { MAD_F(0x06d5e43a) /* 0.427219609 */, 18 },
+ /* 6123 */ { MAD_F(0x06d645cc) /* 0.427312657 */, 18 },
+ /* 6124 */ { MAD_F(0x06d6a75f) /* 0.427405711 */, 18 },
+ /* 6125 */ { MAD_F(0x06d708f3) /* 0.427498769 */, 18 },
+ /* 6126 */ { MAD_F(0x06d76a88) /* 0.427591833 */, 18 },
+ /* 6127 */ { MAD_F(0x06d7cc1f) /* 0.427684901 */, 18 },
+
+ /* 6128 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 18 },
+ /* 6129 */ { MAD_F(0x06d88f51) /* 0.427871054 */, 18 },
+ /* 6130 */ { MAD_F(0x06d8f0ec) /* 0.427964137 */, 18 },
+ /* 6131 */ { MAD_F(0x06d95288) /* 0.428057226 */, 18 },
+ /* 6132 */ { MAD_F(0x06d9b426) /* 0.428150320 */, 18 },
+ /* 6133 */ { MAD_F(0x06da15c5) /* 0.428243419 */, 18 },
+ /* 6134 */ { MAD_F(0x06da7766) /* 0.428336523 */, 18 },
+ /* 6135 */ { MAD_F(0x06dad907) /* 0.428429632 */, 18 },
+ /* 6136 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 18 },
+ /* 6137 */ { MAD_F(0x06db9c4f) /* 0.428615865 */, 18 },
+ /* 6138 */ { MAD_F(0x06dbfdf5) /* 0.428708989 */, 18 },
+ /* 6139 */ { MAD_F(0x06dc5f9c) /* 0.428802119 */, 18 },
+ /* 6140 */ { MAD_F(0x06dcc145) /* 0.428895253 */, 18 },
+ /* 6141 */ { MAD_F(0x06dd22ee) /* 0.428988392 */, 18 },
+ /* 6142 */ { MAD_F(0x06dd849a) /* 0.429081537 */, 18 },
+ /* 6143 */ { MAD_F(0x06dde646) /* 0.429174686 */, 18 },
+
+ /* 6144 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 18 },
+ /* 6145 */ { MAD_F(0x06dea9a4) /* 0.429361001 */, 18 },
+ /* 6146 */ { MAD_F(0x06df0b54) /* 0.429454165 */, 18 },
+ /* 6147 */ { MAD_F(0x06df6d06) /* 0.429547335 */, 18 },
+ /* 6148 */ { MAD_F(0x06dfceba) /* 0.429640510 */, 18 },
+ /* 6149 */ { MAD_F(0x06e0306f) /* 0.429733690 */, 18 },
+ /* 6150 */ { MAD_F(0x06e09225) /* 0.429826874 */, 18 },
+ /* 6151 */ { MAD_F(0x06e0f3dc) /* 0.429920064 */, 18 },
+ /* 6152 */ { MAD_F(0x06e15595) /* 0.430013259 */, 18 },
+ /* 6153 */ { MAD_F(0x06e1b74f) /* 0.430106459 */, 18 },
+ /* 6154 */ { MAD_F(0x06e2190b) /* 0.430199664 */, 18 },
+ /* 6155 */ { MAD_F(0x06e27ac8) /* 0.430292875 */, 18 },
+ /* 6156 */ { MAD_F(0x06e2dc86) /* 0.430386090 */, 18 },
+ /* 6157 */ { MAD_F(0x06e33e46) /* 0.430479310 */, 18 },
+ /* 6158 */ { MAD_F(0x06e3a007) /* 0.430572535 */, 18 },
+ /* 6159 */ { MAD_F(0x06e401c9) /* 0.430665765 */, 18 },
+
+ /* 6160 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 18 },
+ /* 6161 */ { MAD_F(0x06e4c552) /* 0.430852241 */, 18 },
+ /* 6162 */ { MAD_F(0x06e52718) /* 0.430945487 */, 18 },
+ /* 6163 */ { MAD_F(0x06e588e0) /* 0.431038737 */, 18 },
+ /* 6164 */ { MAD_F(0x06e5eaa9) /* 0.431131993 */, 18 },
+ /* 6165 */ { MAD_F(0x06e64c73) /* 0.431225253 */, 18 },
+ /* 6166 */ { MAD_F(0x06e6ae3f) /* 0.431318519 */, 18 },
+ /* 6167 */ { MAD_F(0x06e7100c) /* 0.431411790 */, 18 },
+ /* 6168 */ { MAD_F(0x06e771db) /* 0.431505065 */, 18 },
+ /* 6169 */ { MAD_F(0x06e7d3ab) /* 0.431598346 */, 18 },
+ /* 6170 */ { MAD_F(0x06e8357c) /* 0.431691632 */, 18 },
+ /* 6171 */ { MAD_F(0x06e8974e) /* 0.431784923 */, 18 },
+ /* 6172 */ { MAD_F(0x06e8f922) /* 0.431878218 */, 18 },
+ /* 6173 */ { MAD_F(0x06e95af8) /* 0.431971519 */, 18 },
+ /* 6174 */ { MAD_F(0x06e9bcce) /* 0.432064825 */, 18 },
+ /* 6175 */ { MAD_F(0x06ea1ea6) /* 0.432158136 */, 18 },
+
+ /* 6176 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 18 },
+ /* 6177 */ { MAD_F(0x06eae25a) /* 0.432344773 */, 18 },
+ /* 6178 */ { MAD_F(0x06eb4436) /* 0.432438099 */, 18 },
+ /* 6179 */ { MAD_F(0x06eba614) /* 0.432531431 */, 18 },
+ /* 6180 */ { MAD_F(0x06ec07f2) /* 0.432624767 */, 18 },
+ /* 6181 */ { MAD_F(0x06ec69d2) /* 0.432718108 */, 18 },
+ /* 6182 */ { MAD_F(0x06eccbb4) /* 0.432811454 */, 18 },
+ /* 6183 */ { MAD_F(0x06ed2d97) /* 0.432904805 */, 18 },
+ /* 6184 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 18 },
+ /* 6185 */ { MAD_F(0x06edf160) /* 0.433091523 */, 18 },
+ /* 6186 */ { MAD_F(0x06ee5347) /* 0.433184889 */, 18 },
+ /* 6187 */ { MAD_F(0x06eeb52f) /* 0.433278261 */, 18 },
+ /* 6188 */ { MAD_F(0x06ef1719) /* 0.433371637 */, 18 },
+ /* 6189 */ { MAD_F(0x06ef7904) /* 0.433465019 */, 18 },
+ /* 6190 */ { MAD_F(0x06efdaf0) /* 0.433558405 */, 18 },
+ /* 6191 */ { MAD_F(0x06f03cde) /* 0.433651797 */, 18 },
+
+ /* 6192 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 18 },
+ /* 6193 */ { MAD_F(0x06f100bd) /* 0.433838595 */, 18 },
+ /* 6194 */ { MAD_F(0x06f162ae) /* 0.433932001 */, 18 },
+ /* 6195 */ { MAD_F(0x06f1c4a1) /* 0.434025413 */, 18 },
+ /* 6196 */ { MAD_F(0x06f22696) /* 0.434118830 */, 18 },
+ /* 6197 */ { MAD_F(0x06f2888b) /* 0.434212251 */, 18 },
+ /* 6198 */ { MAD_F(0x06f2ea82) /* 0.434305678 */, 18 },
+ /* 6199 */ { MAD_F(0x06f34c7b) /* 0.434399110 */, 18 },
+ /* 6200 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 18 },
+ /* 6201 */ { MAD_F(0x06f41070) /* 0.434585988 */, 18 },
+ /* 6202 */ { MAD_F(0x06f4726c) /* 0.434679435 */, 18 },
+ /* 6203 */ { MAD_F(0x06f4d46a) /* 0.434772887 */, 18 },
+ /* 6204 */ { MAD_F(0x06f53669) /* 0.434866344 */, 18 },
+ /* 6205 */ { MAD_F(0x06f59869) /* 0.434959806 */, 18 },
+ /* 6206 */ { MAD_F(0x06f5fa6b) /* 0.435053272 */, 18 },
+ /* 6207 */ { MAD_F(0x06f65c6e) /* 0.435146744 */, 18 },
+
+ /* 6208 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 18 },
+ /* 6209 */ { MAD_F(0x06f72079) /* 0.435333703 */, 18 },
+ /* 6210 */ { MAD_F(0x06f78280) /* 0.435427190 */, 18 },
+ /* 6211 */ { MAD_F(0x06f7e489) /* 0.435520682 */, 18 },
+ /* 6212 */ { MAD_F(0x06f84693) /* 0.435614179 */, 18 },
+ /* 6213 */ { MAD_F(0x06f8a89e) /* 0.435707681 */, 18 },
+ /* 6214 */ { MAD_F(0x06f90aaa) /* 0.435801188 */, 18 },
+ /* 6215 */ { MAD_F(0x06f96cb8) /* 0.435894700 */, 18 },
+ /* 6216 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 18 },
+ /* 6217 */ { MAD_F(0x06fa30d8) /* 0.436081739 */, 18 },
+ /* 6218 */ { MAD_F(0x06fa92ea) /* 0.436175266 */, 18 },
+ /* 6219 */ { MAD_F(0x06faf4fe) /* 0.436268799 */, 18 },
+ /* 6220 */ { MAD_F(0x06fb5712) /* 0.436362336 */, 18 },
+ /* 6221 */ { MAD_F(0x06fbb928) /* 0.436455878 */, 18 },
+ /* 6222 */ { MAD_F(0x06fc1b40) /* 0.436549425 */, 18 },
+ /* 6223 */ { MAD_F(0x06fc7d58) /* 0.436642977 */, 18 },
+
+ /* 6224 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 18 },
+ /* 6225 */ { MAD_F(0x06fd418e) /* 0.436830096 */, 18 },
+ /* 6226 */ { MAD_F(0x06fda3ab) /* 0.436923664 */, 18 },
+ /* 6227 */ { MAD_F(0x06fe05c9) /* 0.437017236 */, 18 },
+ /* 6228 */ { MAD_F(0x06fe67e8) /* 0.437110813 */, 18 },
+ /* 6229 */ { MAD_F(0x06feca09) /* 0.437204395 */, 18 },
+ /* 6230 */ { MAD_F(0x06ff2c2b) /* 0.437297982 */, 18 },
+ /* 6231 */ { MAD_F(0x06ff8e4f) /* 0.437391575 */, 18 },
+ /* 6232 */ { MAD_F(0x06fff073) /* 0.437485172 */, 18 },
+ /* 6233 */ { MAD_F(0x0700529a) /* 0.437578774 */, 18 },
+ /* 6234 */ { MAD_F(0x0700b4c1) /* 0.437672381 */, 18 },
+ /* 6235 */ { MAD_F(0x070116ea) /* 0.437765994 */, 18 },
+ /* 6236 */ { MAD_F(0x07017914) /* 0.437859611 */, 18 },
+ /* 6237 */ { MAD_F(0x0701db40) /* 0.437953233 */, 18 },
+ /* 6238 */ { MAD_F(0x07023d6c) /* 0.438046860 */, 18 },
+ /* 6239 */ { MAD_F(0x07029f9b) /* 0.438140493 */, 18 },
+
+ /* 6240 */ { MAD_F(0x070301ca) /* 0.438234130 */, 18 },
+ /* 6241 */ { MAD_F(0x070363fb) /* 0.438327772 */, 18 },
+ /* 6242 */ { MAD_F(0x0703c62d) /* 0.438421419 */, 18 },
+ /* 6243 */ { MAD_F(0x07042861) /* 0.438515072 */, 18 },
+ /* 6244 */ { MAD_F(0x07048a96) /* 0.438608729 */, 18 },
+ /* 6245 */ { MAD_F(0x0704eccc) /* 0.438702391 */, 18 },
+ /* 6246 */ { MAD_F(0x07054f04) /* 0.438796059 */, 18 },
+ /* 6247 */ { MAD_F(0x0705b13d) /* 0.438889731 */, 18 },
+ /* 6248 */ { MAD_F(0x07061377) /* 0.438983408 */, 18 },
+ /* 6249 */ { MAD_F(0x070675b3) /* 0.439077090 */, 18 },
+ /* 6250 */ { MAD_F(0x0706d7f0) /* 0.439170778 */, 18 },
+ /* 6251 */ { MAD_F(0x07073a2e) /* 0.439264470 */, 18 },
+ /* 6252 */ { MAD_F(0x07079c6e) /* 0.439358167 */, 18 },
+ /* 6253 */ { MAD_F(0x0707feaf) /* 0.439451869 */, 18 },
+ /* 6254 */ { MAD_F(0x070860f1) /* 0.439545577 */, 18 },
+ /* 6255 */ { MAD_F(0x0708c335) /* 0.439639289 */, 18 },
+
+ /* 6256 */ { MAD_F(0x0709257a) /* 0.439733006 */, 18 },
+ /* 6257 */ { MAD_F(0x070987c0) /* 0.439826728 */, 18 },
+ /* 6258 */ { MAD_F(0x0709ea08) /* 0.439920456 */, 18 },
+ /* 6259 */ { MAD_F(0x070a4c51) /* 0.440014188 */, 18 },
+ /* 6260 */ { MAD_F(0x070aae9b) /* 0.440107925 */, 18 },
+ /* 6261 */ { MAD_F(0x070b10e7) /* 0.440201667 */, 18 },
+ /* 6262 */ { MAD_F(0x070b7334) /* 0.440295414 */, 18 },
+ /* 6263 */ { MAD_F(0x070bd583) /* 0.440389167 */, 18 },
+ /* 6264 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 18 },
+ /* 6265 */ { MAD_F(0x070c9a23) /* 0.440576686 */, 18 },
+ /* 6266 */ { MAD_F(0x070cfc76) /* 0.440670453 */, 18 },
+ /* 6267 */ { MAD_F(0x070d5eca) /* 0.440764225 */, 18 },
+ /* 6268 */ { MAD_F(0x070dc11f) /* 0.440858002 */, 18 },
+ /* 6269 */ { MAD_F(0x070e2375) /* 0.440951784 */, 18 },
+ /* 6270 */ { MAD_F(0x070e85cd) /* 0.441045572 */, 18 },
+ /* 6271 */ { MAD_F(0x070ee826) /* 0.441139364 */, 18 },
+
+ /* 6272 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 18 },
+ /* 6273 */ { MAD_F(0x070facdc) /* 0.441326963 */, 18 },
+ /* 6274 */ { MAD_F(0x07100f39) /* 0.441420770 */, 18 },
+ /* 6275 */ { MAD_F(0x07107198) /* 0.441514582 */, 18 },
+ /* 6276 */ { MAD_F(0x0710d3f8) /* 0.441608399 */, 18 },
+ /* 6277 */ { MAD_F(0x07113659) /* 0.441702221 */, 18 },
+ /* 6278 */ { MAD_F(0x071198bb) /* 0.441796048 */, 18 },
+ /* 6279 */ { MAD_F(0x0711fb1f) /* 0.441889880 */, 18 },
+ /* 6280 */ { MAD_F(0x07125d84) /* 0.441983717 */, 18 },
+ /* 6281 */ { MAD_F(0x0712bfeb) /* 0.442077559 */, 18 },
+ /* 6282 */ { MAD_F(0x07132253) /* 0.442171406 */, 18 },
+ /* 6283 */ { MAD_F(0x071384bc) /* 0.442265257 */, 18 },
+ /* 6284 */ { MAD_F(0x0713e726) /* 0.442359114 */, 18 },
+ /* 6285 */ { MAD_F(0x07144992) /* 0.442452976 */, 18 },
+ /* 6286 */ { MAD_F(0x0714abff) /* 0.442546843 */, 18 },
+ /* 6287 */ { MAD_F(0x07150e6e) /* 0.442640715 */, 18 },
+
+ /* 6288 */ { MAD_F(0x071570de) /* 0.442734592 */, 18 },
+ /* 6289 */ { MAD_F(0x0715d34f) /* 0.442828473 */, 18 },
+ /* 6290 */ { MAD_F(0x071635c1) /* 0.442922360 */, 18 },
+ /* 6291 */ { MAD_F(0x07169835) /* 0.443016252 */, 18 },
+ /* 6292 */ { MAD_F(0x0716faaa) /* 0.443110148 */, 18 },
+ /* 6293 */ { MAD_F(0x07175d21) /* 0.443204050 */, 18 },
+ /* 6294 */ { MAD_F(0x0717bf99) /* 0.443297957 */, 18 },
+ /* 6295 */ { MAD_F(0x07182212) /* 0.443391868 */, 18 },
+ /* 6296 */ { MAD_F(0x0718848d) /* 0.443485785 */, 18 },
+ /* 6297 */ { MAD_F(0x0718e709) /* 0.443579706 */, 18 },
+ /* 6298 */ { MAD_F(0x07194986) /* 0.443673633 */, 18 },
+ /* 6299 */ { MAD_F(0x0719ac04) /* 0.443767564 */, 18 },
+ /* 6300 */ { MAD_F(0x071a0e84) /* 0.443861501 */, 18 },
+ /* 6301 */ { MAD_F(0x071a7105) /* 0.443955442 */, 18 },
+ /* 6302 */ { MAD_F(0x071ad388) /* 0.444049389 */, 18 },
+ /* 6303 */ { MAD_F(0x071b360c) /* 0.444143340 */, 18 },
+
+ /* 6304 */ { MAD_F(0x071b9891) /* 0.444237296 */, 18 },
+ /* 6305 */ { MAD_F(0x071bfb18) /* 0.444331258 */, 18 },
+ /* 6306 */ { MAD_F(0x071c5d9f) /* 0.444425224 */, 18 },
+ /* 6307 */ { MAD_F(0x071cc029) /* 0.444519195 */, 18 },
+ /* 6308 */ { MAD_F(0x071d22b3) /* 0.444613171 */, 18 },
+ /* 6309 */ { MAD_F(0x071d853f) /* 0.444707153 */, 18 },
+ /* 6310 */ { MAD_F(0x071de7cc) /* 0.444801139 */, 18 },
+ /* 6311 */ { MAD_F(0x071e4a5b) /* 0.444895130 */, 18 },
+ /* 6312 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 18 },
+ /* 6313 */ { MAD_F(0x071f0f7c) /* 0.445083127 */, 18 },
+ /* 6314 */ { MAD_F(0x071f720e) /* 0.445177133 */, 18 },
+ /* 6315 */ { MAD_F(0x071fd4a2) /* 0.445271144 */, 18 },
+ /* 6316 */ { MAD_F(0x07203737) /* 0.445365160 */, 18 },
+ /* 6317 */ { MAD_F(0x072099ce) /* 0.445459181 */, 18 },
+ /* 6318 */ { MAD_F(0x0720fc66) /* 0.445553206 */, 18 },
+ /* 6319 */ { MAD_F(0x07215eff) /* 0.445647237 */, 18 },
+
+ /* 6320 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 18 },
+ /* 6321 */ { MAD_F(0x07222436) /* 0.445835314 */, 18 },
+ /* 6322 */ { MAD_F(0x072286d3) /* 0.445929359 */, 18 },
+ /* 6323 */ { MAD_F(0x0722e971) /* 0.446023410 */, 18 },
+ /* 6324 */ { MAD_F(0x07234c11) /* 0.446117466 */, 18 },
+ /* 6325 */ { MAD_F(0x0723aeb2) /* 0.446211526 */, 18 },
+ /* 6326 */ { MAD_F(0x07241155) /* 0.446305592 */, 18 },
+ /* 6327 */ { MAD_F(0x072473f9) /* 0.446399662 */, 18 },
+ /* 6328 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 18 },
+ /* 6329 */ { MAD_F(0x07253944) /* 0.446587818 */, 18 },
+ /* 6330 */ { MAD_F(0x07259bec) /* 0.446681903 */, 18 },
+ /* 6331 */ { MAD_F(0x0725fe95) /* 0.446775994 */, 18 },
+ /* 6332 */ { MAD_F(0x07266140) /* 0.446870089 */, 18 },
+ /* 6333 */ { MAD_F(0x0726c3ec) /* 0.446964189 */, 18 },
+ /* 6334 */ { MAD_F(0x07272699) /* 0.447058294 */, 18 },
+ /* 6335 */ { MAD_F(0x07278947) /* 0.447152404 */, 18 },
+
+ /* 6336 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 18 },
+ /* 6337 */ { MAD_F(0x07284ea8) /* 0.447340639 */, 18 },
+ /* 6338 */ { MAD_F(0x0728b15b) /* 0.447434764 */, 18 },
+ /* 6339 */ { MAD_F(0x0729140f) /* 0.447528894 */, 18 },
+ /* 6340 */ { MAD_F(0x072976c4) /* 0.447623029 */, 18 },
+ /* 6341 */ { MAD_F(0x0729d97a) /* 0.447717169 */, 18 },
+ /* 6342 */ { MAD_F(0x072a3c32) /* 0.447811314 */, 18 },
+ /* 6343 */ { MAD_F(0x072a9eeb) /* 0.447905463 */, 18 },
+ /* 6344 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 18 },
+ /* 6345 */ { MAD_F(0x072b6461) /* 0.448093778 */, 18 },
+ /* 6346 */ { MAD_F(0x072bc71e) /* 0.448187942 */, 18 },
+ /* 6347 */ { MAD_F(0x072c29dd) /* 0.448282112 */, 18 },
+ /* 6348 */ { MAD_F(0x072c8c9d) /* 0.448376286 */, 18 },
+ /* 6349 */ { MAD_F(0x072cef5e) /* 0.448470466 */, 18 },
+ /* 6350 */ { MAD_F(0x072d5220) /* 0.448564650 */, 18 },
+ /* 6351 */ { MAD_F(0x072db4e4) /* 0.448658839 */, 18 },
+
+ /* 6352 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 18 },
+ /* 6353 */ { MAD_F(0x072e7a6f) /* 0.448847233 */, 18 },
+ /* 6354 */ { MAD_F(0x072edd37) /* 0.448941437 */, 18 },
+ /* 6355 */ { MAD_F(0x072f4000) /* 0.449035646 */, 18 },
+ /* 6356 */ { MAD_F(0x072fa2ca) /* 0.449129860 */, 18 },
+ /* 6357 */ { MAD_F(0x07300596) /* 0.449224079 */, 18 },
+ /* 6358 */ { MAD_F(0x07306863) /* 0.449318303 */, 18 },
+ /* 6359 */ { MAD_F(0x0730cb32) /* 0.449412531 */, 18 },
+ /* 6360 */ { MAD_F(0x07312e01) /* 0.449506765 */, 18 },
+ /* 6361 */ { MAD_F(0x073190d2) /* 0.449601004 */, 18 },
+ /* 6362 */ { MAD_F(0x0731f3a5) /* 0.449695247 */, 18 },
+ /* 6363 */ { MAD_F(0x07325678) /* 0.449789496 */, 18 },
+ /* 6364 */ { MAD_F(0x0732b94d) /* 0.449883749 */, 18 },
+ /* 6365 */ { MAD_F(0x07331c23) /* 0.449978008 */, 18 },
+ /* 6366 */ { MAD_F(0x07337efb) /* 0.450072271 */, 18 },
+ /* 6367 */ { MAD_F(0x0733e1d4) /* 0.450166540 */, 18 },
+
+ /* 6368 */ { MAD_F(0x073444ae) /* 0.450260813 */, 18 },
+ /* 6369 */ { MAD_F(0x0734a78a) /* 0.450355091 */, 18 },
+ /* 6370 */ { MAD_F(0x07350a67) /* 0.450449374 */, 18 },
+ /* 6371 */ { MAD_F(0x07356d45) /* 0.450543662 */, 18 },
+ /* 6372 */ { MAD_F(0x0735d025) /* 0.450637955 */, 18 },
+ /* 6373 */ { MAD_F(0x07363306) /* 0.450732253 */, 18 },
+ /* 6374 */ { MAD_F(0x073695e8) /* 0.450826556 */, 18 },
+ /* 6375 */ { MAD_F(0x0736f8cb) /* 0.450920864 */, 18 },
+ /* 6376 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 18 },
+ /* 6377 */ { MAD_F(0x0737be96) /* 0.451109494 */, 18 },
+ /* 6378 */ { MAD_F(0x0738217e) /* 0.451203817 */, 18 },
+ /* 6379 */ { MAD_F(0x07388467) /* 0.451298144 */, 18 },
+ /* 6380 */ { MAD_F(0x0738e751) /* 0.451392477 */, 18 },
+ /* 6381 */ { MAD_F(0x07394a3d) /* 0.451486814 */, 18 },
+ /* 6382 */ { MAD_F(0x0739ad29) /* 0.451581156 */, 18 },
+ /* 6383 */ { MAD_F(0x073a1017) /* 0.451675503 */, 18 },
+
+ /* 6384 */ { MAD_F(0x073a7307) /* 0.451769856 */, 18 },
+ /* 6385 */ { MAD_F(0x073ad5f8) /* 0.451864213 */, 18 },
+ /* 6386 */ { MAD_F(0x073b38ea) /* 0.451958575 */, 18 },
+ /* 6387 */ { MAD_F(0x073b9bdd) /* 0.452052942 */, 18 },
+ /* 6388 */ { MAD_F(0x073bfed2) /* 0.452147313 */, 18 },
+ /* 6389 */ { MAD_F(0x073c61c8) /* 0.452241690 */, 18 },
+ /* 6390 */ { MAD_F(0x073cc4bf) /* 0.452336072 */, 18 },
+ /* 6391 */ { MAD_F(0x073d27b8) /* 0.452430458 */, 18 },
+ /* 6392 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 18 },
+ /* 6393 */ { MAD_F(0x073dedae) /* 0.452619246 */, 18 },
+ /* 6394 */ { MAD_F(0x073e50aa) /* 0.452713648 */, 18 },
+ /* 6395 */ { MAD_F(0x073eb3a8) /* 0.452808054 */, 18 },
+ /* 6396 */ { MAD_F(0x073f16a8) /* 0.452902465 */, 18 },
+ /* 6397 */ { MAD_F(0x073f79a8) /* 0.452996882 */, 18 },
+ /* 6398 */ { MAD_F(0x073fdcaa) /* 0.453091303 */, 18 },
+ /* 6399 */ { MAD_F(0x07403fad) /* 0.453185729 */, 18 },
+
+ /* 6400 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 18 },
+ /* 6401 */ { MAD_F(0x074105b8) /* 0.453374595 */, 18 },
+ /* 6402 */ { MAD_F(0x074168bf) /* 0.453469036 */, 18 },
+ /* 6403 */ { MAD_F(0x0741cbc8) /* 0.453563482 */, 18 },
+ /* 6404 */ { MAD_F(0x07422ed2) /* 0.453657932 */, 18 },
+ /* 6405 */ { MAD_F(0x074291dd) /* 0.453752388 */, 18 },
+ /* 6406 */ { MAD_F(0x0742f4e9) /* 0.453846848 */, 18 },
+ /* 6407 */ { MAD_F(0x074357f7) /* 0.453941314 */, 18 },
+ /* 6408 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 18 },
+ /* 6409 */ { MAD_F(0x07441e17) /* 0.454130259 */, 18 },
+ /* 6410 */ { MAD_F(0x07448129) /* 0.454224739 */, 18 },
+ /* 6411 */ { MAD_F(0x0744e43c) /* 0.454319224 */, 18 },
+ /* 6412 */ { MAD_F(0x07454750) /* 0.454413714 */, 18 },
+ /* 6413 */ { MAD_F(0x0745aa66) /* 0.454508209 */, 18 },
+ /* 6414 */ { MAD_F(0x07460d7d) /* 0.454602708 */, 18 },
+ /* 6415 */ { MAD_F(0x07467095) /* 0.454697213 */, 18 },
+
+ /* 6416 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 18 },
+ /* 6417 */ { MAD_F(0x074736ca) /* 0.454886237 */, 18 },
+ /* 6418 */ { MAD_F(0x074799e7) /* 0.454980756 */, 18 },
+ /* 6419 */ { MAD_F(0x0747fd04) /* 0.455075281 */, 18 },
+ /* 6420 */ { MAD_F(0x07486023) /* 0.455169810 */, 18 },
+ /* 6421 */ { MAD_F(0x0748c344) /* 0.455264344 */, 18 },
+ /* 6422 */ { MAD_F(0x07492665) /* 0.455358883 */, 18 },
+ /* 6423 */ { MAD_F(0x07498988) /* 0.455453427 */, 18 },
+ /* 6424 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 18 },
+ /* 6425 */ { MAD_F(0x074a4fd2) /* 0.455642529 */, 18 },
+ /* 6426 */ { MAD_F(0x074ab2f9) /* 0.455737088 */, 18 },
+ /* 6427 */ { MAD_F(0x074b1621) /* 0.455831652 */, 18 },
+ /* 6428 */ { MAD_F(0x074b794b) /* 0.455926220 */, 18 },
+ /* 6429 */ { MAD_F(0x074bdc75) /* 0.456020793 */, 18 },
+ /* 6430 */ { MAD_F(0x074c3fa1) /* 0.456115372 */, 18 },
+ /* 6431 */ { MAD_F(0x074ca2cf) /* 0.456209955 */, 18 },
+
+ /* 6432 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 18 },
+ /* 6433 */ { MAD_F(0x074d692e) /* 0.456399136 */, 18 },
+ /* 6434 */ { MAD_F(0x074dcc5f) /* 0.456493733 */, 18 },
+ /* 6435 */ { MAD_F(0x074e2f92) /* 0.456588336 */, 18 },
+ /* 6436 */ { MAD_F(0x074e92c6) /* 0.456682944 */, 18 },
+ /* 6437 */ { MAD_F(0x074ef5fb) /* 0.456777556 */, 18 },
+ /* 6438 */ { MAD_F(0x074f5932) /* 0.456872174 */, 18 },
+ /* 6439 */ { MAD_F(0x074fbc6a) /* 0.456966796 */, 18 },
+ /* 6440 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 18 },
+ /* 6441 */ { MAD_F(0x075082de) /* 0.457156056 */, 18 },
+ /* 6442 */ { MAD_F(0x0750e61a) /* 0.457250693 */, 18 },
+ /* 6443 */ { MAD_F(0x07514957) /* 0.457345335 */, 18 },
+ /* 6444 */ { MAD_F(0x0751ac96) /* 0.457439981 */, 18 },
+ /* 6445 */ { MAD_F(0x07520fd6) /* 0.457534633 */, 18 },
+ /* 6446 */ { MAD_F(0x07527317) /* 0.457629290 */, 18 },
+ /* 6447 */ { MAD_F(0x0752d659) /* 0.457723951 */, 18 },
+
+ /* 6448 */ { MAD_F(0x0753399d) /* 0.457818618 */, 18 },
+ /* 6449 */ { MAD_F(0x07539ce2) /* 0.457913289 */, 18 },
+ /* 6450 */ { MAD_F(0x07540029) /* 0.458007965 */, 18 },
+ /* 6451 */ { MAD_F(0x07546371) /* 0.458102646 */, 18 },
+ /* 6452 */ { MAD_F(0x0754c6ba) /* 0.458197332 */, 18 },
+ /* 6453 */ { MAD_F(0x07552a04) /* 0.458292023 */, 18 },
+ /* 6454 */ { MAD_F(0x07558d50) /* 0.458386719 */, 18 },
+ /* 6455 */ { MAD_F(0x0755f09d) /* 0.458481420 */, 18 },
+ /* 6456 */ { MAD_F(0x075653eb) /* 0.458576125 */, 18 },
+ /* 6457 */ { MAD_F(0x0756b73b) /* 0.458670836 */, 18 },
+ /* 6458 */ { MAD_F(0x07571a8c) /* 0.458765551 */, 18 },
+ /* 6459 */ { MAD_F(0x07577dde) /* 0.458860271 */, 18 },
+ /* 6460 */ { MAD_F(0x0757e131) /* 0.458954996 */, 18 },
+ /* 6461 */ { MAD_F(0x07584486) /* 0.459049726 */, 18 },
+ /* 6462 */ { MAD_F(0x0758a7dd) /* 0.459144461 */, 18 },
+ /* 6463 */ { MAD_F(0x07590b34) /* 0.459239201 */, 18 },
+
+ /* 6464 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 18 },
+ /* 6465 */ { MAD_F(0x0759d1e7) /* 0.459428695 */, 18 },
+ /* 6466 */ { MAD_F(0x075a3542) /* 0.459523450 */, 18 },
+ /* 6467 */ { MAD_F(0x075a989f) /* 0.459618209 */, 18 },
+ /* 6468 */ { MAD_F(0x075afbfd) /* 0.459712973 */, 18 },
+ /* 6469 */ { MAD_F(0x075b5f5d) /* 0.459807742 */, 18 },
+ /* 6470 */ { MAD_F(0x075bc2bd) /* 0.459902516 */, 18 },
+ /* 6471 */ { MAD_F(0x075c261f) /* 0.459997295 */, 18 },
+ /* 6472 */ { MAD_F(0x075c8983) /* 0.460092079 */, 18 },
+ /* 6473 */ { MAD_F(0x075cece7) /* 0.460186867 */, 18 },
+ /* 6474 */ { MAD_F(0x075d504d) /* 0.460281661 */, 18 },
+ /* 6475 */ { MAD_F(0x075db3b5) /* 0.460376459 */, 18 },
+ /* 6476 */ { MAD_F(0x075e171d) /* 0.460471262 */, 18 },
+ /* 6477 */ { MAD_F(0x075e7a87) /* 0.460566071 */, 18 },
+ /* 6478 */ { MAD_F(0x075eddf2) /* 0.460660884 */, 18 },
+ /* 6479 */ { MAD_F(0x075f415f) /* 0.460755701 */, 18 },
+
+ /* 6480 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 18 },
+ /* 6481 */ { MAD_F(0x0760083b) /* 0.460945352 */, 18 },
+ /* 6482 */ { MAD_F(0x07606bac) /* 0.461040184 */, 18 },
+ /* 6483 */ { MAD_F(0x0760cf1e) /* 0.461135022 */, 18 },
+ /* 6484 */ { MAD_F(0x07613291) /* 0.461229864 */, 18 },
+ /* 6485 */ { MAD_F(0x07619605) /* 0.461324711 */, 18 },
+ /* 6486 */ { MAD_F(0x0761f97b) /* 0.461419563 */, 18 },
+ /* 6487 */ { MAD_F(0x07625cf2) /* 0.461514420 */, 18 },
+ /* 6488 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 18 },
+ /* 6489 */ { MAD_F(0x076323e3) /* 0.461704149 */, 18 },
+ /* 6490 */ { MAD_F(0x0763875e) /* 0.461799020 */, 18 },
+ /* 6491 */ { MAD_F(0x0763eadb) /* 0.461893897 */, 18 },
+ /* 6492 */ { MAD_F(0x07644e58) /* 0.461988778 */, 18 },
+ /* 6493 */ { MAD_F(0x0764b1d7) /* 0.462083664 */, 18 },
+ /* 6494 */ { MAD_F(0x07651557) /* 0.462178555 */, 18 },
+ /* 6495 */ { MAD_F(0x076578d8) /* 0.462273451 */, 18 },
+
+ /* 6496 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 18 },
+ /* 6497 */ { MAD_F(0x07663fdf) /* 0.462463257 */, 18 },
+ /* 6498 */ { MAD_F(0x0766a364) /* 0.462558168 */, 18 },
+ /* 6499 */ { MAD_F(0x076706eb) /* 0.462653083 */, 18 },
+ /* 6500 */ { MAD_F(0x07676a73) /* 0.462748003 */, 18 },
+ /* 6501 */ { MAD_F(0x0767cdfc) /* 0.462842928 */, 18 },
+ /* 6502 */ { MAD_F(0x07683187) /* 0.462937858 */, 18 },
+ /* 6503 */ { MAD_F(0x07689513) /* 0.463032793 */, 18 },
+ /* 6504 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 18 },
+ /* 6505 */ { MAD_F(0x07695c2e) /* 0.463222678 */, 18 },
+ /* 6506 */ { MAD_F(0x0769bfbe) /* 0.463317627 */, 18 },
+ /* 6507 */ { MAD_F(0x076a234f) /* 0.463412581 */, 18 },
+ /* 6508 */ { MAD_F(0x076a86e2) /* 0.463507540 */, 18 },
+ /* 6509 */ { MAD_F(0x076aea75) /* 0.463602504 */, 18 },
+ /* 6510 */ { MAD_F(0x076b4e0a) /* 0.463697473 */, 18 },
+ /* 6511 */ { MAD_F(0x076bb1a1) /* 0.463792447 */, 18 },
+
+ /* 6512 */ { MAD_F(0x076c1538) /* 0.463887426 */, 18 },
+ /* 6513 */ { MAD_F(0x076c78d1) /* 0.463982409 */, 18 },
+ /* 6514 */ { MAD_F(0x076cdc6c) /* 0.464077398 */, 18 },
+ /* 6515 */ { MAD_F(0x076d4007) /* 0.464172391 */, 18 },
+ /* 6516 */ { MAD_F(0x076da3a4) /* 0.464267389 */, 18 },
+ /* 6517 */ { MAD_F(0x076e0742) /* 0.464362392 */, 18 },
+ /* 6518 */ { MAD_F(0x076e6ae2) /* 0.464457399 */, 18 },
+ /* 6519 */ { MAD_F(0x076ece82) /* 0.464552412 */, 18 },
+ /* 6520 */ { MAD_F(0x076f3224) /* 0.464647430 */, 18 },
+ /* 6521 */ { MAD_F(0x076f95c8) /* 0.464742452 */, 18 },
+ /* 6522 */ { MAD_F(0x076ff96c) /* 0.464837479 */, 18 },
+ /* 6523 */ { MAD_F(0x07705d12) /* 0.464932511 */, 18 },
+ /* 6524 */ { MAD_F(0x0770c0ba) /* 0.465027548 */, 18 },
+ /* 6525 */ { MAD_F(0x07712462) /* 0.465122590 */, 18 },
+ /* 6526 */ { MAD_F(0x0771880c) /* 0.465217637 */, 18 },
+ /* 6527 */ { MAD_F(0x0771ebb7) /* 0.465312688 */, 18 },
+
+ /* 6528 */ { MAD_F(0x07724f64) /* 0.465407744 */, 18 },
+ /* 6529 */ { MAD_F(0x0772b312) /* 0.465502806 */, 18 },
+ /* 6530 */ { MAD_F(0x077316c1) /* 0.465597872 */, 18 },
+ /* 6531 */ { MAD_F(0x07737a71) /* 0.465692943 */, 18 },
+ /* 6532 */ { MAD_F(0x0773de23) /* 0.465788018 */, 18 },
+ /* 6533 */ { MAD_F(0x077441d6) /* 0.465883099 */, 18 },
+ /* 6534 */ { MAD_F(0x0774a58a) /* 0.465978184 */, 18 },
+ /* 6535 */ { MAD_F(0x07750940) /* 0.466073275 */, 18 },
+ /* 6536 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 18 },
+ /* 6537 */ { MAD_F(0x0775d0af) /* 0.466263470 */, 18 },
+ /* 6538 */ { MAD_F(0x07763468) /* 0.466358575 */, 18 },
+ /* 6539 */ { MAD_F(0x07769823) /* 0.466453684 */, 18 },
+ /* 6540 */ { MAD_F(0x0776fbdf) /* 0.466548799 */, 18 },
+ /* 6541 */ { MAD_F(0x07775f9d) /* 0.466643918 */, 18 },
+ /* 6542 */ { MAD_F(0x0777c35c) /* 0.466739043 */, 18 },
+ /* 6543 */ { MAD_F(0x0778271c) /* 0.466834172 */, 18 },
+
+ /* 6544 */ { MAD_F(0x07788add) /* 0.466929306 */, 18 },
+ /* 6545 */ { MAD_F(0x0778ee9f) /* 0.467024445 */, 18 },
+ /* 6546 */ { MAD_F(0x07795263) /* 0.467119588 */, 18 },
+ /* 6547 */ { MAD_F(0x0779b629) /* 0.467214737 */, 18 },
+ /* 6548 */ { MAD_F(0x077a19ef) /* 0.467309890 */, 18 },
+ /* 6549 */ { MAD_F(0x077a7db7) /* 0.467405048 */, 18 },
+ /* 6550 */ { MAD_F(0x077ae180) /* 0.467500211 */, 18 },
+ /* 6551 */ { MAD_F(0x077b454b) /* 0.467595379 */, 18 },
+ /* 6552 */ { MAD_F(0x077ba916) /* 0.467690552 */, 18 },
+ /* 6553 */ { MAD_F(0x077c0ce3) /* 0.467785729 */, 18 },
+ /* 6554 */ { MAD_F(0x077c70b2) /* 0.467880912 */, 18 },
+ /* 6555 */ { MAD_F(0x077cd481) /* 0.467976099 */, 18 },
+ /* 6556 */ { MAD_F(0x077d3852) /* 0.468071291 */, 18 },
+ /* 6557 */ { MAD_F(0x077d9c24) /* 0.468166488 */, 18 },
+ /* 6558 */ { MAD_F(0x077dfff8) /* 0.468261690 */, 18 },
+ /* 6559 */ { MAD_F(0x077e63cd) /* 0.468356896 */, 18 },
+
+ /* 6560 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 18 },
+ /* 6561 */ { MAD_F(0x077f2b7a) /* 0.468547324 */, 18 },
+ /* 6562 */ { MAD_F(0x077f8f53) /* 0.468642545 */, 18 },
+ /* 6563 */ { MAD_F(0x077ff32d) /* 0.468737771 */, 18 },
+ /* 6564 */ { MAD_F(0x07805708) /* 0.468833002 */, 18 },
+ /* 6565 */ { MAD_F(0x0780bae5) /* 0.468928237 */, 18 },
+ /* 6566 */ { MAD_F(0x07811ec3) /* 0.469023478 */, 18 },
+ /* 6567 */ { MAD_F(0x078182a2) /* 0.469118723 */, 18 },
+ /* 6568 */ { MAD_F(0x0781e683) /* 0.469213973 */, 18 },
+ /* 6569 */ { MAD_F(0x07824a64) /* 0.469309228 */, 18 },
+ /* 6570 */ { MAD_F(0x0782ae47) /* 0.469404488 */, 18 },
+ /* 6571 */ { MAD_F(0x0783122c) /* 0.469499752 */, 18 },
+ /* 6572 */ { MAD_F(0x07837612) /* 0.469595022 */, 18 },
+ /* 6573 */ { MAD_F(0x0783d9f9) /* 0.469690296 */, 18 },
+ /* 6574 */ { MAD_F(0x07843de1) /* 0.469785575 */, 18 },
+ /* 6575 */ { MAD_F(0x0784a1ca) /* 0.469880859 */, 18 },
+
+ /* 6576 */ { MAD_F(0x078505b5) /* 0.469976148 */, 18 },
+ /* 6577 */ { MAD_F(0x078569a2) /* 0.470071442 */, 18 },
+ /* 6578 */ { MAD_F(0x0785cd8f) /* 0.470166740 */, 18 },
+ /* 6579 */ { MAD_F(0x0786317e) /* 0.470262043 */, 18 },
+ /* 6580 */ { MAD_F(0x0786956e) /* 0.470357351 */, 18 },
+ /* 6581 */ { MAD_F(0x0786f95f) /* 0.470452664 */, 18 },
+ /* 6582 */ { MAD_F(0x07875d52) /* 0.470547982 */, 18 },
+ /* 6583 */ { MAD_F(0x0787c146) /* 0.470643305 */, 18 },
+ /* 6584 */ { MAD_F(0x0788253b) /* 0.470738632 */, 18 },
+ /* 6585 */ { MAD_F(0x07888932) /* 0.470833964 */, 18 },
+ /* 6586 */ { MAD_F(0x0788ed2a) /* 0.470929301 */, 18 },
+ /* 6587 */ { MAD_F(0x07895123) /* 0.471024643 */, 18 },
+ /* 6588 */ { MAD_F(0x0789b51d) /* 0.471119990 */, 18 },
+ /* 6589 */ { MAD_F(0x078a1919) /* 0.471215341 */, 18 },
+ /* 6590 */ { MAD_F(0x078a7d16) /* 0.471310698 */, 18 },
+ /* 6591 */ { MAD_F(0x078ae114) /* 0.471406059 */, 18 },
+
+ /* 6592 */ { MAD_F(0x078b4514) /* 0.471501425 */, 18 },
+ /* 6593 */ { MAD_F(0x078ba915) /* 0.471596796 */, 18 },
+ /* 6594 */ { MAD_F(0x078c0d17) /* 0.471692171 */, 18 },
+ /* 6595 */ { MAD_F(0x078c711a) /* 0.471787552 */, 18 },
+ /* 6596 */ { MAD_F(0x078cd51f) /* 0.471882937 */, 18 },
+ /* 6597 */ { MAD_F(0x078d3925) /* 0.471978327 */, 18 },
+ /* 6598 */ { MAD_F(0x078d9d2d) /* 0.472073722 */, 18 },
+ /* 6599 */ { MAD_F(0x078e0135) /* 0.472169122 */, 18 },
+ /* 6600 */ { MAD_F(0x078e653f) /* 0.472264527 */, 18 },
+ /* 6601 */ { MAD_F(0x078ec94b) /* 0.472359936 */, 18 },
+ /* 6602 */ { MAD_F(0x078f2d57) /* 0.472455350 */, 18 },
+ /* 6603 */ { MAD_F(0x078f9165) /* 0.472550769 */, 18 },
+ /* 6604 */ { MAD_F(0x078ff574) /* 0.472646193 */, 18 },
+ /* 6605 */ { MAD_F(0x07905985) /* 0.472741622 */, 18 },
+ /* 6606 */ { MAD_F(0x0790bd96) /* 0.472837055 */, 18 },
+ /* 6607 */ { MAD_F(0x079121a9) /* 0.472932493 */, 18 },
+
+ /* 6608 */ { MAD_F(0x079185be) /* 0.473027937 */, 18 },
+ /* 6609 */ { MAD_F(0x0791e9d3) /* 0.473123384 */, 18 },
+ /* 6610 */ { MAD_F(0x07924dea) /* 0.473218837 */, 18 },
+ /* 6611 */ { MAD_F(0x0792b202) /* 0.473314295 */, 18 },
+ /* 6612 */ { MAD_F(0x0793161c) /* 0.473409757 */, 18 },
+ /* 6613 */ { MAD_F(0x07937a37) /* 0.473505224 */, 18 },
+ /* 6614 */ { MAD_F(0x0793de53) /* 0.473600696 */, 18 },
+ /* 6615 */ { MAD_F(0x07944270) /* 0.473696173 */, 18 },
+ /* 6616 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 18 },
+ /* 6617 */ { MAD_F(0x07950aaf) /* 0.473887141 */, 18 },
+ /* 6618 */ { MAD_F(0x07956ed0) /* 0.473982632 */, 18 },
+ /* 6619 */ { MAD_F(0x0795d2f2) /* 0.474078128 */, 18 },
+ /* 6620 */ { MAD_F(0x07963716) /* 0.474173629 */, 18 },
+ /* 6621 */ { MAD_F(0x07969b3b) /* 0.474269135 */, 18 },
+ /* 6622 */ { MAD_F(0x0796ff62) /* 0.474364645 */, 18 },
+ /* 6623 */ { MAD_F(0x07976389) /* 0.474460161 */, 18 },
+
+ /* 6624 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 18 },
+ /* 6625 */ { MAD_F(0x07982bdd) /* 0.474651205 */, 18 },
+ /* 6626 */ { MAD_F(0x07989008) /* 0.474746735 */, 18 },
+ /* 6627 */ { MAD_F(0x0798f435) /* 0.474842270 */, 18 },
+ /* 6628 */ { MAD_F(0x07995863) /* 0.474937809 */, 18 },
+ /* 6629 */ { MAD_F(0x0799bc92) /* 0.475033353 */, 18 },
+ /* 6630 */ { MAD_F(0x079a20c3) /* 0.475128902 */, 18 },
+ /* 6631 */ { MAD_F(0x079a84f5) /* 0.475224456 */, 18 },
+ /* 6632 */ { MAD_F(0x079ae929) /* 0.475320014 */, 18 },
+ /* 6633 */ { MAD_F(0x079b4d5d) /* 0.475415578 */, 18 },
+ /* 6634 */ { MAD_F(0x079bb193) /* 0.475511146 */, 18 },
+ /* 6635 */ { MAD_F(0x079c15ca) /* 0.475606719 */, 18 },
+ /* 6636 */ { MAD_F(0x079c7a03) /* 0.475702296 */, 18 },
+ /* 6637 */ { MAD_F(0x079cde3c) /* 0.475797879 */, 18 },
+ /* 6638 */ { MAD_F(0x079d4277) /* 0.475893466 */, 18 },
+ /* 6639 */ { MAD_F(0x079da6b4) /* 0.475989058 */, 18 },
+
+ /* 6640 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 18 },
+ /* 6641 */ { MAD_F(0x079e6f30) /* 0.476180257 */, 18 },
+ /* 6642 */ { MAD_F(0x079ed370) /* 0.476275863 */, 18 },
+ /* 6643 */ { MAD_F(0x079f37b2) /* 0.476371475 */, 18 },
+ /* 6644 */ { MAD_F(0x079f9bf5) /* 0.476467091 */, 18 },
+ /* 6645 */ { MAD_F(0x07a00039) /* 0.476562712 */, 18 },
+ /* 6646 */ { MAD_F(0x07a0647e) /* 0.476658338 */, 18 },
+ /* 6647 */ { MAD_F(0x07a0c8c5) /* 0.476753968 */, 18 },
+ /* 6648 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 18 },
+ /* 6649 */ { MAD_F(0x07a19156) /* 0.476945243 */, 18 },
+ /* 6650 */ { MAD_F(0x07a1f5a0) /* 0.477040888 */, 18 },
+ /* 6651 */ { MAD_F(0x07a259ec) /* 0.477136538 */, 18 },
+ /* 6652 */ { MAD_F(0x07a2be39) /* 0.477232193 */, 18 },
+ /* 6653 */ { MAD_F(0x07a32287) /* 0.477327852 */, 18 },
+ /* 6654 */ { MAD_F(0x07a386d7) /* 0.477423516 */, 18 },
+ /* 6655 */ { MAD_F(0x07a3eb28) /* 0.477519185 */, 18 },
+
+ /* 6656 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 18 },
+ /* 6657 */ { MAD_F(0x07a4b3ce) /* 0.477710537 */, 18 },
+ /* 6658 */ { MAD_F(0x07a51822) /* 0.477806220 */, 18 },
+ /* 6659 */ { MAD_F(0x07a57c78) /* 0.477901908 */, 18 },
+ /* 6660 */ { MAD_F(0x07a5e0d0) /* 0.477997601 */, 18 },
+ /* 6661 */ { MAD_F(0x07a64528) /* 0.478093299 */, 18 },
+ /* 6662 */ { MAD_F(0x07a6a982) /* 0.478189001 */, 18 },
+ /* 6663 */ { MAD_F(0x07a70ddd) /* 0.478284708 */, 18 },
+ /* 6664 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 18 },
+ /* 6665 */ { MAD_F(0x07a7d698) /* 0.478476137 */, 18 },
+ /* 6666 */ { MAD_F(0x07a83af7) /* 0.478571858 */, 18 },
+ /* 6667 */ { MAD_F(0x07a89f57) /* 0.478667585 */, 18 },
+ /* 6668 */ { MAD_F(0x07a903b9) /* 0.478763316 */, 18 },
+ /* 6669 */ { MAD_F(0x07a9681c) /* 0.478859052 */, 18 },
+ /* 6670 */ { MAD_F(0x07a9cc80) /* 0.478954793 */, 18 },
+ /* 6671 */ { MAD_F(0x07aa30e5) /* 0.479050538 */, 18 },
+
+ /* 6672 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 18 },
+ /* 6673 */ { MAD_F(0x07aaf9b4) /* 0.479242043 */, 18 },
+ /* 6674 */ { MAD_F(0x07ab5e1e) /* 0.479337803 */, 18 },
+ /* 6675 */ { MAD_F(0x07abc288) /* 0.479433568 */, 18 },
+ /* 6676 */ { MAD_F(0x07ac26f4) /* 0.479529337 */, 18 },
+ /* 6677 */ { MAD_F(0x07ac8b61) /* 0.479625111 */, 18 },
+ /* 6678 */ { MAD_F(0x07acefd0) /* 0.479720890 */, 18 },
+ /* 6679 */ { MAD_F(0x07ad543f) /* 0.479816674 */, 18 },
+ /* 6680 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 18 },
+ /* 6681 */ { MAD_F(0x07ae1d23) /* 0.480008256 */, 18 },
+ /* 6682 */ { MAD_F(0x07ae8196) /* 0.480104054 */, 18 },
+ /* 6683 */ { MAD_F(0x07aee60b) /* 0.480199857 */, 18 },
+ /* 6684 */ { MAD_F(0x07af4a81) /* 0.480295664 */, 18 },
+ /* 6685 */ { MAD_F(0x07afaef9) /* 0.480391477 */, 18 },
+ /* 6686 */ { MAD_F(0x07b01372) /* 0.480487294 */, 18 },
+ /* 6687 */ { MAD_F(0x07b077ec) /* 0.480583116 */, 18 },
+
+ /* 6688 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 18 },
+ /* 6689 */ { MAD_F(0x07b140e4) /* 0.480774774 */, 18 },
+ /* 6690 */ { MAD_F(0x07b1a561) /* 0.480870611 */, 18 },
+ /* 6691 */ { MAD_F(0x07b209e1) /* 0.480966452 */, 18 },
+ /* 6692 */ { MAD_F(0x07b26e61) /* 0.481062298 */, 18 },
+ /* 6693 */ { MAD_F(0x07b2d2e3) /* 0.481158148 */, 18 },
+ /* 6694 */ { MAD_F(0x07b33766) /* 0.481254004 */, 18 },
+ /* 6695 */ { MAD_F(0x07b39bea) /* 0.481349864 */, 18 },
+ /* 6696 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 18 },
+ /* 6697 */ { MAD_F(0x07b464f6) /* 0.481541598 */, 18 },
+ /* 6698 */ { MAD_F(0x07b4c97e) /* 0.481637473 */, 18 },
+ /* 6699 */ { MAD_F(0x07b52e08) /* 0.481733352 */, 18 },
+ /* 6700 */ { MAD_F(0x07b59292) /* 0.481829236 */, 18 },
+ /* 6701 */ { MAD_F(0x07b5f71e) /* 0.481925125 */, 18 },
+ /* 6702 */ { MAD_F(0x07b65bac) /* 0.482021019 */, 18 },
+ /* 6703 */ { MAD_F(0x07b6c03a) /* 0.482116917 */, 18 },
+
+ /* 6704 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 18 },
+ /* 6705 */ { MAD_F(0x07b7895b) /* 0.482308728 */, 18 },
+ /* 6706 */ { MAD_F(0x07b7eded) /* 0.482404640 */, 18 },
+ /* 6707 */ { MAD_F(0x07b85281) /* 0.482500558 */, 18 },
+ /* 6708 */ { MAD_F(0x07b8b716) /* 0.482596480 */, 18 },
+ /* 6709 */ { MAD_F(0x07b91bac) /* 0.482692407 */, 18 },
+ /* 6710 */ { MAD_F(0x07b98044) /* 0.482788339 */, 18 },
+ /* 6711 */ { MAD_F(0x07b9e4dc) /* 0.482884275 */, 18 },
+ /* 6712 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 18 },
+ /* 6713 */ { MAD_F(0x07baae12) /* 0.483076162 */, 18 },
+ /* 6714 */ { MAD_F(0x07bb12ae) /* 0.483172113 */, 18 },
+ /* 6715 */ { MAD_F(0x07bb774c) /* 0.483268069 */, 18 },
+ /* 6716 */ { MAD_F(0x07bbdbeb) /* 0.483364029 */, 18 },
+ /* 6717 */ { MAD_F(0x07bc408c) /* 0.483459994 */, 18 },
+ /* 6718 */ { MAD_F(0x07bca52d) /* 0.483555964 */, 18 },
+ /* 6719 */ { MAD_F(0x07bd09d0) /* 0.483651939 */, 18 },
+
+ /* 6720 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 18 },
+ /* 6721 */ { MAD_F(0x07bdd31a) /* 0.483843902 */, 18 },
+ /* 6722 */ { MAD_F(0x07be37c1) /* 0.483939891 */, 18 },
+ /* 6723 */ { MAD_F(0x07be9c69) /* 0.484035885 */, 18 },
+ /* 6724 */ { MAD_F(0x07bf0113) /* 0.484131883 */, 18 },
+ /* 6725 */ { MAD_F(0x07bf65bd) /* 0.484227886 */, 18 },
+ /* 6726 */ { MAD_F(0x07bfca69) /* 0.484323894 */, 18 },
+ /* 6727 */ { MAD_F(0x07c02f16) /* 0.484419907 */, 18 },
+ /* 6728 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 18 },
+ /* 6729 */ { MAD_F(0x07c0f875) /* 0.484611946 */, 18 },
+ /* 6730 */ { MAD_F(0x07c15d26) /* 0.484707973 */, 18 },
+ /* 6731 */ { MAD_F(0x07c1c1d8) /* 0.484804005 */, 18 },
+ /* 6732 */ { MAD_F(0x07c2268b) /* 0.484900041 */, 18 },
+ /* 6733 */ { MAD_F(0x07c28b40) /* 0.484996083 */, 18 },
+ /* 6734 */ { MAD_F(0x07c2eff6) /* 0.485092128 */, 18 },
+ /* 6735 */ { MAD_F(0x07c354ae) /* 0.485188179 */, 18 },
+
+ /* 6736 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 18 },
+ /* 6737 */ { MAD_F(0x07c41e21) /* 0.485380295 */, 18 },
+ /* 6738 */ { MAD_F(0x07c482dc) /* 0.485476360 */, 18 },
+ /* 6739 */ { MAD_F(0x07c4e798) /* 0.485572430 */, 18 },
+ /* 6740 */ { MAD_F(0x07c54c56) /* 0.485668504 */, 18 },
+ /* 6741 */ { MAD_F(0x07c5b115) /* 0.485764583 */, 18 },
+ /* 6742 */ { MAD_F(0x07c615d6) /* 0.485860667 */, 18 },
+ /* 6743 */ { MAD_F(0x07c67a97) /* 0.485956756 */, 18 },
+ /* 6744 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 18 },
+ /* 6745 */ { MAD_F(0x07c7441e) /* 0.486148948 */, 18 },
+ /* 6746 */ { MAD_F(0x07c7a8e4) /* 0.486245051 */, 18 },
+ /* 6747 */ { MAD_F(0x07c80daa) /* 0.486341158 */, 18 },
+ /* 6748 */ { MAD_F(0x07c87272) /* 0.486437271 */, 18 },
+ /* 6749 */ { MAD_F(0x07c8d73c) /* 0.486533388 */, 18 },
+ /* 6750 */ { MAD_F(0x07c93c06) /* 0.486629510 */, 18 },
+ /* 6751 */ { MAD_F(0x07c9a0d2) /* 0.486725637 */, 18 },
+
+ /* 6752 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 18 },
+ /* 6753 */ { MAD_F(0x07ca6a6d) /* 0.486917905 */, 18 },
+ /* 6754 */ { MAD_F(0x07cacf3d) /* 0.487014045 */, 18 },
+ /* 6755 */ { MAD_F(0x07cb340e) /* 0.487110191 */, 18 },
+ /* 6756 */ { MAD_F(0x07cb98e0) /* 0.487206342 */, 18 },
+ /* 6757 */ { MAD_F(0x07cbfdb4) /* 0.487302497 */, 18 },
+ /* 6758 */ { MAD_F(0x07cc6288) /* 0.487398657 */, 18 },
+ /* 6759 */ { MAD_F(0x07ccc75e) /* 0.487494821 */, 18 },
+ /* 6760 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 18 },
+ /* 6761 */ { MAD_F(0x07cd910e) /* 0.487687165 */, 18 },
+ /* 6762 */ { MAD_F(0x07cdf5e8) /* 0.487783344 */, 18 },
+ /* 6763 */ { MAD_F(0x07ce5ac3) /* 0.487879528 */, 18 },
+ /* 6764 */ { MAD_F(0x07cebfa0) /* 0.487975716 */, 18 },
+ /* 6765 */ { MAD_F(0x07cf247d) /* 0.488071909 */, 18 },
+ /* 6766 */ { MAD_F(0x07cf895c) /* 0.488168107 */, 18 },
+ /* 6767 */ { MAD_F(0x07cfee3c) /* 0.488264310 */, 18 },
+
+ /* 6768 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 18 },
+ /* 6769 */ { MAD_F(0x07d0b801) /* 0.488456729 */, 18 },
+ /* 6770 */ { MAD_F(0x07d11ce5) /* 0.488552946 */, 18 },
+ /* 6771 */ { MAD_F(0x07d181ca) /* 0.488649167 */, 18 },
+ /* 6772 */ { MAD_F(0x07d1e6b0) /* 0.488745394 */, 18 },
+ /* 6773 */ { MAD_F(0x07d24b98) /* 0.488841625 */, 18 },
+ /* 6774 */ { MAD_F(0x07d2b081) /* 0.488937860 */, 18 },
+ /* 6775 */ { MAD_F(0x07d3156c) /* 0.489034101 */, 18 },
+ /* 6776 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 18 },
+ /* 6777 */ { MAD_F(0x07d3df44) /* 0.489226596 */, 18 },
+ /* 6778 */ { MAD_F(0x07d44432) /* 0.489322851 */, 18 },
+ /* 6779 */ { MAD_F(0x07d4a922) /* 0.489419110 */, 18 },
+ /* 6780 */ { MAD_F(0x07d50e13) /* 0.489515375 */, 18 },
+ /* 6781 */ { MAD_F(0x07d57305) /* 0.489611643 */, 18 },
+ /* 6782 */ { MAD_F(0x07d5d7f8) /* 0.489707917 */, 18 },
+ /* 6783 */ { MAD_F(0x07d63cec) /* 0.489804195 */, 18 },
+
+ /* 6784 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 18 },
+ /* 6785 */ { MAD_F(0x07d706d9) /* 0.489996766 */, 18 },
+ /* 6786 */ { MAD_F(0x07d76bd2) /* 0.490093059 */, 18 },
+ /* 6787 */ { MAD_F(0x07d7d0cb) /* 0.490189356 */, 18 },
+ /* 6788 */ { MAD_F(0x07d835c6) /* 0.490285658 */, 18 },
+ /* 6789 */ { MAD_F(0x07d89ac2) /* 0.490381965 */, 18 },
+ /* 6790 */ { MAD_F(0x07d8ffc0) /* 0.490478277 */, 18 },
+ /* 6791 */ { MAD_F(0x07d964be) /* 0.490574593 */, 18 },
+ /* 6792 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 18 },
+ /* 6793 */ { MAD_F(0x07da2ebf) /* 0.490767239 */, 18 },
+ /* 6794 */ { MAD_F(0x07da93c2) /* 0.490863570 */, 18 },
+ /* 6795 */ { MAD_F(0x07daf8c6) /* 0.490959905 */, 18 },
+ /* 6796 */ { MAD_F(0x07db5dcb) /* 0.491056245 */, 18 },
+ /* 6797 */ { MAD_F(0x07dbc2d1) /* 0.491152589 */, 18 },
+ /* 6798 */ { MAD_F(0x07dc27d9) /* 0.491248939 */, 18 },
+ /* 6799 */ { MAD_F(0x07dc8ce1) /* 0.491345293 */, 18 },
+
+ /* 6800 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 18 },
+ /* 6801 */ { MAD_F(0x07dd56f7) /* 0.491538015 */, 18 },
+ /* 6802 */ { MAD_F(0x07ddbc04) /* 0.491634383 */, 18 },
+ /* 6803 */ { MAD_F(0x07de2111) /* 0.491730756 */, 18 },
+ /* 6804 */ { MAD_F(0x07de8621) /* 0.491827134 */, 18 },
+ /* 6805 */ { MAD_F(0x07deeb31) /* 0.491923516 */, 18 },
+ /* 6806 */ { MAD_F(0x07df5043) /* 0.492019903 */, 18 },
+ /* 6807 */ { MAD_F(0x07dfb556) /* 0.492116295 */, 18 },
+ /* 6808 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 18 },
+ /* 6809 */ { MAD_F(0x07e07f80) /* 0.492309093 */, 18 },
+ /* 6810 */ { MAD_F(0x07e0e496) /* 0.492405499 */, 18 },
+ /* 6811 */ { MAD_F(0x07e149ae) /* 0.492501909 */, 18 },
+ /* 6812 */ { MAD_F(0x07e1aec8) /* 0.492598325 */, 18 },
+ /* 6813 */ { MAD_F(0x07e213e2) /* 0.492694745 */, 18 },
+ /* 6814 */ { MAD_F(0x07e278fe) /* 0.492791170 */, 18 },
+ /* 6815 */ { MAD_F(0x07e2de1b) /* 0.492887599 */, 18 },
+
+ /* 6816 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 18 },
+ /* 6817 */ { MAD_F(0x07e3a859) /* 0.493080472 */, 18 },
+ /* 6818 */ { MAD_F(0x07e40d7a) /* 0.493176916 */, 18 },
+ /* 6819 */ { MAD_F(0x07e4729c) /* 0.493273365 */, 18 },
+ /* 6820 */ { MAD_F(0x07e4d7c0) /* 0.493369818 */, 18 },
+ /* 6821 */ { MAD_F(0x07e53ce4) /* 0.493466275 */, 18 },
+ /* 6822 */ { MAD_F(0x07e5a20a) /* 0.493562738 */, 18 },
+ /* 6823 */ { MAD_F(0x07e60732) /* 0.493659205 */, 18 },
+ /* 6824 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 18 },
+ /* 6825 */ { MAD_F(0x07e6d184) /* 0.493852154 */, 18 },
+ /* 6826 */ { MAD_F(0x07e736af) /* 0.493948635 */, 18 },
+ /* 6827 */ { MAD_F(0x07e79bdb) /* 0.494045122 */, 18 },
+ /* 6828 */ { MAD_F(0x07e80109) /* 0.494141612 */, 18 },
+ /* 6829 */ { MAD_F(0x07e86638) /* 0.494238108 */, 18 },
+ /* 6830 */ { MAD_F(0x07e8cb68) /* 0.494334608 */, 18 },
+ /* 6831 */ { MAD_F(0x07e93099) /* 0.494431113 */, 18 },
+
+ /* 6832 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 18 },
+ /* 6833 */ { MAD_F(0x07e9fb00) /* 0.494624137 */, 18 },
+ /* 6834 */ { MAD_F(0x07ea6035) /* 0.494720656 */, 18 },
+ /* 6835 */ { MAD_F(0x07eac56b) /* 0.494817180 */, 18 },
+ /* 6836 */ { MAD_F(0x07eb2aa3) /* 0.494913709 */, 18 },
+ /* 6837 */ { MAD_F(0x07eb8fdc) /* 0.495010242 */, 18 },
+ /* 6838 */ { MAD_F(0x07ebf516) /* 0.495106780 */, 18 },
+ /* 6839 */ { MAD_F(0x07ec5a51) /* 0.495203322 */, 18 },
+ /* 6840 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 18 },
+ /* 6841 */ { MAD_F(0x07ed24cc) /* 0.495396422 */, 18 },
+ /* 6842 */ { MAD_F(0x07ed8a0b) /* 0.495492978 */, 18 },
+ /* 6843 */ { MAD_F(0x07edef4c) /* 0.495589540 */, 18 },
+ /* 6844 */ { MAD_F(0x07ee548e) /* 0.495686106 */, 18 },
+ /* 6845 */ { MAD_F(0x07eeb9d1) /* 0.495782677 */, 18 },
+ /* 6846 */ { MAD_F(0x07ef1f15) /* 0.495879252 */, 18 },
+ /* 6847 */ { MAD_F(0x07ef845b) /* 0.495975833 */, 18 },
+
+ /* 6848 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 18 },
+ /* 6849 */ { MAD_F(0x07f04ee9) /* 0.496169007 */, 18 },
+ /* 6850 */ { MAD_F(0x07f0b433) /* 0.496265602 */, 18 },
+ /* 6851 */ { MAD_F(0x07f1197d) /* 0.496362201 */, 18 },
+ /* 6852 */ { MAD_F(0x07f17ec9) /* 0.496458804 */, 18 },
+ /* 6853 */ { MAD_F(0x07f1e416) /* 0.496555413 */, 18 },
+ /* 6854 */ { MAD_F(0x07f24965) /* 0.496652026 */, 18 },
+ /* 6855 */ { MAD_F(0x07f2aeb5) /* 0.496748644 */, 18 },
+ /* 6856 */ { MAD_F(0x07f31405) /* 0.496845266 */, 18 },
+ /* 6857 */ { MAD_F(0x07f37958) /* 0.496941894 */, 18 },
+ /* 6858 */ { MAD_F(0x07f3deab) /* 0.497038526 */, 18 },
+ /* 6859 */ { MAD_F(0x07f44400) /* 0.497135162 */, 18 },
+ /* 6860 */ { MAD_F(0x07f4a956) /* 0.497231804 */, 18 },
+ /* 6861 */ { MAD_F(0x07f50ead) /* 0.497328450 */, 18 },
+ /* 6862 */ { MAD_F(0x07f57405) /* 0.497425100 */, 18 },
+ /* 6863 */ { MAD_F(0x07f5d95f) /* 0.497521756 */, 18 },
+
+ /* 6864 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 18 },
+ /* 6865 */ { MAD_F(0x07f6a416) /* 0.497715081 */, 18 },
+ /* 6866 */ { MAD_F(0x07f70974) /* 0.497811750 */, 18 },
+ /* 6867 */ { MAD_F(0x07f76ed3) /* 0.497908425 */, 18 },
+ /* 6868 */ { MAD_F(0x07f7d433) /* 0.498005103 */, 18 },
+ /* 6869 */ { MAD_F(0x07f83994) /* 0.498101787 */, 18 },
+ /* 6870 */ { MAD_F(0x07f89ef7) /* 0.498198475 */, 18 },
+ /* 6871 */ { MAD_F(0x07f9045a) /* 0.498295168 */, 18 },
+ /* 6872 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 18 },
+ /* 6873 */ { MAD_F(0x07f9cf26) /* 0.498488568 */, 18 },
+ /* 6874 */ { MAD_F(0x07fa348e) /* 0.498585275 */, 18 },
+ /* 6875 */ { MAD_F(0x07fa99f6) /* 0.498681987 */, 18 },
+ /* 6876 */ { MAD_F(0x07faff60) /* 0.498778704 */, 18 },
+ /* 6877 */ { MAD_F(0x07fb64cc) /* 0.498875425 */, 18 },
+ /* 6878 */ { MAD_F(0x07fbca38) /* 0.498972150 */, 18 },
+ /* 6879 */ { MAD_F(0x07fc2fa6) /* 0.499068881 */, 18 },
+
+ /* 6880 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 18 },
+ /* 6881 */ { MAD_F(0x07fcfa86) /* 0.499262356 */, 18 },
+ /* 6882 */ { MAD_F(0x07fd5ff8) /* 0.499359101 */, 18 },
+ /* 6883 */ { MAD_F(0x07fdc56b) /* 0.499455850 */, 18 },
+ /* 6884 */ { MAD_F(0x07fe2adf) /* 0.499552604 */, 18 },
+ /* 6885 */ { MAD_F(0x07fe9054) /* 0.499649362 */, 18 },
+ /* 6886 */ { MAD_F(0x07fef5cb) /* 0.499746126 */, 18 },
+ /* 6887 */ { MAD_F(0x07ff5b43) /* 0.499842894 */, 18 },
+ /* 6888 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 18 },
+ /* 6889 */ { MAD_F(0x0400131b) /* 0.250018222 */, 19 },
+ /* 6890 */ { MAD_F(0x040045d9) /* 0.250066613 */, 19 },
+ /* 6891 */ { MAD_F(0x04007897) /* 0.250115006 */, 19 },
+ /* 6892 */ { MAD_F(0x0400ab57) /* 0.250163402 */, 19 },
+ /* 6893 */ { MAD_F(0x0400de16) /* 0.250211800 */, 19 },
+ /* 6894 */ { MAD_F(0x040110d7) /* 0.250260200 */, 19 },
+ /* 6895 */ { MAD_F(0x04014398) /* 0.250308603 */, 19 },
+
+ /* 6896 */ { MAD_F(0x04017659) /* 0.250357008 */, 19 },
+ /* 6897 */ { MAD_F(0x0401a91c) /* 0.250405415 */, 19 },
+ /* 6898 */ { MAD_F(0x0401dbdf) /* 0.250453825 */, 19 },
+ /* 6899 */ { MAD_F(0x04020ea2) /* 0.250502237 */, 19 },
+ /* 6900 */ { MAD_F(0x04024166) /* 0.250550652 */, 19 },
+ /* 6901 */ { MAD_F(0x0402742b) /* 0.250599068 */, 19 },
+ /* 6902 */ { MAD_F(0x0402a6f0) /* 0.250647488 */, 19 },
+ /* 6903 */ { MAD_F(0x0402d9b6) /* 0.250695909 */, 19 },
+ /* 6904 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 19 },
+ /* 6905 */ { MAD_F(0x04033f44) /* 0.250792759 */, 19 },
+ /* 6906 */ { MAD_F(0x0403720c) /* 0.250841187 */, 19 },
+ /* 6907 */ { MAD_F(0x0403a4d5) /* 0.250889618 */, 19 },
+ /* 6908 */ { MAD_F(0x0403d79e) /* 0.250938051 */, 19 },
+ /* 6909 */ { MAD_F(0x04040a68) /* 0.250986487 */, 19 },
+ /* 6910 */ { MAD_F(0x04043d32) /* 0.251034924 */, 19 },
+ /* 6911 */ { MAD_F(0x04046ffd) /* 0.251083365 */, 19 },
+
+ /* 6912 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 19 },
+ /* 6913 */ { MAD_F(0x0404d595) /* 0.251180252 */, 19 },
+ /* 6914 */ { MAD_F(0x04050862) /* 0.251228699 */, 19 },
+ /* 6915 */ { MAD_F(0x04053b30) /* 0.251277148 */, 19 },
+ /* 6916 */ { MAD_F(0x04056dfe) /* 0.251325600 */, 19 },
+ /* 6917 */ { MAD_F(0x0405a0cd) /* 0.251374054 */, 19 },
+ /* 6918 */ { MAD_F(0x0405d39c) /* 0.251422511 */, 19 },
+ /* 6919 */ { MAD_F(0x0406066c) /* 0.251470970 */, 19 },
+ /* 6920 */ { MAD_F(0x0406393d) /* 0.251519431 */, 19 },
+ /* 6921 */ { MAD_F(0x04066c0e) /* 0.251567894 */, 19 },
+ /* 6922 */ { MAD_F(0x04069ee0) /* 0.251616360 */, 19 },
+ /* 6923 */ { MAD_F(0x0406d1b3) /* 0.251664828 */, 19 },
+ /* 6924 */ { MAD_F(0x04070486) /* 0.251713299 */, 19 },
+ /* 6925 */ { MAD_F(0x0407375a) /* 0.251761772 */, 19 },
+ /* 6926 */ { MAD_F(0x04076a2e) /* 0.251810247 */, 19 },
+ /* 6927 */ { MAD_F(0x04079d03) /* 0.251858724 */, 19 },
+
+ /* 6928 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 19 },
+ /* 6929 */ { MAD_F(0x040802af) /* 0.251955686 */, 19 },
+ /* 6930 */ { MAD_F(0x04083586) /* 0.252004171 */, 19 },
+ /* 6931 */ { MAD_F(0x0408685e) /* 0.252052658 */, 19 },
+ /* 6932 */ { MAD_F(0x04089b36) /* 0.252101147 */, 19 },
+ /* 6933 */ { MAD_F(0x0408ce0f) /* 0.252149638 */, 19 },
+ /* 6934 */ { MAD_F(0x040900e8) /* 0.252198132 */, 19 },
+ /* 6935 */ { MAD_F(0x040933c2) /* 0.252246628 */, 19 },
+ /* 6936 */ { MAD_F(0x0409669d) /* 0.252295127 */, 19 },
+ /* 6937 */ { MAD_F(0x04099978) /* 0.252343627 */, 19 },
+ /* 6938 */ { MAD_F(0x0409cc54) /* 0.252392131 */, 19 },
+ /* 6939 */ { MAD_F(0x0409ff31) /* 0.252440636 */, 19 },
+ /* 6940 */ { MAD_F(0x040a320e) /* 0.252489144 */, 19 },
+ /* 6941 */ { MAD_F(0x040a64ec) /* 0.252537654 */, 19 },
+ /* 6942 */ { MAD_F(0x040a97cb) /* 0.252586166 */, 19 },
+ /* 6943 */ { MAD_F(0x040acaaa) /* 0.252634681 */, 19 },
+
+ /* 6944 */ { MAD_F(0x040afd89) /* 0.252683198 */, 19 },
+ /* 6945 */ { MAD_F(0x040b306a) /* 0.252731718 */, 19 },
+ /* 6946 */ { MAD_F(0x040b634b) /* 0.252780240 */, 19 },
+ /* 6947 */ { MAD_F(0x040b962c) /* 0.252828764 */, 19 },
+ /* 6948 */ { MAD_F(0x040bc90e) /* 0.252877290 */, 19 },
+ /* 6949 */ { MAD_F(0x040bfbf1) /* 0.252925819 */, 19 },
+ /* 6950 */ { MAD_F(0x040c2ed5) /* 0.252974350 */, 19 },
+ /* 6951 */ { MAD_F(0x040c61b9) /* 0.253022883 */, 19 },
+ /* 6952 */ { MAD_F(0x040c949e) /* 0.253071419 */, 19 },
+ /* 6953 */ { MAD_F(0x040cc783) /* 0.253119957 */, 19 },
+ /* 6954 */ { MAD_F(0x040cfa69) /* 0.253168498 */, 19 },
+ /* 6955 */ { MAD_F(0x040d2d4f) /* 0.253217040 */, 19 },
+ /* 6956 */ { MAD_F(0x040d6037) /* 0.253265585 */, 19 },
+ /* 6957 */ { MAD_F(0x040d931e) /* 0.253314133 */, 19 },
+ /* 6958 */ { MAD_F(0x040dc607) /* 0.253362682 */, 19 },
+ /* 6959 */ { MAD_F(0x040df8f0) /* 0.253411234 */, 19 },
+
+ /* 6960 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 19 },
+ /* 6961 */ { MAD_F(0x040e5ec4) /* 0.253508345 */, 19 },
+ /* 6962 */ { MAD_F(0x040e91af) /* 0.253556904 */, 19 },
+ /* 6963 */ { MAD_F(0x040ec49b) /* 0.253605466 */, 19 },
+ /* 6964 */ { MAD_F(0x040ef787) /* 0.253654029 */, 19 },
+ /* 6965 */ { MAD_F(0x040f2a74) /* 0.253702595 */, 19 },
+ /* 6966 */ { MAD_F(0x040f5d61) /* 0.253751164 */, 19 },
+ /* 6967 */ { MAD_F(0x040f904f) /* 0.253799734 */, 19 },
+ /* 6968 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 19 },
+ /* 6969 */ { MAD_F(0x040ff62d) /* 0.253896883 */, 19 },
+ /* 6970 */ { MAD_F(0x0410291d) /* 0.253945460 */, 19 },
+ /* 6971 */ { MAD_F(0x04105c0e) /* 0.253994040 */, 19 },
+ /* 6972 */ { MAD_F(0x04108eff) /* 0.254042622 */, 19 },
+ /* 6973 */ { MAD_F(0x0410c1f1) /* 0.254091207 */, 19 },
+ /* 6974 */ { MAD_F(0x0410f4e3) /* 0.254139794 */, 19 },
+ /* 6975 */ { MAD_F(0x041127d6) /* 0.254188383 */, 19 },
+
+ /* 6976 */ { MAD_F(0x04115aca) /* 0.254236974 */, 19 },
+ /* 6977 */ { MAD_F(0x04118dbe) /* 0.254285568 */, 19 },
+ /* 6978 */ { MAD_F(0x0411c0b3) /* 0.254334165 */, 19 },
+ /* 6979 */ { MAD_F(0x0411f3a9) /* 0.254382763 */, 19 },
+ /* 6980 */ { MAD_F(0x0412269f) /* 0.254431364 */, 19 },
+ /* 6981 */ { MAD_F(0x04125996) /* 0.254479967 */, 19 },
+ /* 6982 */ { MAD_F(0x04128c8d) /* 0.254528572 */, 19 },
+ /* 6983 */ { MAD_F(0x0412bf85) /* 0.254577180 */, 19 },
+ /* 6984 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 19 },
+ /* 6985 */ { MAD_F(0x04132577) /* 0.254674403 */, 19 },
+ /* 6986 */ { MAD_F(0x04135871) /* 0.254723017 */, 19 },
+ /* 6987 */ { MAD_F(0x04138b6c) /* 0.254771635 */, 19 },
+ /* 6988 */ { MAD_F(0x0413be67) /* 0.254820254 */, 19 },
+ /* 6989 */ { MAD_F(0x0413f163) /* 0.254868876 */, 19 },
+ /* 6990 */ { MAD_F(0x0414245f) /* 0.254917500 */, 19 },
+ /* 6991 */ { MAD_F(0x0414575c) /* 0.254966126 */, 19 },
+
+ /* 6992 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 19 },
+ /* 6993 */ { MAD_F(0x0414bd58) /* 0.255063386 */, 19 },
+ /* 6994 */ { MAD_F(0x0414f057) /* 0.255112019 */, 19 },
+ /* 6995 */ { MAD_F(0x04152356) /* 0.255160655 */, 19 },
+ /* 6996 */ { MAD_F(0x04155657) /* 0.255209292 */, 19 },
+ /* 6997 */ { MAD_F(0x04158957) /* 0.255257933 */, 19 },
+ /* 6998 */ { MAD_F(0x0415bc59) /* 0.255306575 */, 19 },
+ /* 6999 */ { MAD_F(0x0415ef5b) /* 0.255355220 */, 19 },
+ /* 7000 */ { MAD_F(0x0416225d) /* 0.255403867 */, 19 },
+ /* 7001 */ { MAD_F(0x04165561) /* 0.255452517 */, 19 },
+ /* 7002 */ { MAD_F(0x04168864) /* 0.255501169 */, 19 },
+ /* 7003 */ { MAD_F(0x0416bb69) /* 0.255549823 */, 19 },
+ /* 7004 */ { MAD_F(0x0416ee6e) /* 0.255598479 */, 19 },
+ /* 7005 */ { MAD_F(0x04172174) /* 0.255647138 */, 19 },
+ /* 7006 */ { MAD_F(0x0417547a) /* 0.255695799 */, 19 },
+ /* 7007 */ { MAD_F(0x04178781) /* 0.255744463 */, 19 },
+
+ /* 7008 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 19 },
+ /* 7009 */ { MAD_F(0x0417ed91) /* 0.255841796 */, 19 },
+ /* 7010 */ { MAD_F(0x0418209a) /* 0.255890467 */, 19 },
+ /* 7011 */ { MAD_F(0x041853a3) /* 0.255939139 */, 19 },
+ /* 7012 */ { MAD_F(0x041886ad) /* 0.255987814 */, 19 },
+ /* 7013 */ { MAD_F(0x0418b9b8) /* 0.256036492 */, 19 },
+ /* 7014 */ { MAD_F(0x0418ecc3) /* 0.256085171 */, 19 },
+ /* 7015 */ { MAD_F(0x04191fcf) /* 0.256133853 */, 19 },
+ /* 7016 */ { MAD_F(0x041952dc) /* 0.256182537 */, 19 },
+ /* 7017 */ { MAD_F(0x041985e9) /* 0.256231224 */, 19 },
+ /* 7018 */ { MAD_F(0x0419b8f7) /* 0.256279913 */, 19 },
+ /* 7019 */ { MAD_F(0x0419ec05) /* 0.256328604 */, 19 },
+ /* 7020 */ { MAD_F(0x041a1f15) /* 0.256377297 */, 19 },
+ /* 7021 */ { MAD_F(0x041a5224) /* 0.256425993 */, 19 },
+ /* 7022 */ { MAD_F(0x041a8534) /* 0.256474691 */, 19 },
+ /* 7023 */ { MAD_F(0x041ab845) /* 0.256523392 */, 19 },
+
+ /* 7024 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 19 },
+ /* 7025 */ { MAD_F(0x041b1e69) /* 0.256620800 */, 19 },
+ /* 7026 */ { MAD_F(0x041b517c) /* 0.256669507 */, 19 },
+ /* 7027 */ { MAD_F(0x041b848f) /* 0.256718217 */, 19 },
+ /* 7028 */ { MAD_F(0x041bb7a3) /* 0.256766929 */, 19 },
+ /* 7029 */ { MAD_F(0x041beab8) /* 0.256815643 */, 19 },
+ /* 7030 */ { MAD_F(0x041c1dcd) /* 0.256864359 */, 19 },
+ /* 7031 */ { MAD_F(0x041c50e3) /* 0.256913078 */, 19 },
+ /* 7032 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 19 },
+ /* 7033 */ { MAD_F(0x041cb711) /* 0.257010523 */, 19 },
+ /* 7034 */ { MAD_F(0x041cea28) /* 0.257059249 */, 19 },
+ /* 7035 */ { MAD_F(0x041d1d41) /* 0.257107977 */, 19 },
+ /* 7036 */ { MAD_F(0x041d505a) /* 0.257156708 */, 19 },
+ /* 7037 */ { MAD_F(0x041d8373) /* 0.257205440 */, 19 },
+ /* 7038 */ { MAD_F(0x041db68e) /* 0.257254175 */, 19 },
+ /* 7039 */ { MAD_F(0x041de9a8) /* 0.257302913 */, 19 },
+
+ /* 7040 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 19 },
+ /* 7041 */ { MAD_F(0x041e4fe0) /* 0.257400394 */, 19 },
+ /* 7042 */ { MAD_F(0x041e82fd) /* 0.257449139 */, 19 },
+ /* 7043 */ { MAD_F(0x041eb61a) /* 0.257497885 */, 19 },
+ /* 7044 */ { MAD_F(0x041ee938) /* 0.257546634 */, 19 },
+ /* 7045 */ { MAD_F(0x041f1c57) /* 0.257595386 */, 19 },
+ /* 7046 */ { MAD_F(0x041f4f76) /* 0.257644139 */, 19 },
+ /* 7047 */ { MAD_F(0x041f8296) /* 0.257692895 */, 19 },
+ /* 7048 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 19 },
+ /* 7049 */ { MAD_F(0x041fe8d7) /* 0.257790414 */, 19 },
+ /* 7050 */ { MAD_F(0x04201bf9) /* 0.257839176 */, 19 },
+ /* 7051 */ { MAD_F(0x04204f1b) /* 0.257887941 */, 19 },
+ /* 7052 */ { MAD_F(0x0420823e) /* 0.257936709 */, 19 },
+ /* 7053 */ { MAD_F(0x0420b561) /* 0.257985478 */, 19 },
+ /* 7054 */ { MAD_F(0x0420e885) /* 0.258034250 */, 19 },
+ /* 7055 */ { MAD_F(0x04211baa) /* 0.258083025 */, 19 },
+
+ /* 7056 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 19 },
+ /* 7057 */ { MAD_F(0x042181f6) /* 0.258180580 */, 19 },
+ /* 7058 */ { MAD_F(0x0421b51c) /* 0.258229361 */, 19 },
+ /* 7059 */ { MAD_F(0x0421e843) /* 0.258278145 */, 19 },
+ /* 7060 */ { MAD_F(0x04221b6b) /* 0.258326931 */, 19 },
+ /* 7061 */ { MAD_F(0x04224e94) /* 0.258375719 */, 19 },
+ /* 7062 */ { MAD_F(0x042281bd) /* 0.258424509 */, 19 },
+ /* 7063 */ { MAD_F(0x0422b4e6) /* 0.258473302 */, 19 },
+ /* 7064 */ { MAD_F(0x0422e811) /* 0.258522097 */, 19 },
+ /* 7065 */ { MAD_F(0x04231b3c) /* 0.258570894 */, 19 },
+ /* 7066 */ { MAD_F(0x04234e67) /* 0.258619694 */, 19 },
+ /* 7067 */ { MAD_F(0x04238193) /* 0.258668496 */, 19 },
+ /* 7068 */ { MAD_F(0x0423b4c0) /* 0.258717300 */, 19 },
+ /* 7069 */ { MAD_F(0x0423e7ee) /* 0.258766106 */, 19 },
+ /* 7070 */ { MAD_F(0x04241b1c) /* 0.258814915 */, 19 },
+ /* 7071 */ { MAD_F(0x04244e4a) /* 0.258863726 */, 19 },
+
+ /* 7072 */ { MAD_F(0x04248179) /* 0.258912540 */, 19 },
+ /* 7073 */ { MAD_F(0x0424b4a9) /* 0.258961356 */, 19 },
+ /* 7074 */ { MAD_F(0x0424e7da) /* 0.259010174 */, 19 },
+ /* 7075 */ { MAD_F(0x04251b0b) /* 0.259058994 */, 19 },
+ /* 7076 */ { MAD_F(0x04254e3d) /* 0.259107817 */, 19 },
+ /* 7077 */ { MAD_F(0x0425816f) /* 0.259156642 */, 19 },
+ /* 7078 */ { MAD_F(0x0425b4a2) /* 0.259205469 */, 19 },
+ /* 7079 */ { MAD_F(0x0425e7d6) /* 0.259254298 */, 19 },
+ /* 7080 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 19 },
+ /* 7081 */ { MAD_F(0x04264e3f) /* 0.259351964 */, 19 },
+ /* 7082 */ { MAD_F(0x04268174) /* 0.259400801 */, 19 },
+ /* 7083 */ { MAD_F(0x0426b4aa) /* 0.259449639 */, 19 },
+ /* 7084 */ { MAD_F(0x0426e7e1) /* 0.259498480 */, 19 },
+ /* 7085 */ { MAD_F(0x04271b18) /* 0.259547324 */, 19 },
+ /* 7086 */ { MAD_F(0x04274e50) /* 0.259596169 */, 19 },
+ /* 7087 */ { MAD_F(0x04278188) /* 0.259645017 */, 19 },
+
+ /* 7088 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 19 },
+ /* 7089 */ { MAD_F(0x0427e7fb) /* 0.259742720 */, 19 },
+ /* 7090 */ { MAD_F(0x04281b36) /* 0.259791575 */, 19 },
+ /* 7091 */ { MAD_F(0x04284e71) /* 0.259840432 */, 19 },
+ /* 7092 */ { MAD_F(0x042881ac) /* 0.259889291 */, 19 },
+ /* 7093 */ { MAD_F(0x0428b4e8) /* 0.259938153 */, 19 },
+ /* 7094 */ { MAD_F(0x0428e825) /* 0.259987017 */, 19 },
+ /* 7095 */ { MAD_F(0x04291b63) /* 0.260035883 */, 19 },
+ /* 7096 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 19 },
+ /* 7097 */ { MAD_F(0x042981df) /* 0.260133623 */, 19 },
+ /* 7098 */ { MAD_F(0x0429b51f) /* 0.260182496 */, 19 },
+ /* 7099 */ { MAD_F(0x0429e85f) /* 0.260231372 */, 19 },
+ /* 7100 */ { MAD_F(0x042a1b9f) /* 0.260280249 */, 19 },
+ /* 7101 */ { MAD_F(0x042a4ee0) /* 0.260329129 */, 19 },
+ /* 7102 */ { MAD_F(0x042a8222) /* 0.260378012 */, 19 },
+ /* 7103 */ { MAD_F(0x042ab564) /* 0.260426896 */, 19 },
+
+ /* 7104 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 19 },
+ /* 7105 */ { MAD_F(0x042b1beb) /* 0.260524673 */, 19 },
+ /* 7106 */ { MAD_F(0x042b4f2f) /* 0.260573564 */, 19 },
+ /* 7107 */ { MAD_F(0x042b8274) /* 0.260622458 */, 19 },
+ /* 7108 */ { MAD_F(0x042bb5ba) /* 0.260671354 */, 19 },
+ /* 7109 */ { MAD_F(0x042be900) /* 0.260720252 */, 19 },
+ /* 7110 */ { MAD_F(0x042c1c46) /* 0.260769153 */, 19 },
+ /* 7111 */ { MAD_F(0x042c4f8e) /* 0.260818056 */, 19 },
+ /* 7112 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 19 },
+ /* 7113 */ { MAD_F(0x042cb61e) /* 0.260915869 */, 19 },
+ /* 7114 */ { MAD_F(0x042ce967) /* 0.260964779 */, 19 },
+ /* 7115 */ { MAD_F(0x042d1cb1) /* 0.261013691 */, 19 },
+ /* 7116 */ { MAD_F(0x042d4ffb) /* 0.261062606 */, 19 },
+ /* 7117 */ { MAD_F(0x042d8346) /* 0.261111522 */, 19 },
+ /* 7118 */ { MAD_F(0x042db692) /* 0.261160441 */, 19 },
+ /* 7119 */ { MAD_F(0x042de9de) /* 0.261209363 */, 19 },
+
+ /* 7120 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 19 },
+ /* 7121 */ { MAD_F(0x042e5078) /* 0.261307212 */, 19 },
+ /* 7122 */ { MAD_F(0x042e83c6) /* 0.261356140 */, 19 },
+ /* 7123 */ { MAD_F(0x042eb715) /* 0.261405071 */, 19 },
+ /* 7124 */ { MAD_F(0x042eea64) /* 0.261454004 */, 19 },
+ /* 7125 */ { MAD_F(0x042f1db4) /* 0.261502939 */, 19 },
+ /* 7126 */ { MAD_F(0x042f5105) /* 0.261551876 */, 19 },
+ /* 7127 */ { MAD_F(0x042f8456) /* 0.261600816 */, 19 },
+ /* 7128 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 19 },
+ /* 7129 */ { MAD_F(0x042feafa) /* 0.261698702 */, 19 },
+ /* 7130 */ { MAD_F(0x04301e4d) /* 0.261747649 */, 19 },
+ /* 7131 */ { MAD_F(0x043051a1) /* 0.261796597 */, 19 },
+ /* 7132 */ { MAD_F(0x043084f5) /* 0.261845548 */, 19 },
+ /* 7133 */ { MAD_F(0x0430b84a) /* 0.261894502 */, 19 },
+ /* 7134 */ { MAD_F(0x0430eb9f) /* 0.261943458 */, 19 },
+ /* 7135 */ { MAD_F(0x04311ef5) /* 0.261992416 */, 19 },
+
+ /* 7136 */ { MAD_F(0x0431524c) /* 0.262041376 */, 19 },
+ /* 7137 */ { MAD_F(0x043185a3) /* 0.262090338 */, 19 },
+ /* 7138 */ { MAD_F(0x0431b8fb) /* 0.262139303 */, 19 },
+ /* 7139 */ { MAD_F(0x0431ec54) /* 0.262188270 */, 19 },
+ /* 7140 */ { MAD_F(0x04321fad) /* 0.262237240 */, 19 },
+ /* 7141 */ { MAD_F(0x04325306) /* 0.262286211 */, 19 },
+ /* 7142 */ { MAD_F(0x04328661) /* 0.262335185 */, 19 },
+ /* 7143 */ { MAD_F(0x0432b9bc) /* 0.262384162 */, 19 },
+ /* 7144 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 19 },
+ /* 7145 */ { MAD_F(0x04332074) /* 0.262482121 */, 19 },
+ /* 7146 */ { MAD_F(0x043353d0) /* 0.262531104 */, 19 },
+ /* 7147 */ { MAD_F(0x0433872e) /* 0.262580089 */, 19 },
+ /* 7148 */ { MAD_F(0x0433ba8c) /* 0.262629077 */, 19 },
+ /* 7149 */ { MAD_F(0x0433edea) /* 0.262678067 */, 19 },
+ /* 7150 */ { MAD_F(0x0434214a) /* 0.262727059 */, 19 },
+ /* 7151 */ { MAD_F(0x043454aa) /* 0.262776054 */, 19 },
+
+ /* 7152 */ { MAD_F(0x0434880a) /* 0.262825051 */, 19 },
+ /* 7153 */ { MAD_F(0x0434bb6b) /* 0.262874050 */, 19 },
+ /* 7154 */ { MAD_F(0x0434eecd) /* 0.262923051 */, 19 },
+ /* 7155 */ { MAD_F(0x0435222f) /* 0.262972055 */, 19 },
+ /* 7156 */ { MAD_F(0x04355592) /* 0.263021061 */, 19 },
+ /* 7157 */ { MAD_F(0x043588f6) /* 0.263070069 */, 19 },
+ /* 7158 */ { MAD_F(0x0435bc5a) /* 0.263119079 */, 19 },
+ /* 7159 */ { MAD_F(0x0435efbf) /* 0.263168092 */, 19 },
+ /* 7160 */ { MAD_F(0x04362324) /* 0.263217107 */, 19 },
+ /* 7161 */ { MAD_F(0x0436568a) /* 0.263266125 */, 19 },
+ /* 7162 */ { MAD_F(0x043689f1) /* 0.263315144 */, 19 },
+ /* 7163 */ { MAD_F(0x0436bd58) /* 0.263364166 */, 19 },
+ /* 7164 */ { MAD_F(0x0436f0c0) /* 0.263413191 */, 19 },
+ /* 7165 */ { MAD_F(0x04372428) /* 0.263462217 */, 19 },
+ /* 7166 */ { MAD_F(0x04375791) /* 0.263511246 */, 19 },
+ /* 7167 */ { MAD_F(0x04378afb) /* 0.263560277 */, 19 },
+
+ /* 7168 */ { MAD_F(0x0437be65) /* 0.263609310 */, 19 },
+ /* 7169 */ { MAD_F(0x0437f1d0) /* 0.263658346 */, 19 },
+ /* 7170 */ { MAD_F(0x0438253c) /* 0.263707384 */, 19 },
+ /* 7171 */ { MAD_F(0x043858a8) /* 0.263756424 */, 19 },
+ /* 7172 */ { MAD_F(0x04388c14) /* 0.263805466 */, 19 },
+ /* 7173 */ { MAD_F(0x0438bf82) /* 0.263854511 */, 19 },
+ /* 7174 */ { MAD_F(0x0438f2f0) /* 0.263903558 */, 19 },
+ /* 7175 */ { MAD_F(0x0439265e) /* 0.263952607 */, 19 },
+ /* 7176 */ { MAD_F(0x043959cd) /* 0.264001659 */, 19 },
+ /* 7177 */ { MAD_F(0x04398d3d) /* 0.264050713 */, 19 },
+ /* 7178 */ { MAD_F(0x0439c0ae) /* 0.264099769 */, 19 },
+ /* 7179 */ { MAD_F(0x0439f41f) /* 0.264148827 */, 19 },
+ /* 7180 */ { MAD_F(0x043a2790) /* 0.264197888 */, 19 },
+ /* 7181 */ { MAD_F(0x043a5b02) /* 0.264246951 */, 19 },
+ /* 7182 */ { MAD_F(0x043a8e75) /* 0.264296016 */, 19 },
+ /* 7183 */ { MAD_F(0x043ac1e9) /* 0.264345084 */, 19 },
+
+ /* 7184 */ { MAD_F(0x043af55d) /* 0.264394153 */, 19 },
+ /* 7185 */ { MAD_F(0x043b28d2) /* 0.264443225 */, 19 },
+ /* 7186 */ { MAD_F(0x043b5c47) /* 0.264492300 */, 19 },
+ /* 7187 */ { MAD_F(0x043b8fbd) /* 0.264541376 */, 19 },
+ /* 7188 */ { MAD_F(0x043bc333) /* 0.264590455 */, 19 },
+ /* 7189 */ { MAD_F(0x043bf6aa) /* 0.264639536 */, 19 },
+ /* 7190 */ { MAD_F(0x043c2a22) /* 0.264688620 */, 19 },
+ /* 7191 */ { MAD_F(0x043c5d9a) /* 0.264737706 */, 19 },
+ /* 7192 */ { MAD_F(0x043c9113) /* 0.264786794 */, 19 },
+ /* 7193 */ { MAD_F(0x043cc48d) /* 0.264835884 */, 19 },
+ /* 7194 */ { MAD_F(0x043cf807) /* 0.264884976 */, 19 },
+ /* 7195 */ { MAD_F(0x043d2b82) /* 0.264934071 */, 19 },
+ /* 7196 */ { MAD_F(0x043d5efd) /* 0.264983168 */, 19 },
+ /* 7197 */ { MAD_F(0x043d9279) /* 0.265032268 */, 19 },
+ /* 7198 */ { MAD_F(0x043dc5f6) /* 0.265081369 */, 19 },
+ /* 7199 */ { MAD_F(0x043df973) /* 0.265130473 */, 19 },
+
+ /* 7200 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 19 },
+ /* 7201 */ { MAD_F(0x043e6070) /* 0.265228688 */, 19 },
+ /* 7202 */ { MAD_F(0x043e93ef) /* 0.265277799 */, 19 },
+ /* 7203 */ { MAD_F(0x043ec76e) /* 0.265326912 */, 19 },
+ /* 7204 */ { MAD_F(0x043efaef) /* 0.265376027 */, 19 },
+ /* 7205 */ { MAD_F(0x043f2e6f) /* 0.265425145 */, 19 },
+ /* 7206 */ { MAD_F(0x043f61f1) /* 0.265474264 */, 19 },
+ /* 7207 */ { MAD_F(0x043f9573) /* 0.265523387 */, 19 },
+ /* 7208 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 19 },
+ /* 7209 */ { MAD_F(0x043ffc79) /* 0.265621638 */, 19 },
+ /* 7210 */ { MAD_F(0x04402ffd) /* 0.265670766 */, 19 },
+ /* 7211 */ { MAD_F(0x04406382) /* 0.265719898 */, 19 },
+ /* 7212 */ { MAD_F(0x04409707) /* 0.265769031 */, 19 },
+ /* 7213 */ { MAD_F(0x0440ca8d) /* 0.265818167 */, 19 },
+ /* 7214 */ { MAD_F(0x0440fe13) /* 0.265867305 */, 19 },
+ /* 7215 */ { MAD_F(0x0441319a) /* 0.265916445 */, 19 },
+
+ /* 7216 */ { MAD_F(0x04416522) /* 0.265965588 */, 19 },
+ /* 7217 */ { MAD_F(0x044198aa) /* 0.266014732 */, 19 },
+ /* 7218 */ { MAD_F(0x0441cc33) /* 0.266063880 */, 19 },
+ /* 7219 */ { MAD_F(0x0441ffbc) /* 0.266113029 */, 19 },
+ /* 7220 */ { MAD_F(0x04423346) /* 0.266162181 */, 19 },
+ /* 7221 */ { MAD_F(0x044266d1) /* 0.266211334 */, 19 },
+ /* 7222 */ { MAD_F(0x04429a5c) /* 0.266260491 */, 19 },
+ /* 7223 */ { MAD_F(0x0442cde8) /* 0.266309649 */, 19 },
+ /* 7224 */ { MAD_F(0x04430174) /* 0.266358810 */, 19 },
+ /* 7225 */ { MAD_F(0x04433501) /* 0.266407973 */, 19 },
+ /* 7226 */ { MAD_F(0x0443688f) /* 0.266457138 */, 19 },
+ /* 7227 */ { MAD_F(0x04439c1d) /* 0.266506305 */, 19 },
+ /* 7228 */ { MAD_F(0x0443cfac) /* 0.266555475 */, 19 },
+ /* 7229 */ { MAD_F(0x0444033c) /* 0.266604647 */, 19 },
+ /* 7230 */ { MAD_F(0x044436cc) /* 0.266653822 */, 19 },
+ /* 7231 */ { MAD_F(0x04446a5d) /* 0.266702998 */, 19 },
+
+ /* 7232 */ { MAD_F(0x04449dee) /* 0.266752177 */, 19 },
+ /* 7233 */ { MAD_F(0x0444d180) /* 0.266801358 */, 19 },
+ /* 7234 */ { MAD_F(0x04450513) /* 0.266850541 */, 19 },
+ /* 7235 */ { MAD_F(0x044538a6) /* 0.266899727 */, 19 },
+ /* 7236 */ { MAD_F(0x04456c39) /* 0.266948915 */, 19 },
+ /* 7237 */ { MAD_F(0x04459fce) /* 0.266998105 */, 19 },
+ /* 7238 */ { MAD_F(0x0445d363) /* 0.267047298 */, 19 },
+ /* 7239 */ { MAD_F(0x044606f8) /* 0.267096492 */, 19 },
+ /* 7240 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 19 },
+ /* 7241 */ { MAD_F(0x04466e25) /* 0.267194888 */, 19 },
+ /* 7242 */ { MAD_F(0x0446a1bd) /* 0.267244090 */, 19 },
+ /* 7243 */ { MAD_F(0x0446d555) /* 0.267293294 */, 19 },
+ /* 7244 */ { MAD_F(0x044708ee) /* 0.267342500 */, 19 },
+ /* 7245 */ { MAD_F(0x04473c87) /* 0.267391708 */, 19 },
+ /* 7246 */ { MAD_F(0x04477021) /* 0.267440919 */, 19 },
+ /* 7247 */ { MAD_F(0x0447a3bb) /* 0.267490131 */, 19 },
+
+ /* 7248 */ { MAD_F(0x0447d756) /* 0.267539347 */, 19 },
+ /* 7249 */ { MAD_F(0x04480af2) /* 0.267588564 */, 19 },
+ /* 7250 */ { MAD_F(0x04483e8e) /* 0.267637783 */, 19 },
+ /* 7251 */ { MAD_F(0x0448722b) /* 0.267687005 */, 19 },
+ /* 7252 */ { MAD_F(0x0448a5c9) /* 0.267736229 */, 19 },
+ /* 7253 */ { MAD_F(0x0448d967) /* 0.267785456 */, 19 },
+ /* 7254 */ { MAD_F(0x04490d05) /* 0.267834685 */, 19 },
+ /* 7255 */ { MAD_F(0x044940a5) /* 0.267883915 */, 19 },
+ /* 7256 */ { MAD_F(0x04497445) /* 0.267933149 */, 19 },
+ /* 7257 */ { MAD_F(0x0449a7e5) /* 0.267982384 */, 19 },
+ /* 7258 */ { MAD_F(0x0449db86) /* 0.268031622 */, 19 },
+ /* 7259 */ { MAD_F(0x044a0f28) /* 0.268080862 */, 19 },
+ /* 7260 */ { MAD_F(0x044a42ca) /* 0.268130104 */, 19 },
+ /* 7261 */ { MAD_F(0x044a766d) /* 0.268179349 */, 19 },
+ /* 7262 */ { MAD_F(0x044aaa11) /* 0.268228595 */, 19 },
+ /* 7263 */ { MAD_F(0x044addb5) /* 0.268277844 */, 19 },
+
+ /* 7264 */ { MAD_F(0x044b115a) /* 0.268327096 */, 19 },
+ /* 7265 */ { MAD_F(0x044b44ff) /* 0.268376349 */, 19 },
+ /* 7266 */ { MAD_F(0x044b78a5) /* 0.268425605 */, 19 },
+ /* 7267 */ { MAD_F(0x044bac4c) /* 0.268474863 */, 19 },
+ /* 7268 */ { MAD_F(0x044bdff3) /* 0.268524123 */, 19 },
+ /* 7269 */ { MAD_F(0x044c139b) /* 0.268573386 */, 19 },
+ /* 7270 */ { MAD_F(0x044c4743) /* 0.268622651 */, 19 },
+ /* 7271 */ { MAD_F(0x044c7aec) /* 0.268671918 */, 19 },
+ /* 7272 */ { MAD_F(0x044cae96) /* 0.268721187 */, 19 },
+ /* 7273 */ { MAD_F(0x044ce240) /* 0.268770459 */, 19 },
+ /* 7274 */ { MAD_F(0x044d15eb) /* 0.268819733 */, 19 },
+ /* 7275 */ { MAD_F(0x044d4997) /* 0.268869009 */, 19 },
+ /* 7276 */ { MAD_F(0x044d7d43) /* 0.268918287 */, 19 },
+ /* 7277 */ { MAD_F(0x044db0ef) /* 0.268967568 */, 19 },
+ /* 7278 */ { MAD_F(0x044de49d) /* 0.269016851 */, 19 },
+ /* 7279 */ { MAD_F(0x044e184b) /* 0.269066136 */, 19 },
+
+ /* 7280 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 19 },
+ /* 7281 */ { MAD_F(0x044e7fa8) /* 0.269164713 */, 19 },
+ /* 7282 */ { MAD_F(0x044eb358) /* 0.269214005 */, 19 },
+ /* 7283 */ { MAD_F(0x044ee708) /* 0.269263299 */, 19 },
+ /* 7284 */ { MAD_F(0x044f1ab9) /* 0.269312595 */, 19 },
+ /* 7285 */ { MAD_F(0x044f4e6b) /* 0.269361894 */, 19 },
+ /* 7286 */ { MAD_F(0x044f821d) /* 0.269411195 */, 19 },
+ /* 7287 */ { MAD_F(0x044fb5cf) /* 0.269460498 */, 19 },
+ /* 7288 */ { MAD_F(0x044fe983) /* 0.269509804 */, 19 },
+ /* 7289 */ { MAD_F(0x04501d37) /* 0.269559111 */, 19 },
+ /* 7290 */ { MAD_F(0x045050eb) /* 0.269608421 */, 19 },
+ /* 7291 */ { MAD_F(0x045084a0) /* 0.269657734 */, 19 },
+ /* 7292 */ { MAD_F(0x0450b856) /* 0.269707048 */, 19 },
+ /* 7293 */ { MAD_F(0x0450ec0d) /* 0.269756365 */, 19 },
+ /* 7294 */ { MAD_F(0x04511fc4) /* 0.269805684 */, 19 },
+ /* 7295 */ { MAD_F(0x0451537b) /* 0.269855005 */, 19 },
+
+ /* 7296 */ { MAD_F(0x04518733) /* 0.269904329 */, 19 },
+ /* 7297 */ { MAD_F(0x0451baec) /* 0.269953654 */, 19 },
+ /* 7298 */ { MAD_F(0x0451eea5) /* 0.270002982 */, 19 },
+ /* 7299 */ { MAD_F(0x0452225f) /* 0.270052313 */, 19 },
+ /* 7300 */ { MAD_F(0x0452561a) /* 0.270101645 */, 19 },
+ /* 7301 */ { MAD_F(0x045289d5) /* 0.270150980 */, 19 },
+ /* 7302 */ { MAD_F(0x0452bd91) /* 0.270200317 */, 19 },
+ /* 7303 */ { MAD_F(0x0452f14d) /* 0.270249656 */, 19 },
+ /* 7304 */ { MAD_F(0x0453250a) /* 0.270298998 */, 19 },
+ /* 7305 */ { MAD_F(0x045358c8) /* 0.270348341 */, 19 },
+ /* 7306 */ { MAD_F(0x04538c86) /* 0.270397687 */, 19 },
+ /* 7307 */ { MAD_F(0x0453c045) /* 0.270447036 */, 19 },
+ /* 7308 */ { MAD_F(0x0453f405) /* 0.270496386 */, 19 },
+ /* 7309 */ { MAD_F(0x045427c5) /* 0.270545739 */, 19 },
+ /* 7310 */ { MAD_F(0x04545b85) /* 0.270595094 */, 19 },
+ /* 7311 */ { MAD_F(0x04548f46) /* 0.270644451 */, 19 },
+
+ /* 7312 */ { MAD_F(0x0454c308) /* 0.270693811 */, 19 },
+ /* 7313 */ { MAD_F(0x0454f6cb) /* 0.270743173 */, 19 },
+ /* 7314 */ { MAD_F(0x04552a8e) /* 0.270792537 */, 19 },
+ /* 7315 */ { MAD_F(0x04555e51) /* 0.270841903 */, 19 },
+ /* 7316 */ { MAD_F(0x04559216) /* 0.270891271 */, 19 },
+ /* 7317 */ { MAD_F(0x0455c5db) /* 0.270940642 */, 19 },
+ /* 7318 */ { MAD_F(0x0455f9a0) /* 0.270990015 */, 19 },
+ /* 7319 */ { MAD_F(0x04562d66) /* 0.271039390 */, 19 },
+ /* 7320 */ { MAD_F(0x0456612d) /* 0.271088768 */, 19 },
+ /* 7321 */ { MAD_F(0x045694f4) /* 0.271138148 */, 19 },
+ /* 7322 */ { MAD_F(0x0456c8bc) /* 0.271187530 */, 19 },
+ /* 7323 */ { MAD_F(0x0456fc84) /* 0.271236914 */, 19 },
+ /* 7324 */ { MAD_F(0x0457304e) /* 0.271286301 */, 19 },
+ /* 7325 */ { MAD_F(0x04576417) /* 0.271335689 */, 19 },
+ /* 7326 */ { MAD_F(0x045797e2) /* 0.271385080 */, 19 },
+ /* 7327 */ { MAD_F(0x0457cbac) /* 0.271434474 */, 19 },
+
+ /* 7328 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 19 },
+ /* 7329 */ { MAD_F(0x04583344) /* 0.271533267 */, 19 },
+ /* 7330 */ { MAD_F(0x04586711) /* 0.271582667 */, 19 },
+ /* 7331 */ { MAD_F(0x04589ade) /* 0.271632069 */, 19 },
+ /* 7332 */ { MAD_F(0x0458ceac) /* 0.271681474 */, 19 },
+ /* 7333 */ { MAD_F(0x0459027b) /* 0.271730880 */, 19 },
+ /* 7334 */ { MAD_F(0x0459364a) /* 0.271780289 */, 19 },
+ /* 7335 */ { MAD_F(0x04596a19) /* 0.271829701 */, 19 },
+ /* 7336 */ { MAD_F(0x04599dea) /* 0.271879114 */, 19 },
+ /* 7337 */ { MAD_F(0x0459d1bb) /* 0.271928530 */, 19 },
+ /* 7338 */ { MAD_F(0x045a058c) /* 0.271977948 */, 19 },
+ /* 7339 */ { MAD_F(0x045a395e) /* 0.272027368 */, 19 },
+ /* 7340 */ { MAD_F(0x045a6d31) /* 0.272076790 */, 19 },
+ /* 7341 */ { MAD_F(0x045aa104) /* 0.272126215 */, 19 },
+ /* 7342 */ { MAD_F(0x045ad4d8) /* 0.272175642 */, 19 },
+ /* 7343 */ { MAD_F(0x045b08ad) /* 0.272225071 */, 19 },
+
+ /* 7344 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 19 },
+ /* 7345 */ { MAD_F(0x045b7058) /* 0.272323936 */, 19 },
+ /* 7346 */ { MAD_F(0x045ba42e) /* 0.272373372 */, 19 },
+ /* 7347 */ { MAD_F(0x045bd805) /* 0.272422810 */, 19 },
+ /* 7348 */ { MAD_F(0x045c0bdd) /* 0.272472251 */, 19 },
+ /* 7349 */ { MAD_F(0x045c3fb5) /* 0.272521693 */, 19 },
+ /* 7350 */ { MAD_F(0x045c738e) /* 0.272571138 */, 19 },
+ /* 7351 */ { MAD_F(0x045ca767) /* 0.272620585 */, 19 },
+ /* 7352 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 19 },
+ /* 7353 */ { MAD_F(0x045d0f1b) /* 0.272719486 */, 19 },
+ /* 7354 */ { MAD_F(0x045d42f7) /* 0.272768940 */, 19 },
+ /* 7355 */ { MAD_F(0x045d76d2) /* 0.272818396 */, 19 },
+ /* 7356 */ { MAD_F(0x045daaaf) /* 0.272867855 */, 19 },
+ /* 7357 */ { MAD_F(0x045dde8c) /* 0.272917315 */, 19 },
+ /* 7358 */ { MAD_F(0x045e1269) /* 0.272966778 */, 19 },
+ /* 7359 */ { MAD_F(0x045e4647) /* 0.273016243 */, 19 },
+
+ /* 7360 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 19 },
+ /* 7361 */ { MAD_F(0x045eae06) /* 0.273115180 */, 19 },
+ /* 7362 */ { MAD_F(0x045ee1e6) /* 0.273164652 */, 19 },
+ /* 7363 */ { MAD_F(0x045f15c6) /* 0.273214126 */, 19 },
+ /* 7364 */ { MAD_F(0x045f49a7) /* 0.273263602 */, 19 },
+ /* 7365 */ { MAD_F(0x045f7d89) /* 0.273313081 */, 19 },
+ /* 7366 */ { MAD_F(0x045fb16c) /* 0.273362561 */, 19 },
+ /* 7367 */ { MAD_F(0x045fe54f) /* 0.273412044 */, 19 },
+ /* 7368 */ { MAD_F(0x04601932) /* 0.273461530 */, 19 },
+ /* 7369 */ { MAD_F(0x04604d16) /* 0.273511017 */, 19 },
+ /* 7370 */ { MAD_F(0x046080fb) /* 0.273560507 */, 19 },
+ /* 7371 */ { MAD_F(0x0460b4e1) /* 0.273609999 */, 19 },
+ /* 7372 */ { MAD_F(0x0460e8c7) /* 0.273659493 */, 19 },
+ /* 7373 */ { MAD_F(0x04611cad) /* 0.273708989 */, 19 },
+ /* 7374 */ { MAD_F(0x04615094) /* 0.273758488 */, 19 },
+ /* 7375 */ { MAD_F(0x0461847c) /* 0.273807989 */, 19 },
+
+ /* 7376 */ { MAD_F(0x0461b864) /* 0.273857492 */, 19 },
+ /* 7377 */ { MAD_F(0x0461ec4d) /* 0.273906997 */, 19 },
+ /* 7378 */ { MAD_F(0x04622037) /* 0.273956505 */, 19 },
+ /* 7379 */ { MAD_F(0x04625421) /* 0.274006015 */, 19 },
+ /* 7380 */ { MAD_F(0x0462880c) /* 0.274055527 */, 19 },
+ /* 7381 */ { MAD_F(0x0462bbf7) /* 0.274105041 */, 19 },
+ /* 7382 */ { MAD_F(0x0462efe3) /* 0.274154558 */, 19 },
+ /* 7383 */ { MAD_F(0x046323d0) /* 0.274204076 */, 19 },
+ /* 7384 */ { MAD_F(0x046357bd) /* 0.274253597 */, 19 },
+ /* 7385 */ { MAD_F(0x04638bab) /* 0.274303121 */, 19 },
+ /* 7386 */ { MAD_F(0x0463bf99) /* 0.274352646 */, 19 },
+ /* 7387 */ { MAD_F(0x0463f388) /* 0.274402174 */, 19 },
+ /* 7388 */ { MAD_F(0x04642778) /* 0.274451704 */, 19 },
+ /* 7389 */ { MAD_F(0x04645b68) /* 0.274501236 */, 19 },
+ /* 7390 */ { MAD_F(0x04648f59) /* 0.274550771 */, 19 },
+ /* 7391 */ { MAD_F(0x0464c34a) /* 0.274600307 */, 19 },
+
+ /* 7392 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 19 },
+ /* 7393 */ { MAD_F(0x04652b2f) /* 0.274699387 */, 19 },
+ /* 7394 */ { MAD_F(0x04655f22) /* 0.274748931 */, 19 },
+ /* 7395 */ { MAD_F(0x04659316) /* 0.274798476 */, 19 },
+ /* 7396 */ { MAD_F(0x0465c70a) /* 0.274848024 */, 19 },
+ /* 7397 */ { MAD_F(0x0465faff) /* 0.274897574 */, 19 },
+ /* 7398 */ { MAD_F(0x04662ef5) /* 0.274947126 */, 19 },
+ /* 7399 */ { MAD_F(0x046662eb) /* 0.274996681 */, 19 },
+ /* 7400 */ { MAD_F(0x046696e2) /* 0.275046238 */, 19 },
+ /* 7401 */ { MAD_F(0x0466cad9) /* 0.275095797 */, 19 },
+ /* 7402 */ { MAD_F(0x0466fed1) /* 0.275145358 */, 19 },
+ /* 7403 */ { MAD_F(0x046732ca) /* 0.275194921 */, 19 },
+ /* 7404 */ { MAD_F(0x046766c3) /* 0.275244487 */, 19 },
+ /* 7405 */ { MAD_F(0x04679abd) /* 0.275294055 */, 19 },
+ /* 7406 */ { MAD_F(0x0467ceb7) /* 0.275343625 */, 19 },
+ /* 7407 */ { MAD_F(0x046802b2) /* 0.275393198 */, 19 },
+
+ /* 7408 */ { MAD_F(0x046836ae) /* 0.275442772 */, 19 },
+ /* 7409 */ { MAD_F(0x04686aaa) /* 0.275492349 */, 19 },
+ /* 7410 */ { MAD_F(0x04689ea7) /* 0.275541928 */, 19 },
+ /* 7411 */ { MAD_F(0x0468d2a4) /* 0.275591509 */, 19 },
+ /* 7412 */ { MAD_F(0x046906a2) /* 0.275641093 */, 19 },
+ /* 7413 */ { MAD_F(0x04693aa1) /* 0.275690679 */, 19 },
+ /* 7414 */ { MAD_F(0x04696ea0) /* 0.275740267 */, 19 },
+ /* 7415 */ { MAD_F(0x0469a2a0) /* 0.275789857 */, 19 },
+ /* 7416 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 19 },
+ /* 7417 */ { MAD_F(0x046a0aa1) /* 0.275889044 */, 19 },
+ /* 7418 */ { MAD_F(0x046a3ea3) /* 0.275938641 */, 19 },
+ /* 7419 */ { MAD_F(0x046a72a5) /* 0.275988240 */, 19 },
+ /* 7420 */ { MAD_F(0x046aa6a8) /* 0.276037842 */, 19 },
+ /* 7421 */ { MAD_F(0x046adaab) /* 0.276087445 */, 19 },
+ /* 7422 */ { MAD_F(0x046b0eaf) /* 0.276137051 */, 19 },
+ /* 7423 */ { MAD_F(0x046b42b3) /* 0.276186659 */, 19 },
+
+ /* 7424 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 19 },
+ /* 7425 */ { MAD_F(0x046baabe) /* 0.276285882 */, 19 },
+ /* 7426 */ { MAD_F(0x046bdec5) /* 0.276335497 */, 19 },
+ /* 7427 */ { MAD_F(0x046c12cc) /* 0.276385113 */, 19 },
+ /* 7428 */ { MAD_F(0x046c46d3) /* 0.276434733 */, 19 },
+ /* 7429 */ { MAD_F(0x046c7adb) /* 0.276484354 */, 19 },
+ /* 7430 */ { MAD_F(0x046caee4) /* 0.276533978 */, 19 },
+ /* 7431 */ { MAD_F(0x046ce2ee) /* 0.276583604 */, 19 },
+ /* 7432 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 19 },
+ /* 7433 */ { MAD_F(0x046d4b02) /* 0.276682862 */, 19 },
+ /* 7434 */ { MAD_F(0x046d7f0d) /* 0.276732495 */, 19 },
+ /* 7435 */ { MAD_F(0x046db319) /* 0.276782129 */, 19 },
+ /* 7436 */ { MAD_F(0x046de725) /* 0.276831766 */, 19 },
+ /* 7437 */ { MAD_F(0x046e1b32) /* 0.276881406 */, 19 },
+ /* 7438 */ { MAD_F(0x046e4f40) /* 0.276931047 */, 19 },
+ /* 7439 */ { MAD_F(0x046e834e) /* 0.276980691 */, 19 },
+
+ /* 7440 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 19 },
+ /* 7441 */ { MAD_F(0x046eeb6c) /* 0.277079985 */, 19 },
+ /* 7442 */ { MAD_F(0x046f1f7c) /* 0.277129635 */, 19 },
+ /* 7443 */ { MAD_F(0x046f538c) /* 0.277179288 */, 19 },
+ /* 7444 */ { MAD_F(0x046f879d) /* 0.277228942 */, 19 },
+ /* 7445 */ { MAD_F(0x046fbbaf) /* 0.277278600 */, 19 },
+ /* 7446 */ { MAD_F(0x046fefc1) /* 0.277328259 */, 19 },
+ /* 7447 */ { MAD_F(0x047023d4) /* 0.277377920 */, 19 },
+ /* 7448 */ { MAD_F(0x047057e8) /* 0.277427584 */, 19 },
+ /* 7449 */ { MAD_F(0x04708bfc) /* 0.277477250 */, 19 },
+ /* 7450 */ { MAD_F(0x0470c011) /* 0.277526918 */, 19 },
+ /* 7451 */ { MAD_F(0x0470f426) /* 0.277576588 */, 19 },
+ /* 7452 */ { MAD_F(0x0471283c) /* 0.277626261 */, 19 },
+ /* 7453 */ { MAD_F(0x04715c52) /* 0.277675936 */, 19 },
+ /* 7454 */ { MAD_F(0x04719069) /* 0.277725613 */, 19 },
+ /* 7455 */ { MAD_F(0x0471c481) /* 0.277775292 */, 19 },
+
+ /* 7456 */ { MAD_F(0x0471f899) /* 0.277824973 */, 19 },
+ /* 7457 */ { MAD_F(0x04722cb2) /* 0.277874657 */, 19 },
+ /* 7458 */ { MAD_F(0x047260cc) /* 0.277924343 */, 19 },
+ /* 7459 */ { MAD_F(0x047294e6) /* 0.277974031 */, 19 },
+ /* 7460 */ { MAD_F(0x0472c900) /* 0.278023722 */, 19 },
+ /* 7461 */ { MAD_F(0x0472fd1b) /* 0.278073414 */, 19 },
+ /* 7462 */ { MAD_F(0x04733137) /* 0.278123109 */, 19 },
+ /* 7463 */ { MAD_F(0x04736554) /* 0.278172806 */, 19 },
+ /* 7464 */ { MAD_F(0x04739971) /* 0.278222505 */, 19 },
+ /* 7465 */ { MAD_F(0x0473cd8e) /* 0.278272207 */, 19 },
+ /* 7466 */ { MAD_F(0x047401ad) /* 0.278321910 */, 19 },
+ /* 7467 */ { MAD_F(0x047435cb) /* 0.278371616 */, 19 },
+ /* 7468 */ { MAD_F(0x047469eb) /* 0.278421324 */, 19 },
+ /* 7469 */ { MAD_F(0x04749e0b) /* 0.278471035 */, 19 },
+ /* 7470 */ { MAD_F(0x0474d22c) /* 0.278520747 */, 19 },
+ /* 7471 */ { MAD_F(0x0475064d) /* 0.278570462 */, 19 },
+
+ /* 7472 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 19 },
+ /* 7473 */ { MAD_F(0x04756e91) /* 0.278669898 */, 19 },
+ /* 7474 */ { MAD_F(0x0475a2b4) /* 0.278719619 */, 19 },
+ /* 7475 */ { MAD_F(0x0475d6d7) /* 0.278769343 */, 19 },
+ /* 7476 */ { MAD_F(0x04760afc) /* 0.278819069 */, 19 },
+ /* 7477 */ { MAD_F(0x04763f20) /* 0.278868797 */, 19 },
+ /* 7478 */ { MAD_F(0x04767346) /* 0.278918527 */, 19 },
+ /* 7479 */ { MAD_F(0x0476a76c) /* 0.278968260 */, 19 },
+ /* 7480 */ { MAD_F(0x0476db92) /* 0.279017995 */, 19 },
+ /* 7481 */ { MAD_F(0x04770fba) /* 0.279067731 */, 19 },
+ /* 7482 */ { MAD_F(0x047743e1) /* 0.279117471 */, 19 },
+ /* 7483 */ { MAD_F(0x0477780a) /* 0.279167212 */, 19 },
+ /* 7484 */ { MAD_F(0x0477ac33) /* 0.279216956 */, 19 },
+ /* 7485 */ { MAD_F(0x0477e05c) /* 0.279266701 */, 19 },
+ /* 7486 */ { MAD_F(0x04781486) /* 0.279316449 */, 19 },
+ /* 7487 */ { MAD_F(0x047848b1) /* 0.279366200 */, 19 },
+
+ /* 7488 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 19 },
+ /* 7489 */ { MAD_F(0x0478b108) /* 0.279465707 */, 19 },
+ /* 7490 */ { MAD_F(0x0478e535) /* 0.279515464 */, 19 },
+ /* 7491 */ { MAD_F(0x04791962) /* 0.279565223 */, 19 },
+ /* 7492 */ { MAD_F(0x04794d8f) /* 0.279614984 */, 19 },
+ /* 7493 */ { MAD_F(0x047981be) /* 0.279664748 */, 19 },
+ /* 7494 */ { MAD_F(0x0479b5ed) /* 0.279714513 */, 19 },
+ /* 7495 */ { MAD_F(0x0479ea1c) /* 0.279764281 */, 19 },
+ /* 7496 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 19 },
+ /* 7497 */ { MAD_F(0x047a527d) /* 0.279863824 */, 19 },
+ /* 7498 */ { MAD_F(0x047a86ae) /* 0.279913598 */, 19 },
+ /* 7499 */ { MAD_F(0x047abae0) /* 0.279963375 */, 19 },
+ /* 7500 */ { MAD_F(0x047aef12) /* 0.280013154 */, 19 },
+ /* 7501 */ { MAD_F(0x047b2346) /* 0.280062935 */, 19 },
+ /* 7502 */ { MAD_F(0x047b5779) /* 0.280112719 */, 19 },
+ /* 7503 */ { MAD_F(0x047b8bad) /* 0.280162504 */, 19 },
+
+ /* 7504 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 19 },
+ /* 7505 */ { MAD_F(0x047bf418) /* 0.280262082 */, 19 },
+ /* 7506 */ { MAD_F(0x047c284e) /* 0.280311875 */, 19 },
+ /* 7507 */ { MAD_F(0x047c5c84) /* 0.280361669 */, 19 },
+ /* 7508 */ { MAD_F(0x047c90bb) /* 0.280411466 */, 19 },
+ /* 7509 */ { MAD_F(0x047cc4f3) /* 0.280461265 */, 19 },
+ /* 7510 */ { MAD_F(0x047cf92c) /* 0.280511066 */, 19 },
+ /* 7511 */ { MAD_F(0x047d2d65) /* 0.280560869 */, 19 },
+ /* 7512 */ { MAD_F(0x047d619e) /* 0.280610675 */, 19 },
+ /* 7513 */ { MAD_F(0x047d95d8) /* 0.280660483 */, 19 },
+ /* 7514 */ { MAD_F(0x047dca13) /* 0.280710292 */, 19 },
+ /* 7515 */ { MAD_F(0x047dfe4e) /* 0.280760105 */, 19 },
+ /* 7516 */ { MAD_F(0x047e328a) /* 0.280809919 */, 19 },
+ /* 7517 */ { MAD_F(0x047e66c7) /* 0.280859736 */, 19 },
+ /* 7518 */ { MAD_F(0x047e9b04) /* 0.280909554 */, 19 },
+ /* 7519 */ { MAD_F(0x047ecf42) /* 0.280959375 */, 19 },
+
+ /* 7520 */ { MAD_F(0x047f0380) /* 0.281009199 */, 19 },
+ /* 7521 */ { MAD_F(0x047f37bf) /* 0.281059024 */, 19 },
+ /* 7522 */ { MAD_F(0x047f6bff) /* 0.281108852 */, 19 },
+ /* 7523 */ { MAD_F(0x047fa03f) /* 0.281158682 */, 19 },
+ /* 7524 */ { MAD_F(0x047fd47f) /* 0.281208514 */, 19 },
+ /* 7525 */ { MAD_F(0x048008c1) /* 0.281258348 */, 19 },
+ /* 7526 */ { MAD_F(0x04803d02) /* 0.281308184 */, 19 },
+ /* 7527 */ { MAD_F(0x04807145) /* 0.281358023 */, 19 },
+ /* 7528 */ { MAD_F(0x0480a588) /* 0.281407864 */, 19 },
+ /* 7529 */ { MAD_F(0x0480d9cc) /* 0.281457707 */, 19 },
+ /* 7530 */ { MAD_F(0x04810e10) /* 0.281507552 */, 19 },
+ /* 7531 */ { MAD_F(0x04814255) /* 0.281557400 */, 19 },
+ /* 7532 */ { MAD_F(0x0481769a) /* 0.281607250 */, 19 },
+ /* 7533 */ { MAD_F(0x0481aae0) /* 0.281657101 */, 19 },
+ /* 7534 */ { MAD_F(0x0481df27) /* 0.281706956 */, 19 },
+ /* 7535 */ { MAD_F(0x0482136e) /* 0.281756812 */, 19 },
+
+ /* 7536 */ { MAD_F(0x048247b6) /* 0.281806670 */, 19 },
+ /* 7537 */ { MAD_F(0x04827bfe) /* 0.281856531 */, 19 },
+ /* 7538 */ { MAD_F(0x0482b047) /* 0.281906394 */, 19 },
+ /* 7539 */ { MAD_F(0x0482e491) /* 0.281956259 */, 19 },
+ /* 7540 */ { MAD_F(0x048318db) /* 0.282006127 */, 19 },
+ /* 7541 */ { MAD_F(0x04834d26) /* 0.282055996 */, 19 },
+ /* 7542 */ { MAD_F(0x04838171) /* 0.282105868 */, 19 },
+ /* 7543 */ { MAD_F(0x0483b5bd) /* 0.282155742 */, 19 },
+ /* 7544 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 19 },
+ /* 7545 */ { MAD_F(0x04841e57) /* 0.282255496 */, 19 },
+ /* 7546 */ { MAD_F(0x048452a4) /* 0.282305377 */, 19 },
+ /* 7547 */ { MAD_F(0x048486f3) /* 0.282355260 */, 19 },
+ /* 7548 */ { MAD_F(0x0484bb42) /* 0.282405145 */, 19 },
+ /* 7549 */ { MAD_F(0x0484ef91) /* 0.282455032 */, 19 },
+ /* 7550 */ { MAD_F(0x048523e1) /* 0.282504921 */, 19 },
+ /* 7551 */ { MAD_F(0x04855832) /* 0.282554813 */, 19 },
+
+ /* 7552 */ { MAD_F(0x04858c83) /* 0.282604707 */, 19 },
+ /* 7553 */ { MAD_F(0x0485c0d5) /* 0.282654603 */, 19 },
+ /* 7554 */ { MAD_F(0x0485f527) /* 0.282704501 */, 19 },
+ /* 7555 */ { MAD_F(0x0486297a) /* 0.282754401 */, 19 },
+ /* 7556 */ { MAD_F(0x04865dce) /* 0.282804304 */, 19 },
+ /* 7557 */ { MAD_F(0x04869222) /* 0.282854209 */, 19 },
+ /* 7558 */ { MAD_F(0x0486c677) /* 0.282904116 */, 19 },
+ /* 7559 */ { MAD_F(0x0486facc) /* 0.282954025 */, 19 },
+ /* 7560 */ { MAD_F(0x04872f22) /* 0.283003936 */, 19 },
+ /* 7561 */ { MAD_F(0x04876379) /* 0.283053850 */, 19 },
+ /* 7562 */ { MAD_F(0x048797d0) /* 0.283103766 */, 19 },
+ /* 7563 */ { MAD_F(0x0487cc28) /* 0.283153684 */, 19 },
+ /* 7564 */ { MAD_F(0x04880080) /* 0.283203604 */, 19 },
+ /* 7565 */ { MAD_F(0x048834d9) /* 0.283253527 */, 19 },
+ /* 7566 */ { MAD_F(0x04886933) /* 0.283303451 */, 19 },
+ /* 7567 */ { MAD_F(0x04889d8d) /* 0.283353378 */, 19 },
+
+ /* 7568 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 19 },
+ /* 7569 */ { MAD_F(0x04890643) /* 0.283453238 */, 19 },
+ /* 7570 */ { MAD_F(0x04893a9f) /* 0.283503172 */, 19 },
+ /* 7571 */ { MAD_F(0x04896efb) /* 0.283553107 */, 19 },
+ /* 7572 */ { MAD_F(0x0489a358) /* 0.283603045 */, 19 },
+ /* 7573 */ { MAD_F(0x0489d7b6) /* 0.283652985 */, 19 },
+ /* 7574 */ { MAD_F(0x048a0c14) /* 0.283702927 */, 19 },
+ /* 7575 */ { MAD_F(0x048a4073) /* 0.283752872 */, 19 },
+ /* 7576 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 19 },
+ /* 7577 */ { MAD_F(0x048aa933) /* 0.283852767 */, 19 },
+ /* 7578 */ { MAD_F(0x048add93) /* 0.283902718 */, 19 },
+ /* 7579 */ { MAD_F(0x048b11f5) /* 0.283952671 */, 19 },
+ /* 7580 */ { MAD_F(0x048b4656) /* 0.284002627 */, 19 },
+ /* 7581 */ { MAD_F(0x048b7ab9) /* 0.284052584 */, 19 },
+ /* 7582 */ { MAD_F(0x048baf1c) /* 0.284102544 */, 19 },
+ /* 7583 */ { MAD_F(0x048be37f) /* 0.284152506 */, 19 },
+
+ /* 7584 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 19 },
+ /* 7585 */ { MAD_F(0x048c4c48) /* 0.284252436 */, 19 },
+ /* 7586 */ { MAD_F(0x048c80ad) /* 0.284302405 */, 19 },
+ /* 7587 */ { MAD_F(0x048cb513) /* 0.284352376 */, 19 },
+ /* 7588 */ { MAD_F(0x048ce97a) /* 0.284402349 */, 19 },
+ /* 7589 */ { MAD_F(0x048d1de1) /* 0.284452324 */, 19 },
+ /* 7590 */ { MAD_F(0x048d5249) /* 0.284502301 */, 19 },
+ /* 7591 */ { MAD_F(0x048d86b1) /* 0.284552281 */, 19 },
+ /* 7592 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 19 },
+ /* 7593 */ { MAD_F(0x048def83) /* 0.284652246 */, 19 },
+ /* 7594 */ { MAD_F(0x048e23ed) /* 0.284702233 */, 19 },
+ /* 7595 */ { MAD_F(0x048e5858) /* 0.284752221 */, 19 },
+ /* 7596 */ { MAD_F(0x048e8cc3) /* 0.284802211 */, 19 },
+ /* 7597 */ { MAD_F(0x048ec12f) /* 0.284852204 */, 19 },
+ /* 7598 */ { MAD_F(0x048ef59b) /* 0.284902199 */, 19 },
+ /* 7599 */ { MAD_F(0x048f2a08) /* 0.284952196 */, 19 },
+
+ /* 7600 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 19 },
+ /* 7601 */ { MAD_F(0x048f92e4) /* 0.285052197 */, 19 },
+ /* 7602 */ { MAD_F(0x048fc753) /* 0.285102201 */, 19 },
+ /* 7603 */ { MAD_F(0x048ffbc2) /* 0.285152206 */, 19 },
+ /* 7604 */ { MAD_F(0x04903032) /* 0.285202214 */, 19 },
+ /* 7605 */ { MAD_F(0x049064a3) /* 0.285252225 */, 19 },
+ /* 7606 */ { MAD_F(0x04909914) /* 0.285302237 */, 19 },
+ /* 7607 */ { MAD_F(0x0490cd86) /* 0.285352252 */, 19 },
+ /* 7608 */ { MAD_F(0x049101f8) /* 0.285402269 */, 19 },
+ /* 7609 */ { MAD_F(0x0491366b) /* 0.285452288 */, 19 },
+ /* 7610 */ { MAD_F(0x04916ade) /* 0.285502309 */, 19 },
+ /* 7611 */ { MAD_F(0x04919f52) /* 0.285552332 */, 19 },
+ /* 7612 */ { MAD_F(0x0491d3c7) /* 0.285602358 */, 19 },
+ /* 7613 */ { MAD_F(0x0492083c) /* 0.285652386 */, 19 },
+ /* 7614 */ { MAD_F(0x04923cb2) /* 0.285702416 */, 19 },
+ /* 7615 */ { MAD_F(0x04927128) /* 0.285752448 */, 19 },
+
+ /* 7616 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 19 },
+ /* 7617 */ { MAD_F(0x0492da17) /* 0.285852519 */, 19 },
+ /* 7618 */ { MAD_F(0x04930e8f) /* 0.285902557 */, 19 },
+ /* 7619 */ { MAD_F(0x04934308) /* 0.285952598 */, 19 },
+ /* 7620 */ { MAD_F(0x04937781) /* 0.286002641 */, 19 },
+ /* 7621 */ { MAD_F(0x0493abfb) /* 0.286052687 */, 19 },
+ /* 7622 */ { MAD_F(0x0493e076) /* 0.286102734 */, 19 },
+ /* 7623 */ { MAD_F(0x049414f1) /* 0.286152784 */, 19 },
+ /* 7624 */ { MAD_F(0x0494496c) /* 0.286202836 */, 19 },
+ /* 7625 */ { MAD_F(0x04947de9) /* 0.286252890 */, 19 },
+ /* 7626 */ { MAD_F(0x0494b266) /* 0.286302946 */, 19 },
+ /* 7627 */ { MAD_F(0x0494e6e3) /* 0.286353005 */, 19 },
+ /* 7628 */ { MAD_F(0x04951b61) /* 0.286403065 */, 19 },
+ /* 7629 */ { MAD_F(0x04954fe0) /* 0.286453128 */, 19 },
+ /* 7630 */ { MAD_F(0x0495845f) /* 0.286503193 */, 19 },
+ /* 7631 */ { MAD_F(0x0495b8df) /* 0.286553260 */, 19 },
+
+ /* 7632 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 19 },
+ /* 7633 */ { MAD_F(0x049621e0) /* 0.286653401 */, 19 },
+ /* 7634 */ { MAD_F(0x04965662) /* 0.286703475 */, 19 },
+ /* 7635 */ { MAD_F(0x04968ae4) /* 0.286753551 */, 19 },
+ /* 7636 */ { MAD_F(0x0496bf67) /* 0.286803629 */, 19 },
+ /* 7637 */ { MAD_F(0x0496f3ea) /* 0.286853709 */, 19 },
+ /* 7638 */ { MAD_F(0x0497286e) /* 0.286903792 */, 19 },
+ /* 7639 */ { MAD_F(0x04975cf2) /* 0.286953876 */, 19 },
+ /* 7640 */ { MAD_F(0x04979177) /* 0.287003963 */, 19 },
+ /* 7641 */ { MAD_F(0x0497c5fd) /* 0.287054052 */, 19 },
+ /* 7642 */ { MAD_F(0x0497fa83) /* 0.287104143 */, 19 },
+ /* 7643 */ { MAD_F(0x04982f0a) /* 0.287154237 */, 19 },
+ /* 7644 */ { MAD_F(0x04986392) /* 0.287204332 */, 19 },
+ /* 7645 */ { MAD_F(0x0498981a) /* 0.287254430 */, 19 },
+ /* 7646 */ { MAD_F(0x0498cca2) /* 0.287304530 */, 19 },
+ /* 7647 */ { MAD_F(0x0499012c) /* 0.287354632 */, 19 },
+
+ /* 7648 */ { MAD_F(0x049935b5) /* 0.287404737 */, 19 },
+ /* 7649 */ { MAD_F(0x04996a40) /* 0.287454843 */, 19 },
+ /* 7650 */ { MAD_F(0x04999ecb) /* 0.287504952 */, 19 },
+ /* 7651 */ { MAD_F(0x0499d356) /* 0.287555063 */, 19 },
+ /* 7652 */ { MAD_F(0x049a07e2) /* 0.287605176 */, 19 },
+ /* 7653 */ { MAD_F(0x049a3c6f) /* 0.287655291 */, 19 },
+ /* 7654 */ { MAD_F(0x049a70fc) /* 0.287705409 */, 19 },
+ /* 7655 */ { MAD_F(0x049aa58a) /* 0.287755528 */, 19 },
+ /* 7656 */ { MAD_F(0x049ada19) /* 0.287805650 */, 19 },
+ /* 7657 */ { MAD_F(0x049b0ea8) /* 0.287855774 */, 19 },
+ /* 7658 */ { MAD_F(0x049b4337) /* 0.287905900 */, 19 },
+ /* 7659 */ { MAD_F(0x049b77c8) /* 0.287956028 */, 19 },
+ /* 7660 */ { MAD_F(0x049bac58) /* 0.288006159 */, 19 },
+ /* 7661 */ { MAD_F(0x049be0ea) /* 0.288056292 */, 19 },
+ /* 7662 */ { MAD_F(0x049c157c) /* 0.288106427 */, 19 },
+ /* 7663 */ { MAD_F(0x049c4a0e) /* 0.288156564 */, 19 },
+
+ /* 7664 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 19 },
+ /* 7665 */ { MAD_F(0x049cb335) /* 0.288256844 */, 19 },
+ /* 7666 */ { MAD_F(0x049ce7ca) /* 0.288306988 */, 19 },
+ /* 7667 */ { MAD_F(0x049d1c5e) /* 0.288357134 */, 19 },
+ /* 7668 */ { MAD_F(0x049d50f4) /* 0.288407282 */, 19 },
+ /* 7669 */ { MAD_F(0x049d858a) /* 0.288457432 */, 19 },
+ /* 7670 */ { MAD_F(0x049dba21) /* 0.288507584 */, 19 },
+ /* 7671 */ { MAD_F(0x049deeb8) /* 0.288557739 */, 19 },
+ /* 7672 */ { MAD_F(0x049e2350) /* 0.288607895 */, 19 },
+ /* 7673 */ { MAD_F(0x049e57e8) /* 0.288658054 */, 19 },
+ /* 7674 */ { MAD_F(0x049e8c81) /* 0.288708215 */, 19 },
+ /* 7675 */ { MAD_F(0x049ec11b) /* 0.288758379 */, 19 },
+ /* 7676 */ { MAD_F(0x049ef5b5) /* 0.288808544 */, 19 },
+ /* 7677 */ { MAD_F(0x049f2a50) /* 0.288858712 */, 19 },
+ /* 7678 */ { MAD_F(0x049f5eeb) /* 0.288908881 */, 19 },
+ /* 7679 */ { MAD_F(0x049f9387) /* 0.288959053 */, 19 },
+
+ /* 7680 */ { MAD_F(0x049fc824) /* 0.289009227 */, 19 },
+ /* 7681 */ { MAD_F(0x049ffcc1) /* 0.289059404 */, 19 },
+ /* 7682 */ { MAD_F(0x04a0315e) /* 0.289109582 */, 19 },
+ /* 7683 */ { MAD_F(0x04a065fd) /* 0.289159763 */, 19 },
+ /* 7684 */ { MAD_F(0x04a09a9b) /* 0.289209946 */, 19 },
+ /* 7685 */ { MAD_F(0x04a0cf3b) /* 0.289260131 */, 19 },
+ /* 7686 */ { MAD_F(0x04a103db) /* 0.289310318 */, 19 },
+ /* 7687 */ { MAD_F(0x04a1387b) /* 0.289360507 */, 19 },
+ /* 7688 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 19 },
+ /* 7689 */ { MAD_F(0x04a1a1be) /* 0.289460893 */, 19 },
+ /* 7690 */ { MAD_F(0x04a1d661) /* 0.289511088 */, 19 },
+ /* 7691 */ { MAD_F(0x04a20b04) /* 0.289561287 */, 19 },
+ /* 7692 */ { MAD_F(0x04a23fa7) /* 0.289611487 */, 19 },
+ /* 7693 */ { MAD_F(0x04a2744b) /* 0.289661689 */, 19 },
+ /* 7694 */ { MAD_F(0x04a2a8f0) /* 0.289711894 */, 19 },
+ /* 7695 */ { MAD_F(0x04a2dd95) /* 0.289762101 */, 19 },
+
+ /* 7696 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 19 },
+ /* 7697 */ { MAD_F(0x04a346e2) /* 0.289862521 */, 19 },
+ /* 7698 */ { MAD_F(0x04a37b89) /* 0.289912734 */, 19 },
+ /* 7699 */ { MAD_F(0x04a3b030) /* 0.289962949 */, 19 },
+ /* 7700 */ { MAD_F(0x04a3e4d8) /* 0.290013167 */, 19 },
+ /* 7701 */ { MAD_F(0x04a41981) /* 0.290063387 */, 19 },
+ /* 7702 */ { MAD_F(0x04a44e2b) /* 0.290113609 */, 19 },
+ /* 7703 */ { MAD_F(0x04a482d5) /* 0.290163833 */, 19 },
+ /* 7704 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 19 },
+ /* 7705 */ { MAD_F(0x04a4ec2a) /* 0.290264288 */, 19 },
+ /* 7706 */ { MAD_F(0x04a520d6) /* 0.290314519 */, 19 },
+ /* 7707 */ { MAD_F(0x04a55582) /* 0.290364751 */, 19 },
+ /* 7708 */ { MAD_F(0x04a58a2f) /* 0.290414986 */, 19 },
+ /* 7709 */ { MAD_F(0x04a5bedd) /* 0.290465224 */, 19 },
+ /* 7710 */ { MAD_F(0x04a5f38b) /* 0.290515463 */, 19 },
+ /* 7711 */ { MAD_F(0x04a62839) /* 0.290565705 */, 19 },
+
+ /* 7712 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 19 },
+ /* 7713 */ { MAD_F(0x04a69198) /* 0.290666194 */, 19 },
+ /* 7714 */ { MAD_F(0x04a6c648) /* 0.290716442 */, 19 },
+ /* 7715 */ { MAD_F(0x04a6faf9) /* 0.290766692 */, 19 },
+ /* 7716 */ { MAD_F(0x04a72fab) /* 0.290816945 */, 19 },
+ /* 7717 */ { MAD_F(0x04a7645d) /* 0.290867199 */, 19 },
+ /* 7718 */ { MAD_F(0x04a79910) /* 0.290917456 */, 19 },
+ /* 7719 */ { MAD_F(0x04a7cdc3) /* 0.290967715 */, 19 },
+ /* 7720 */ { MAD_F(0x04a80277) /* 0.291017976 */, 19 },
+ /* 7721 */ { MAD_F(0x04a8372b) /* 0.291068239 */, 19 },
+ /* 7722 */ { MAD_F(0x04a86be0) /* 0.291118505 */, 19 },
+ /* 7723 */ { MAD_F(0x04a8a096) /* 0.291168772 */, 19 },
+ /* 7724 */ { MAD_F(0x04a8d54c) /* 0.291219042 */, 19 },
+ /* 7725 */ { MAD_F(0x04a90a03) /* 0.291269314 */, 19 },
+ /* 7726 */ { MAD_F(0x04a93eba) /* 0.291319588 */, 19 },
+ /* 7727 */ { MAD_F(0x04a97372) /* 0.291369865 */, 19 },
+
+ /* 7728 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 19 },
+ /* 7729 */ { MAD_F(0x04a9dce4) /* 0.291470424 */, 19 },
+ /* 7730 */ { MAD_F(0x04aa119d) /* 0.291520706 */, 19 },
+ /* 7731 */ { MAD_F(0x04aa4658) /* 0.291570991 */, 19 },
+ /* 7732 */ { MAD_F(0x04aa7b13) /* 0.291621278 */, 19 },
+ /* 7733 */ { MAD_F(0x04aaafce) /* 0.291671568 */, 19 },
+ /* 7734 */ { MAD_F(0x04aae48a) /* 0.291721859 */, 19 },
+ /* 7735 */ { MAD_F(0x04ab1947) /* 0.291772153 */, 19 },
+ /* 7736 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 19 },
+ /* 7737 */ { MAD_F(0x04ab82c2) /* 0.291872747 */, 19 },
+ /* 7738 */ { MAD_F(0x04abb780) /* 0.291923047 */, 19 },
+ /* 7739 */ { MAD_F(0x04abec3f) /* 0.291973349 */, 19 },
+ /* 7740 */ { MAD_F(0x04ac20fe) /* 0.292023653 */, 19 },
+ /* 7741 */ { MAD_F(0x04ac55be) /* 0.292073960 */, 19 },
+ /* 7742 */ { MAD_F(0x04ac8a7f) /* 0.292124269 */, 19 },
+ /* 7743 */ { MAD_F(0x04acbf40) /* 0.292174580 */, 19 },
+
+ /* 7744 */ { MAD_F(0x04acf402) /* 0.292224893 */, 19 },
+ /* 7745 */ { MAD_F(0x04ad28c5) /* 0.292275208 */, 19 },
+ /* 7746 */ { MAD_F(0x04ad5d88) /* 0.292325526 */, 19 },
+ /* 7747 */ { MAD_F(0x04ad924b) /* 0.292375845 */, 19 },
+ /* 7748 */ { MAD_F(0x04adc70f) /* 0.292426167 */, 19 },
+ /* 7749 */ { MAD_F(0x04adfbd4) /* 0.292476491 */, 19 },
+ /* 7750 */ { MAD_F(0x04ae3099) /* 0.292526817 */, 19 },
+ /* 7751 */ { MAD_F(0x04ae655f) /* 0.292577145 */, 19 },
+ /* 7752 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 19 },
+ /* 7753 */ { MAD_F(0x04aeceed) /* 0.292677808 */, 19 },
+ /* 7754 */ { MAD_F(0x04af03b4) /* 0.292728143 */, 19 },
+ /* 7755 */ { MAD_F(0x04af387d) /* 0.292778480 */, 19 },
+ /* 7756 */ { MAD_F(0x04af6d45) /* 0.292828819 */, 19 },
+ /* 7757 */ { MAD_F(0x04afa20f) /* 0.292879160 */, 19 },
+ /* 7758 */ { MAD_F(0x04afd6d9) /* 0.292929504 */, 19 },
+ /* 7759 */ { MAD_F(0x04b00ba3) /* 0.292979849 */, 19 },
+
+ /* 7760 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 19 },
+ /* 7761 */ { MAD_F(0x04b0753a) /* 0.293080547 */, 19 },
+ /* 7762 */ { MAD_F(0x04b0aa06) /* 0.293130899 */, 19 },
+ /* 7763 */ { MAD_F(0x04b0ded3) /* 0.293181253 */, 19 },
+ /* 7764 */ { MAD_F(0x04b113a1) /* 0.293231610 */, 19 },
+ /* 7765 */ { MAD_F(0x04b1486f) /* 0.293281968 */, 19 },
+ /* 7766 */ { MAD_F(0x04b17d3d) /* 0.293332329 */, 19 },
+ /* 7767 */ { MAD_F(0x04b1b20c) /* 0.293382692 */, 19 },
+ /* 7768 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 19 },
+ /* 7769 */ { MAD_F(0x04b21bad) /* 0.293483424 */, 19 },
+ /* 7770 */ { MAD_F(0x04b2507d) /* 0.293533794 */, 19 },
+ /* 7771 */ { MAD_F(0x04b2854f) /* 0.293584165 */, 19 },
+ /* 7772 */ { MAD_F(0x04b2ba21) /* 0.293634539 */, 19 },
+ /* 7773 */ { MAD_F(0x04b2eef4) /* 0.293684915 */, 19 },
+ /* 7774 */ { MAD_F(0x04b323c7) /* 0.293735293 */, 19 },
+ /* 7775 */ { MAD_F(0x04b3589b) /* 0.293785673 */, 19 },
+
+ /* 7776 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 19 },
+ /* 7777 */ { MAD_F(0x04b3c244) /* 0.293886440 */, 19 },
+ /* 7778 */ { MAD_F(0x04b3f71a) /* 0.293936826 */, 19 },
+ /* 7779 */ { MAD_F(0x04b42bf0) /* 0.293987215 */, 19 },
+ /* 7780 */ { MAD_F(0x04b460c7) /* 0.294037606 */, 19 },
+ /* 7781 */ { MAD_F(0x04b4959e) /* 0.294087999 */, 19 },
+ /* 7782 */ { MAD_F(0x04b4ca76) /* 0.294138395 */, 19 },
+ /* 7783 */ { MAD_F(0x04b4ff4e) /* 0.294188792 */, 19 },
+ /* 7784 */ { MAD_F(0x04b53427) /* 0.294239192 */, 19 },
+ /* 7785 */ { MAD_F(0x04b56901) /* 0.294289593 */, 19 },
+ /* 7786 */ { MAD_F(0x04b59ddb) /* 0.294339997 */, 19 },
+ /* 7787 */ { MAD_F(0x04b5d2b6) /* 0.294390403 */, 19 },
+ /* 7788 */ { MAD_F(0x04b60791) /* 0.294440812 */, 19 },
+ /* 7789 */ { MAD_F(0x04b63c6d) /* 0.294491222 */, 19 },
+ /* 7790 */ { MAD_F(0x04b6714a) /* 0.294541635 */, 19 },
+ /* 7791 */ { MAD_F(0x04b6a627) /* 0.294592049 */, 19 },
+
+ /* 7792 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 19 },
+ /* 7793 */ { MAD_F(0x04b70fe3) /* 0.294692885 */, 19 },
+ /* 7794 */ { MAD_F(0x04b744c2) /* 0.294743306 */, 19 },
+ /* 7795 */ { MAD_F(0x04b779a1) /* 0.294793730 */, 19 },
+ /* 7796 */ { MAD_F(0x04b7ae81) /* 0.294844155 */, 19 },
+ /* 7797 */ { MAD_F(0x04b7e362) /* 0.294894583 */, 19 },
+ /* 7798 */ { MAD_F(0x04b81843) /* 0.294945013 */, 19 },
+ /* 7799 */ { MAD_F(0x04b84d24) /* 0.294995445 */, 19 },
+ /* 7800 */ { MAD_F(0x04b88207) /* 0.295045879 */, 19 },
+ /* 7801 */ { MAD_F(0x04b8b6ea) /* 0.295096315 */, 19 },
+ /* 7802 */ { MAD_F(0x04b8ebcd) /* 0.295146753 */, 19 },
+ /* 7803 */ { MAD_F(0x04b920b1) /* 0.295197194 */, 19 },
+ /* 7804 */ { MAD_F(0x04b95596) /* 0.295247637 */, 19 },
+ /* 7805 */ { MAD_F(0x04b98a7b) /* 0.295298082 */, 19 },
+ /* 7806 */ { MAD_F(0x04b9bf61) /* 0.295348529 */, 19 },
+ /* 7807 */ { MAD_F(0x04b9f447) /* 0.295398978 */, 19 },
+
+ /* 7808 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 19 },
+ /* 7809 */ { MAD_F(0x04ba5e16) /* 0.295499883 */, 19 },
+ /* 7810 */ { MAD_F(0x04ba92fe) /* 0.295550338 */, 19 },
+ /* 7811 */ { MAD_F(0x04bac7e6) /* 0.295600796 */, 19 },
+ /* 7812 */ { MAD_F(0x04bafcd0) /* 0.295651256 */, 19 },
+ /* 7813 */ { MAD_F(0x04bb31b9) /* 0.295701718 */, 19 },
+ /* 7814 */ { MAD_F(0x04bb66a4) /* 0.295752183 */, 19 },
+ /* 7815 */ { MAD_F(0x04bb9b8f) /* 0.295802649 */, 19 },
+ /* 7816 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 19 },
+ /* 7817 */ { MAD_F(0x04bc0566) /* 0.295903588 */, 19 },
+ /* 7818 */ { MAD_F(0x04bc3a53) /* 0.295954061 */, 19 },
+ /* 7819 */ { MAD_F(0x04bc6f40) /* 0.296004536 */, 19 },
+ /* 7820 */ { MAD_F(0x04bca42e) /* 0.296055013 */, 19 },
+ /* 7821 */ { MAD_F(0x04bcd91d) /* 0.296105493 */, 19 },
+ /* 7822 */ { MAD_F(0x04bd0e0c) /* 0.296155974 */, 19 },
+ /* 7823 */ { MAD_F(0x04bd42fb) /* 0.296206458 */, 19 },
+
+ /* 7824 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 19 },
+ /* 7825 */ { MAD_F(0x04bdacdc) /* 0.296307432 */, 19 },
+ /* 7826 */ { MAD_F(0x04bde1ce) /* 0.296357922 */, 19 },
+ /* 7827 */ { MAD_F(0x04be16c0) /* 0.296408414 */, 19 },
+ /* 7828 */ { MAD_F(0x04be4bb2) /* 0.296458908 */, 19 },
+ /* 7829 */ { MAD_F(0x04be80a5) /* 0.296509405 */, 19 },
+ /* 7830 */ { MAD_F(0x04beb599) /* 0.296559904 */, 19 },
+ /* 7831 */ { MAD_F(0x04beea8d) /* 0.296610404 */, 19 },
+ /* 7832 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 19 },
+ /* 7833 */ { MAD_F(0x04bf5477) /* 0.296711413 */, 19 },
+ /* 7834 */ { MAD_F(0x04bf896d) /* 0.296761920 */, 19 },
+ /* 7835 */ { MAD_F(0x04bfbe64) /* 0.296812429 */, 19 },
+ /* 7836 */ { MAD_F(0x04bff35b) /* 0.296862941 */, 19 },
+ /* 7837 */ { MAD_F(0x04c02852) /* 0.296913455 */, 19 },
+ /* 7838 */ { MAD_F(0x04c05d4b) /* 0.296963971 */, 19 },
+ /* 7839 */ { MAD_F(0x04c09243) /* 0.297014489 */, 19 },
+
+ /* 7840 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 19 },
+ /* 7841 */ { MAD_F(0x04c0fc37) /* 0.297115531 */, 19 },
+ /* 7842 */ { MAD_F(0x04c13131) /* 0.297166056 */, 19 },
+ /* 7843 */ { MAD_F(0x04c1662d) /* 0.297216582 */, 19 },
+ /* 7844 */ { MAD_F(0x04c19b28) /* 0.297267111 */, 19 },
+ /* 7845 */ { MAD_F(0x04c1d025) /* 0.297317642 */, 19 },
+ /* 7846 */ { MAD_F(0x04c20521) /* 0.297368175 */, 19 },
+ /* 7847 */ { MAD_F(0x04c23a1f) /* 0.297418710 */, 19 },
+ /* 7848 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 19 },
+ /* 7849 */ { MAD_F(0x04c2a41b) /* 0.297519787 */, 19 },
+ /* 7850 */ { MAD_F(0x04c2d91b) /* 0.297570329 */, 19 },
+ /* 7851 */ { MAD_F(0x04c30e1a) /* 0.297620873 */, 19 },
+ /* 7852 */ { MAD_F(0x04c3431b) /* 0.297671418 */, 19 },
+ /* 7853 */ { MAD_F(0x04c3781c) /* 0.297721967 */, 19 },
+ /* 7854 */ { MAD_F(0x04c3ad1d) /* 0.297772517 */, 19 },
+ /* 7855 */ { MAD_F(0x04c3e21f) /* 0.297823069 */, 19 },
+
+ /* 7856 */ { MAD_F(0x04c41722) /* 0.297873624 */, 19 },
+ /* 7857 */ { MAD_F(0x04c44c25) /* 0.297924180 */, 19 },
+ /* 7858 */ { MAD_F(0x04c48129) /* 0.297974739 */, 19 },
+ /* 7859 */ { MAD_F(0x04c4b62d) /* 0.298025300 */, 19 },
+ /* 7860 */ { MAD_F(0x04c4eb32) /* 0.298075863 */, 19 },
+ /* 7861 */ { MAD_F(0x04c52038) /* 0.298126429 */, 19 },
+ /* 7862 */ { MAD_F(0x04c5553e) /* 0.298176996 */, 19 },
+ /* 7863 */ { MAD_F(0x04c58a44) /* 0.298227565 */, 19 },
+ /* 7864 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 19 },
+ /* 7865 */ { MAD_F(0x04c5f453) /* 0.298328711 */, 19 },
+ /* 7866 */ { MAD_F(0x04c6295c) /* 0.298379287 */, 19 },
+ /* 7867 */ { MAD_F(0x04c65e65) /* 0.298429865 */, 19 },
+ /* 7868 */ { MAD_F(0x04c6936e) /* 0.298480445 */, 19 },
+ /* 7869 */ { MAD_F(0x04c6c878) /* 0.298531028 */, 19 },
+ /* 7870 */ { MAD_F(0x04c6fd83) /* 0.298581612 */, 19 },
+ /* 7871 */ { MAD_F(0x04c7328e) /* 0.298632199 */, 19 },
+
+ /* 7872 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 19 },
+ /* 7873 */ { MAD_F(0x04c79ca7) /* 0.298733379 */, 19 },
+ /* 7874 */ { MAD_F(0x04c7d1b4) /* 0.298783972 */, 19 },
+ /* 7875 */ { MAD_F(0x04c806c1) /* 0.298834567 */, 19 },
+ /* 7876 */ { MAD_F(0x04c83bcf) /* 0.298885165 */, 19 },
+ /* 7877 */ { MAD_F(0x04c870de) /* 0.298935764 */, 19 },
+ /* 7878 */ { MAD_F(0x04c8a5ed) /* 0.298986366 */, 19 },
+ /* 7879 */ { MAD_F(0x04c8dafd) /* 0.299036970 */, 19 },
+ /* 7880 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 19 },
+ /* 7881 */ { MAD_F(0x04c9451e) /* 0.299138184 */, 19 },
+ /* 7882 */ { MAD_F(0x04c97a30) /* 0.299188794 */, 19 },
+ /* 7883 */ { MAD_F(0x04c9af42) /* 0.299239406 */, 19 },
+ /* 7884 */ { MAD_F(0x04c9e455) /* 0.299290021 */, 19 },
+ /* 7885 */ { MAD_F(0x04ca1968) /* 0.299340638 */, 19 },
+ /* 7886 */ { MAD_F(0x04ca4e7c) /* 0.299391256 */, 19 },
+ /* 7887 */ { MAD_F(0x04ca8391) /* 0.299441877 */, 19 },
+
+ /* 7888 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 19 },
+ /* 7889 */ { MAD_F(0x04caedbb) /* 0.299543126 */, 19 },
+ /* 7890 */ { MAD_F(0x04cb22d1) /* 0.299593753 */, 19 },
+ /* 7891 */ { MAD_F(0x04cb57e8) /* 0.299644382 */, 19 },
+ /* 7892 */ { MAD_F(0x04cb8d00) /* 0.299695014 */, 19 },
+ /* 7893 */ { MAD_F(0x04cbc217) /* 0.299745648 */, 19 },
+ /* 7894 */ { MAD_F(0x04cbf730) /* 0.299796284 */, 19 },
+ /* 7895 */ { MAD_F(0x04cc2c49) /* 0.299846922 */, 19 },
+ /* 7896 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 19 },
+ /* 7897 */ { MAD_F(0x04cc967d) /* 0.299948204 */, 19 },
+ /* 7898 */ { MAD_F(0x04cccb98) /* 0.299998849 */, 19 },
+ /* 7899 */ { MAD_F(0x04cd00b3) /* 0.300049495 */, 19 },
+ /* 7900 */ { MAD_F(0x04cd35cf) /* 0.300100144 */, 19 },
+ /* 7901 */ { MAD_F(0x04cd6aeb) /* 0.300150795 */, 19 },
+ /* 7902 */ { MAD_F(0x04cda008) /* 0.300201448 */, 19 },
+ /* 7903 */ { MAD_F(0x04cdd526) /* 0.300252103 */, 19 },
+
+ /* 7904 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 19 },
+ /* 7905 */ { MAD_F(0x04ce3f63) /* 0.300353420 */, 19 },
+ /* 7906 */ { MAD_F(0x04ce7482) /* 0.300404082 */, 19 },
+ /* 7907 */ { MAD_F(0x04cea9a2) /* 0.300454745 */, 19 },
+ /* 7908 */ { MAD_F(0x04cedec3) /* 0.300505411 */, 19 },
+ /* 7909 */ { MAD_F(0x04cf13e4) /* 0.300556079 */, 19 },
+ /* 7910 */ { MAD_F(0x04cf4906) /* 0.300606749 */, 19 },
+ /* 7911 */ { MAD_F(0x04cf7e28) /* 0.300657421 */, 19 },
+ /* 7912 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 19 },
+ /* 7913 */ { MAD_F(0x04cfe86e) /* 0.300758772 */, 19 },
+ /* 7914 */ { MAD_F(0x04d01d92) /* 0.300809451 */, 19 },
+ /* 7915 */ { MAD_F(0x04d052b6) /* 0.300860132 */, 19 },
+ /* 7916 */ { MAD_F(0x04d087db) /* 0.300910815 */, 19 },
+ /* 7917 */ { MAD_F(0x04d0bd01) /* 0.300961500 */, 19 },
+ /* 7918 */ { MAD_F(0x04d0f227) /* 0.301012187 */, 19 },
+ /* 7919 */ { MAD_F(0x04d1274e) /* 0.301062876 */, 19 },
+
+ /* 7920 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 19 },
+ /* 7921 */ { MAD_F(0x04d1919e) /* 0.301164261 */, 19 },
+ /* 7922 */ { MAD_F(0x04d1c6c6) /* 0.301214957 */, 19 },
+ /* 7923 */ { MAD_F(0x04d1fbef) /* 0.301265655 */, 19 },
+ /* 7924 */ { MAD_F(0x04d23119) /* 0.301316355 */, 19 },
+ /* 7925 */ { MAD_F(0x04d26643) /* 0.301367057 */, 19 },
+ /* 7926 */ { MAD_F(0x04d29b6e) /* 0.301417761 */, 19 },
+ /* 7927 */ { MAD_F(0x04d2d099) /* 0.301468468 */, 19 },
+ /* 7928 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 19 },
+ /* 7929 */ { MAD_F(0x04d33af2) /* 0.301569887 */, 19 },
+ /* 7930 */ { MAD_F(0x04d3701f) /* 0.301620599 */, 19 },
+ /* 7931 */ { MAD_F(0x04d3a54d) /* 0.301671314 */, 19 },
+ /* 7932 */ { MAD_F(0x04d3da7b) /* 0.301722031 */, 19 },
+ /* 7933 */ { MAD_F(0x04d40faa) /* 0.301772751 */, 19 },
+ /* 7934 */ { MAD_F(0x04d444d9) /* 0.301823472 */, 19 },
+ /* 7935 */ { MAD_F(0x04d47a09) /* 0.301874195 */, 19 },
+
+ /* 7936 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 19 },
+ /* 7937 */ { MAD_F(0x04d4e46b) /* 0.301975649 */, 19 },
+ /* 7938 */ { MAD_F(0x04d5199c) /* 0.302026378 */, 19 },
+ /* 7939 */ { MAD_F(0x04d54ecf) /* 0.302077110 */, 19 },
+ /* 7940 */ { MAD_F(0x04d58401) /* 0.302127845 */, 19 },
+ /* 7941 */ { MAD_F(0x04d5b935) /* 0.302178581 */, 19 },
+ /* 7942 */ { MAD_F(0x04d5ee69) /* 0.302229319 */, 19 },
+ /* 7943 */ { MAD_F(0x04d6239d) /* 0.302280060 */, 19 },
+ /* 7944 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 19 },
+ /* 7945 */ { MAD_F(0x04d68e08) /* 0.302381547 */, 19 },
+ /* 7946 */ { MAD_F(0x04d6c33e) /* 0.302432294 */, 19 },
+ /* 7947 */ { MAD_F(0x04d6f875) /* 0.302483043 */, 19 },
+ /* 7948 */ { MAD_F(0x04d72dad) /* 0.302533794 */, 19 },
+ /* 7949 */ { MAD_F(0x04d762e5) /* 0.302584547 */, 19 },
+ /* 7950 */ { MAD_F(0x04d7981d) /* 0.302635303 */, 19 },
+ /* 7951 */ { MAD_F(0x04d7cd56) /* 0.302686060 */, 19 },
+
+ /* 7952 */ { MAD_F(0x04d80290) /* 0.302736820 */, 19 },
+ /* 7953 */ { MAD_F(0x04d837ca) /* 0.302787581 */, 19 },
+ /* 7954 */ { MAD_F(0x04d86d05) /* 0.302838345 */, 19 },
+ /* 7955 */ { MAD_F(0x04d8a240) /* 0.302889111 */, 19 },
+ /* 7956 */ { MAD_F(0x04d8d77c) /* 0.302939879 */, 19 },
+ /* 7957 */ { MAD_F(0x04d90cb9) /* 0.302990650 */, 19 },
+ /* 7958 */ { MAD_F(0x04d941f6) /* 0.303041422 */, 19 },
+ /* 7959 */ { MAD_F(0x04d97734) /* 0.303092197 */, 19 },
+ /* 7960 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 19 },
+ /* 7961 */ { MAD_F(0x04d9e1b1) /* 0.303193752 */, 19 },
+ /* 7962 */ { MAD_F(0x04da16f0) /* 0.303244533 */, 19 },
+ /* 7963 */ { MAD_F(0x04da4c30) /* 0.303295316 */, 19 },
+ /* 7964 */ { MAD_F(0x04da8171) /* 0.303346101 */, 19 },
+ /* 7965 */ { MAD_F(0x04dab6b2) /* 0.303396889 */, 19 },
+ /* 7966 */ { MAD_F(0x04daebf4) /* 0.303447678 */, 19 },
+ /* 7967 */ { MAD_F(0x04db2136) /* 0.303498469 */, 19 },
+
+ /* 7968 */ { MAD_F(0x04db5679) /* 0.303549263 */, 19 },
+ /* 7969 */ { MAD_F(0x04db8bbc) /* 0.303600059 */, 19 },
+ /* 7970 */ { MAD_F(0x04dbc100) /* 0.303650857 */, 19 },
+ /* 7971 */ { MAD_F(0x04dbf644) /* 0.303701657 */, 19 },
+ /* 7972 */ { MAD_F(0x04dc2b8a) /* 0.303752459 */, 19 },
+ /* 7973 */ { MAD_F(0x04dc60cf) /* 0.303803263 */, 19 },
+ /* 7974 */ { MAD_F(0x04dc9616) /* 0.303854070 */, 19 },
+ /* 7975 */ { MAD_F(0x04dccb5c) /* 0.303904878 */, 19 },
+ /* 7976 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 19 },
+ /* 7977 */ { MAD_F(0x04dd35ec) /* 0.304006502 */, 19 },
+ /* 7978 */ { MAD_F(0x04dd6b34) /* 0.304057317 */, 19 },
+ /* 7979 */ { MAD_F(0x04dda07d) /* 0.304108134 */, 19 },
+ /* 7980 */ { MAD_F(0x04ddd5c7) /* 0.304158953 */, 19 },
+ /* 7981 */ { MAD_F(0x04de0b11) /* 0.304209774 */, 19 },
+ /* 7982 */ { MAD_F(0x04de405c) /* 0.304260597 */, 19 },
+ /* 7983 */ { MAD_F(0x04de75a7) /* 0.304311423 */, 19 },
+
+ /* 7984 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 19 },
+ /* 7985 */ { MAD_F(0x04dee040) /* 0.304413080 */, 19 },
+ /* 7986 */ { MAD_F(0x04df158d) /* 0.304463912 */, 19 },
+ /* 7987 */ { MAD_F(0x04df4adb) /* 0.304514746 */, 19 },
+ /* 7988 */ { MAD_F(0x04df8029) /* 0.304565582 */, 19 },
+ /* 7989 */ { MAD_F(0x04dfb578) /* 0.304616421 */, 19 },
+ /* 7990 */ { MAD_F(0x04dfeac7) /* 0.304667261 */, 19 },
+ /* 7991 */ { MAD_F(0x04e02017) /* 0.304718103 */, 19 },
+ /* 7992 */ { MAD_F(0x04e05567) /* 0.304768948 */, 19 },
+ /* 7993 */ { MAD_F(0x04e08ab8) /* 0.304819795 */, 19 },
+ /* 7994 */ { MAD_F(0x04e0c00a) /* 0.304870644 */, 19 },
+ /* 7995 */ { MAD_F(0x04e0f55c) /* 0.304921495 */, 19 },
+ /* 7996 */ { MAD_F(0x04e12aaf) /* 0.304972348 */, 19 },
+ /* 7997 */ { MAD_F(0x04e16002) /* 0.305023203 */, 19 },
+ /* 7998 */ { MAD_F(0x04e19556) /* 0.305074060 */, 19 },
+ /* 7999 */ { MAD_F(0x04e1caab) /* 0.305124920 */, 19 },
+
+ /* 8000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 19 },
+ /* 8001 */ { MAD_F(0x04e23555) /* 0.305226645 */, 19 },
+ /* 8002 */ { MAD_F(0x04e26aac) /* 0.305277511 */, 19 },
+ /* 8003 */ { MAD_F(0x04e2a002) /* 0.305328379 */, 19 },
+ /* 8004 */ { MAD_F(0x04e2d55a) /* 0.305379249 */, 19 },
+ /* 8005 */ { MAD_F(0x04e30ab2) /* 0.305430121 */, 19 },
+ /* 8006 */ { MAD_F(0x04e3400a) /* 0.305480995 */, 19 },
+ /* 8007 */ { MAD_F(0x04e37563) /* 0.305531872 */, 19 },
+ /* 8008 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 19 },
+ /* 8009 */ { MAD_F(0x04e3e017) /* 0.305633631 */, 19 },
+ /* 8010 */ { MAD_F(0x04e41572) /* 0.305684513 */, 19 },
+ /* 8011 */ { MAD_F(0x04e44acd) /* 0.305735398 */, 19 },
+ /* 8012 */ { MAD_F(0x04e48029) /* 0.305786285 */, 19 },
+ /* 8013 */ { MAD_F(0x04e4b585) /* 0.305837174 */, 19 },
+ /* 8014 */ { MAD_F(0x04e4eae2) /* 0.305888066 */, 19 },
+ /* 8015 */ { MAD_F(0x04e52040) /* 0.305938959 */, 19 },
+
+ /* 8016 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 19 },
+ /* 8017 */ { MAD_F(0x04e58afd) /* 0.306040752 */, 19 },
+ /* 8018 */ { MAD_F(0x04e5c05c) /* 0.306091652 */, 19 },
+ /* 8019 */ { MAD_F(0x04e5f5bc) /* 0.306142554 */, 19 },
+ /* 8020 */ { MAD_F(0x04e62b1c) /* 0.306193457 */, 19 },
+ /* 8021 */ { MAD_F(0x04e6607d) /* 0.306244364 */, 19 },
+ /* 8022 */ { MAD_F(0x04e695df) /* 0.306295272 */, 19 },
+ /* 8023 */ { MAD_F(0x04e6cb41) /* 0.306346182 */, 19 },
+ /* 8024 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 19 },
+ /* 8025 */ { MAD_F(0x04e73607) /* 0.306448009 */, 19 },
+ /* 8026 */ { MAD_F(0x04e76b6b) /* 0.306498925 */, 19 },
+ /* 8027 */ { MAD_F(0x04e7a0cf) /* 0.306549844 */, 19 },
+ /* 8028 */ { MAD_F(0x04e7d634) /* 0.306600765 */, 19 },
+ /* 8029 */ { MAD_F(0x04e80b99) /* 0.306651688 */, 19 },
+ /* 8030 */ { MAD_F(0x04e84100) /* 0.306702613 */, 19 },
+ /* 8031 */ { MAD_F(0x04e87666) /* 0.306753540 */, 19 },
+
+ /* 8032 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 19 },
+ /* 8033 */ { MAD_F(0x04e8e135) /* 0.306855401 */, 19 },
+ /* 8034 */ { MAD_F(0x04e9169e) /* 0.306906334 */, 19 },
+ /* 8035 */ { MAD_F(0x04e94c07) /* 0.306957270 */, 19 },
+ /* 8036 */ { MAD_F(0x04e98170) /* 0.307008208 */, 19 },
+ /* 8037 */ { MAD_F(0x04e9b6da) /* 0.307059148 */, 19 },
+ /* 8038 */ { MAD_F(0x04e9ec45) /* 0.307110090 */, 19 },
+ /* 8039 */ { MAD_F(0x04ea21b0) /* 0.307161034 */, 19 },
+ /* 8040 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 19 },
+ /* 8041 */ { MAD_F(0x04ea8c88) /* 0.307262928 */, 19 },
+ /* 8042 */ { MAD_F(0x04eac1f5) /* 0.307313879 */, 19 },
+ /* 8043 */ { MAD_F(0x04eaf762) /* 0.307364831 */, 19 },
+ /* 8044 */ { MAD_F(0x04eb2cd0) /* 0.307415786 */, 19 },
+ /* 8045 */ { MAD_F(0x04eb623f) /* 0.307466743 */, 19 },
+ /* 8046 */ { MAD_F(0x04eb97ae) /* 0.307517702 */, 19 },
+ /* 8047 */ { MAD_F(0x04ebcd1e) /* 0.307568663 */, 19 },
+
+ /* 8048 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 19 },
+ /* 8049 */ { MAD_F(0x04ec37ff) /* 0.307670591 */, 19 },
+ /* 8050 */ { MAD_F(0x04ec6d71) /* 0.307721558 */, 19 },
+ /* 8051 */ { MAD_F(0x04eca2e3) /* 0.307772528 */, 19 },
+ /* 8052 */ { MAD_F(0x04ecd855) /* 0.307823499 */, 19 },
+ /* 8053 */ { MAD_F(0x04ed0dc8) /* 0.307874473 */, 19 },
+ /* 8054 */ { MAD_F(0x04ed433c) /* 0.307925449 */, 19 },
+ /* 8055 */ { MAD_F(0x04ed78b0) /* 0.307976426 */, 19 },
+ /* 8056 */ { MAD_F(0x04edae25) /* 0.308027406 */, 19 },
+ /* 8057 */ { MAD_F(0x04ede39a) /* 0.308078389 */, 19 },
+ /* 8058 */ { MAD_F(0x04ee1910) /* 0.308129373 */, 19 },
+ /* 8059 */ { MAD_F(0x04ee4e87) /* 0.308180359 */, 19 },
+ /* 8060 */ { MAD_F(0x04ee83fe) /* 0.308231347 */, 19 },
+ /* 8061 */ { MAD_F(0x04eeb976) /* 0.308282338 */, 19 },
+ /* 8062 */ { MAD_F(0x04eeeeee) /* 0.308333331 */, 19 },
+ /* 8063 */ { MAD_F(0x04ef2467) /* 0.308384325 */, 19 },
+
+ /* 8064 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 19 },
+ /* 8065 */ { MAD_F(0x04ef8f5a) /* 0.308486321 */, 19 },
+ /* 8066 */ { MAD_F(0x04efc4d5) /* 0.308537322 */, 19 },
+ /* 8067 */ { MAD_F(0x04effa50) /* 0.308588325 */, 19 },
+ /* 8068 */ { MAD_F(0x04f02fcb) /* 0.308639331 */, 19 },
+ /* 8069 */ { MAD_F(0x04f06547) /* 0.308690338 */, 19 },
+ /* 8070 */ { MAD_F(0x04f09ac4) /* 0.308741348 */, 19 },
+ /* 8071 */ { MAD_F(0x04f0d041) /* 0.308792359 */, 19 },
+ /* 8072 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 19 },
+ /* 8073 */ { MAD_F(0x04f13b3e) /* 0.308894389 */, 19 },
+ /* 8074 */ { MAD_F(0x04f170bd) /* 0.308945407 */, 19 },
+ /* 8075 */ { MAD_F(0x04f1a63c) /* 0.308996427 */, 19 },
+ /* 8076 */ { MAD_F(0x04f1dbbd) /* 0.309047449 */, 19 },
+ /* 8077 */ { MAD_F(0x04f2113d) /* 0.309098473 */, 19 },
+ /* 8078 */ { MAD_F(0x04f246bf) /* 0.309149499 */, 19 },
+ /* 8079 */ { MAD_F(0x04f27c40) /* 0.309200528 */, 19 },
+
+ /* 8080 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 19 },
+ /* 8081 */ { MAD_F(0x04f2e746) /* 0.309302591 */, 19 },
+ /* 8082 */ { MAD_F(0x04f31cc9) /* 0.309353626 */, 19 },
+ /* 8083 */ { MAD_F(0x04f3524d) /* 0.309404663 */, 19 },
+ /* 8084 */ { MAD_F(0x04f387d2) /* 0.309455702 */, 19 },
+ /* 8085 */ { MAD_F(0x04f3bd57) /* 0.309506743 */, 19 },
+ /* 8086 */ { MAD_F(0x04f3f2dd) /* 0.309557786 */, 19 },
+ /* 8087 */ { MAD_F(0x04f42864) /* 0.309608831 */, 19 },
+ /* 8088 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 19 },
+ /* 8089 */ { MAD_F(0x04f49372) /* 0.309710928 */, 19 },
+ /* 8090 */ { MAD_F(0x04f4c8fa) /* 0.309761980 */, 19 },
+ /* 8091 */ { MAD_F(0x04f4fe83) /* 0.309813033 */, 19 },
+ /* 8092 */ { MAD_F(0x04f5340c) /* 0.309864089 */, 19 },
+ /* 8093 */ { MAD_F(0x04f56996) /* 0.309915147 */, 19 },
+ /* 8094 */ { MAD_F(0x04f59f20) /* 0.309966207 */, 19 },
+ /* 8095 */ { MAD_F(0x04f5d4ab) /* 0.310017269 */, 19 },
+
+ /* 8096 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 19 },
+ /* 8097 */ { MAD_F(0x04f63fc2) /* 0.310119400 */, 19 },
+ /* 8098 */ { MAD_F(0x04f6754f) /* 0.310170468 */, 19 },
+ /* 8099 */ { MAD_F(0x04f6aadc) /* 0.310221539 */, 19 },
+ /* 8100 */ { MAD_F(0x04f6e06a) /* 0.310272611 */, 19 },
+ /* 8101 */ { MAD_F(0x04f715f8) /* 0.310323686 */, 19 },
+ /* 8102 */ { MAD_F(0x04f74b87) /* 0.310374763 */, 19 },
+ /* 8103 */ { MAD_F(0x04f78116) /* 0.310425842 */, 19 },
+ /* 8104 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 19 },
+ /* 8105 */ { MAD_F(0x04f7ec37) /* 0.310528006 */, 19 },
+ /* 8106 */ { MAD_F(0x04f821c8) /* 0.310579091 */, 19 },
+ /* 8107 */ { MAD_F(0x04f85759) /* 0.310630179 */, 19 },
+ /* 8108 */ { MAD_F(0x04f88cec) /* 0.310681268 */, 19 },
+ /* 8109 */ { MAD_F(0x04f8c27e) /* 0.310732360 */, 19 },
+ /* 8110 */ { MAD_F(0x04f8f812) /* 0.310783453 */, 19 },
+ /* 8111 */ { MAD_F(0x04f92da6) /* 0.310834549 */, 19 },
+
+ /* 8112 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 19 },
+ /* 8113 */ { MAD_F(0x04f998cf) /* 0.310936747 */, 19 },
+ /* 8114 */ { MAD_F(0x04f9ce65) /* 0.310987849 */, 19 },
+ /* 8115 */ { MAD_F(0x04fa03fb) /* 0.311038953 */, 19 },
+ /* 8116 */ { MAD_F(0x04fa3992) /* 0.311090059 */, 19 },
+ /* 8117 */ { MAD_F(0x04fa6f29) /* 0.311141168 */, 19 },
+ /* 8118 */ { MAD_F(0x04faa4c1) /* 0.311192278 */, 19 },
+ /* 8119 */ { MAD_F(0x04fada59) /* 0.311243390 */, 19 },
+ /* 8120 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 19 },
+ /* 8121 */ { MAD_F(0x04fb458c) /* 0.311345622 */, 19 },
+ /* 8122 */ { MAD_F(0x04fb7b26) /* 0.311396741 */, 19 },
+ /* 8123 */ { MAD_F(0x04fbb0c1) /* 0.311447862 */, 19 },
+ /* 8124 */ { MAD_F(0x04fbe65c) /* 0.311498985 */, 19 },
+ /* 8125 */ { MAD_F(0x04fc1bf8) /* 0.311550110 */, 19 },
+ /* 8126 */ { MAD_F(0x04fc5194) /* 0.311601237 */, 19 },
+ /* 8127 */ { MAD_F(0x04fc8731) /* 0.311652366 */, 19 },
+
+ /* 8128 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 19 },
+ /* 8129 */ { MAD_F(0x04fcf26c) /* 0.311754631 */, 19 },
+ /* 8130 */ { MAD_F(0x04fd280b) /* 0.311805767 */, 19 },
+ /* 8131 */ { MAD_F(0x04fd5daa) /* 0.311856905 */, 19 },
+ /* 8132 */ { MAD_F(0x04fd934a) /* 0.311908044 */, 19 },
+ /* 8133 */ { MAD_F(0x04fdc8ea) /* 0.311959186 */, 19 },
+ /* 8134 */ { MAD_F(0x04fdfe8b) /* 0.312010330 */, 19 },
+ /* 8135 */ { MAD_F(0x04fe342c) /* 0.312061476 */, 19 },
+ /* 8136 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 19 },
+ /* 8137 */ { MAD_F(0x04fe9f71) /* 0.312163775 */, 19 },
+ /* 8138 */ { MAD_F(0x04fed514) /* 0.312214927 */, 19 },
+ /* 8139 */ { MAD_F(0x04ff0ab8) /* 0.312266082 */, 19 },
+ /* 8140 */ { MAD_F(0x04ff405c) /* 0.312317238 */, 19 },
+ /* 8141 */ { MAD_F(0x04ff7601) /* 0.312368397 */, 19 },
+ /* 8142 */ { MAD_F(0x04ffaba6) /* 0.312419558 */, 19 },
+ /* 8143 */ { MAD_F(0x04ffe14c) /* 0.312470720 */, 19 },
+
+ /* 8144 */ { MAD_F(0x050016f3) /* 0.312521885 */, 19 },
+ /* 8145 */ { MAD_F(0x05004c9a) /* 0.312573052 */, 19 },
+ /* 8146 */ { MAD_F(0x05008241) /* 0.312624222 */, 19 },
+ /* 8147 */ { MAD_F(0x0500b7e9) /* 0.312675393 */, 19 },
+ /* 8148 */ { MAD_F(0x0500ed92) /* 0.312726566 */, 19 },
+ /* 8149 */ { MAD_F(0x0501233b) /* 0.312777742 */, 19 },
+ /* 8150 */ { MAD_F(0x050158e5) /* 0.312828919 */, 19 },
+ /* 8151 */ { MAD_F(0x05018e90) /* 0.312880099 */, 19 },
+ /* 8152 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 19 },
+ /* 8153 */ { MAD_F(0x0501f9e6) /* 0.312982464 */, 19 },
+ /* 8154 */ { MAD_F(0x05022f92) /* 0.313033650 */, 19 },
+ /* 8155 */ { MAD_F(0x0502653f) /* 0.313084838 */, 19 },
+ /* 8156 */ { MAD_F(0x05029aec) /* 0.313136028 */, 19 },
+ /* 8157 */ { MAD_F(0x0502d09a) /* 0.313187220 */, 19 },
+ /* 8158 */ { MAD_F(0x05030648) /* 0.313238414 */, 19 },
+ /* 8159 */ { MAD_F(0x05033bf7) /* 0.313289611 */, 19 },
+
+ /* 8160 */ { MAD_F(0x050371a7) /* 0.313340809 */, 19 },
+ /* 8161 */ { MAD_F(0x0503a757) /* 0.313392010 */, 19 },
+ /* 8162 */ { MAD_F(0x0503dd07) /* 0.313443212 */, 19 },
+ /* 8163 */ { MAD_F(0x050412b9) /* 0.313494417 */, 19 },
+ /* 8164 */ { MAD_F(0x0504486a) /* 0.313545624 */, 19 },
+ /* 8165 */ { MAD_F(0x05047e1d) /* 0.313596833 */, 19 },
+ /* 8166 */ { MAD_F(0x0504b3cf) /* 0.313648044 */, 19 },
+ /* 8167 */ { MAD_F(0x0504e983) /* 0.313699257 */, 19 },
+ /* 8168 */ { MAD_F(0x05051f37) /* 0.313750472 */, 19 },
+ /* 8169 */ { MAD_F(0x050554eb) /* 0.313801689 */, 19 },
+ /* 8170 */ { MAD_F(0x05058aa0) /* 0.313852909 */, 19 },
+ /* 8171 */ { MAD_F(0x0505c056) /* 0.313904130 */, 19 },
+ /* 8172 */ { MAD_F(0x0505f60c) /* 0.313955354 */, 19 },
+ /* 8173 */ { MAD_F(0x05062bc3) /* 0.314006579 */, 19 },
+ /* 8174 */ { MAD_F(0x0506617a) /* 0.314057807 */, 19 },
+ /* 8175 */ { MAD_F(0x05069732) /* 0.314109037 */, 19 },
+
+ /* 8176 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 19 },
+ /* 8177 */ { MAD_F(0x050702a4) /* 0.314211502 */, 19 },
+ /* 8178 */ { MAD_F(0x0507385d) /* 0.314262739 */, 19 },
+ /* 8179 */ { MAD_F(0x05076e17) /* 0.314313977 */, 19 },
+ /* 8180 */ { MAD_F(0x0507a3d2) /* 0.314365217 */, 19 },
+ /* 8181 */ { MAD_F(0x0507d98d) /* 0.314416459 */, 19 },
+ /* 8182 */ { MAD_F(0x05080f49) /* 0.314467704 */, 19 },
+ /* 8183 */ { MAD_F(0x05084506) /* 0.314518950 */, 19 },
+ /* 8184 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 19 },
+ /* 8185 */ { MAD_F(0x0508b080) /* 0.314621449 */, 19 },
+ /* 8186 */ { MAD_F(0x0508e63e) /* 0.314672702 */, 19 },
+ /* 8187 */ { MAD_F(0x05091bfd) /* 0.314723957 */, 19 },
+ /* 8188 */ { MAD_F(0x050951bc) /* 0.314775214 */, 19 },
+ /* 8189 */ { MAD_F(0x0509877c) /* 0.314826473 */, 19 },
+ /* 8190 */ { MAD_F(0x0509bd3c) /* 0.314877734 */, 19 },
+ /* 8191 */ { MAD_F(0x0509f2fd) /* 0.314928997 */, 19 },
+
+ /* 8192 */ { MAD_F(0x050a28be) /* 0.314980262 */, 19 },
+ /* 8193 */ { MAD_F(0x050a5e80) /* 0.315031530 */, 19 },
+ /* 8194 */ { MAD_F(0x050a9443) /* 0.315082799 */, 19 },
+ /* 8195 */ { MAD_F(0x050aca06) /* 0.315134071 */, 19 },
+ /* 8196 */ { MAD_F(0x050affc9) /* 0.315185344 */, 19 },
+ /* 8197 */ { MAD_F(0x050b358e) /* 0.315236620 */, 19 },
+ /* 8198 */ { MAD_F(0x050b6b52) /* 0.315287898 */, 19 },
+ /* 8199 */ { MAD_F(0x050ba118) /* 0.315339178 */, 19 },
+ /* 8200 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 19 },
+ /* 8201 */ { MAD_F(0x050c0ca4) /* 0.315441744 */, 19 },
+ /* 8202 */ { MAD_F(0x050c426b) /* 0.315493030 */, 19 },
+ /* 8203 */ { MAD_F(0x050c7833) /* 0.315544318 */, 19 },
+ /* 8204 */ { MAD_F(0x050cadfb) /* 0.315595608 */, 19 },
+ /* 8205 */ { MAD_F(0x050ce3c4) /* 0.315646901 */, 19 },
+ /* 8206 */ { MAD_F(0x050d198d) /* 0.315698195 */, 19 }
diff --git a/core/multimedia/opieplayer/libmad/sf_table.dat b/core/multimedia/opieplayer/libmad/sf_table.dat
new file mode 100644
index 0000000..18e6202
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/sf_table.dat
@@ -0,0 +1,100 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+/*
+ * These are the scalefactor values for Layer I and Layer II.
+ * The values are from Table B.1 of ISO/IEC 11172-3.
+ *
+ * There is some error introduced by the 32-bit fixed-point representation;
+ * the amount of error is shown. For 16-bit PCM output, this shouldn't be
+ * too much of a problem.
+ */
+
+ MAD_F(0x20000000), /* 2.000000000000 => 2.000000000000, e 0.000000000000 */
+ MAD_F(0x1965fea5), /* 1.587401051968 => 1.587401051074, e 0.000000000894 */
+ MAD_F(0x1428a2fa), /* 1.259921049895 => 1.259921051562, e -0.000000001667 */
+ MAD_F(0x10000000), /* 1.000000000000 => 1.000000000000, e 0.000000000000 */
+ MAD_F(0x0cb2ff53), /* 0.793700525984 => 0.793700527400, e -0.000000001416 */
+ MAD_F(0x0a14517d), /* 0.629960524947 => 0.629960525781, e -0.000000000833 */
+ MAD_F(0x08000000), /* 0.500000000000 => 0.500000000000, e 0.000000000000 */
+ MAD_F(0x06597fa9), /* 0.396850262992 => 0.396850261837, e 0.000000001155 */
+
+ MAD_F(0x050a28be), /* 0.314980262474 => 0.314980261028, e 0.000000001446 */
+ MAD_F(0x04000000), /* 0.250000000000 => 0.250000000000, e 0.000000000000 */
+ MAD_F(0x032cbfd5), /* 0.198425131496 => 0.198425132781, e -0.000000001285 */
+ MAD_F(0x0285145f), /* 0.157490131237 => 0.157490130514, e 0.000000000723 */
+ MAD_F(0x02000000), /* 0.125000000000 => 0.125000000000, e 0.000000000000 */
+ MAD_F(0x01965fea), /* 0.099212565748 => 0.099212564528, e 0.000000001220 */
+ MAD_F(0x01428a30), /* 0.078745065618 => 0.078745067120, e -0.000000001501 */
+ MAD_F(0x01000000), /* 0.062500000000 => 0.062500000000, e 0.000000000000 */
+
+ MAD_F(0x00cb2ff5), /* 0.049606282874 => 0.049606282264, e 0.000000000610 */
+ MAD_F(0x00a14518), /* 0.039372532809 => 0.039372533560, e -0.000000000751 */
+ MAD_F(0x00800000), /* 0.031250000000 => 0.031250000000, e 0.000000000000 */
+ MAD_F(0x006597fb), /* 0.024803141437 => 0.024803142995, e -0.000000001558 */
+ MAD_F(0x0050a28c), /* 0.019686266405 => 0.019686266780, e -0.000000000375 */
+ MAD_F(0x00400000), /* 0.015625000000 => 0.015625000000, e 0.000000000000 */
+ MAD_F(0x0032cbfd), /* 0.012401570719 => 0.012401569635, e 0.000000001084 */
+ MAD_F(0x00285146), /* 0.009843133202 => 0.009843133390, e -0.000000000188 */
+
+ MAD_F(0x00200000), /* 0.007812500000 => 0.007812500000, e 0.000000000000 */
+ MAD_F(0x001965ff), /* 0.006200785359 => 0.006200786680, e -0.000000001321 */
+ MAD_F(0x001428a3), /* 0.004921566601 => 0.004921566695, e -0.000000000094 */
+ MAD_F(0x00100000), /* 0.003906250000 => 0.003906250000, e 0.000000000000 */
+ MAD_F(0x000cb2ff), /* 0.003100392680 => 0.003100391477, e 0.000000001202 */
+ MAD_F(0x000a1451), /* 0.002460783301 => 0.002460781485, e 0.000000001816 */
+ MAD_F(0x00080000), /* 0.001953125000 => 0.001953125000, e 0.000000000000 */
+ MAD_F(0x00065980), /* 0.001550196340 => 0.001550197601, e -0.000000001262 */
+
+ MAD_F(0x00050a29), /* 0.001230391650 => 0.001230392605, e -0.000000000955 */
+ MAD_F(0x00040000), /* 0.000976562500 => 0.000976562500, e 0.000000000000 */
+ MAD_F(0x00032cc0), /* 0.000775098170 => 0.000775098801, e -0.000000000631 */
+ MAD_F(0x00028514), /* 0.000615195825 => 0.000615194440, e 0.000000001385 */
+ MAD_F(0x00020000), /* 0.000488281250 => 0.000488281250, e 0.000000000000 */
+ MAD_F(0x00019660), /* 0.000387549085 => 0.000387549400, e -0.000000000315 */
+ MAD_F(0x0001428a), /* 0.000307597913 => 0.000307597220, e 0.000000000693 */
+ MAD_F(0x00010000), /* 0.000244140625 => 0.000244140625, e 0.000000000000 */
+
+ MAD_F(0x0000cb30), /* 0.000193774542 => 0.000193774700, e -0.000000000158 */
+ MAD_F(0x0000a145), /* 0.000153798956 => 0.000153798610, e 0.000000000346 */
+ MAD_F(0x00008000), /* 0.000122070313 => 0.000122070313, e 0.000000000000 */
+ MAD_F(0x00006598), /* 0.000096887271 => 0.000096887350, e -0.000000000079 */
+ MAD_F(0x000050a3), /* 0.000076899478 => 0.000076901168, e -0.000000001689 */
+ MAD_F(0x00004000), /* 0.000061035156 => 0.000061035156, e 0.000000000000 */
+ MAD_F(0x000032cc), /* 0.000048443636 => 0.000048443675, e -0.000000000039 */
+ MAD_F(0x00002851), /* 0.000038449739 => 0.000038448721, e 0.000000001018 */
+
+ MAD_F(0x00002000), /* 0.000030517578 => 0.000030517578, e 0.000000000000 */
+ MAD_F(0x00001966), /* 0.000024221818 => 0.000024221838, e -0.000000000020 */
+ MAD_F(0x00001429), /* 0.000019224870 => 0.000019226223, e -0.000000001354 */
+ MAD_F(0x00001000), /* 0.000015258789 => 0.000015258789, e -0.000000000000 */
+ MAD_F(0x00000cb3), /* 0.000012110909 => 0.000012110919, e -0.000000000010 */
+ MAD_F(0x00000a14), /* 0.000009612435 => 0.000009611249, e 0.000000001186 */
+ MAD_F(0x00000800), /* 0.000007629395 => 0.000007629395, e -0.000000000000 */
+ MAD_F(0x00000659), /* 0.000006055454 => 0.000006053597, e 0.000000001858 */
+
+ MAD_F(0x0000050a), /* 0.000004806217 => 0.000004805624, e 0.000000000593 */
+ MAD_F(0x00000400), /* 0.000003814697 => 0.000003814697, e 0.000000000000 */
+ MAD_F(0x0000032d), /* 0.000003027727 => 0.000003028661, e -0.000000000934 */
+ MAD_F(0x00000285), /* 0.000002403109 => 0.000002402812, e 0.000000000296 */
+ MAD_F(0x00000200), /* 0.000001907349 => 0.000001907349, e -0.000000000000 */
+ MAD_F(0x00000196), /* 0.000001513864 => 0.000001512468, e 0.000000001396 */
+ MAD_F(0x00000143) /* 0.000001201554 => 0.000001203269, e -0.000000001714 */
diff --git a/core/multimedia/opieplayer/libmad/stream.c b/core/multimedia/opieplayer/libmad/stream.c
new file mode 100644
index 0000000..dea7b8e
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/stream.c
@@ -0,0 +1,123 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifdef HAVE_CONFIG_H
+# include "libmad_config.h"
+# endif
+
+# include "libmad_global.h"
+
+# include <stdlib.h>
+
+# include "bit.h"
+# include "stream.h"
+
+/*
+ * NAME: stream->init()
+ * DESCRIPTION: initialize stream struct
+ */
+void mad_stream_init(struct mad_stream *stream)
+{
+ stream->buffer = 0;
+ stream->bufend = 0;
+ stream->skiplen = 0;
+
+ stream->sync = 0;
+ stream->freerate = 0;
+
+ stream->this_frame = 0;
+ stream->next_frame = 0;
+ mad_bit_init(&stream->ptr, 0);
+
+ mad_bit_init(&stream->anc_ptr, 0);
+ stream->anc_bitlen = 0;
+
+ stream->main_data = 0;
+ stream->md_len = 0;
+
+ stream->options = 0;
+ stream->error = 0;
+}
+
+/*
+ * NAME: stream->finish()
+ * DESCRIPTION: deallocate any dynamic memory associated with stream
+ */
+void mad_stream_finish(struct mad_stream *stream)
+{
+ if (stream->main_data) {
+ free(stream->main_data);
+ stream->main_data = 0;
+ }
+
+ mad_bit_finish(&stream->anc_ptr);
+ mad_bit_finish(&stream->ptr);
+}
+
+/*
+ * NAME: stream->buffer()
+ * DESCRIPTION: set stream buffer pointers
+ */
+void mad_stream_buffer(struct mad_stream *stream,
+ unsigned char const *buffer, unsigned long length)
+{
+ stream->buffer = buffer;
+ stream->bufend = buffer + length;
+
+ stream->this_frame = buffer;
+ stream->next_frame = buffer;
+
+ stream->sync = 1;
+
+ mad_bit_init(&stream->ptr, buffer);
+}
+
+/*
+ * NAME: stream->skip()
+ * DESCRIPTION: arrange to skip bytes before the next frame
+ */
+void mad_stream_skip(struct mad_stream *stream, unsigned long length)
+{
+ stream->skiplen += length;
+}
+
+/*
+ * NAME: stream->sync()
+ * DESCRIPTION: locate the next stream sync word
+ */
+int mad_stream_sync(struct mad_stream *stream)
+{
+ register unsigned char const *ptr, *end;
+
+ ptr = mad_bit_nextbyte(&stream->ptr);
+ end = stream->bufend;
+
+ while (ptr < end - 1 &&
+ !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0))
+ ++ptr;
+
+ if (end - ptr < MAD_BUFFER_GUARD)
+ return -1;
+
+ mad_bit_init(&stream->ptr, ptr);
+
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmad/stream.h b/core/multimedia/opieplayer/libmad/stream.h
new file mode 100644
index 0000000..cf3280e
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/stream.h
@@ -0,0 +1,102 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifndef LIBMAD_STREAM_H
+# define LIBMAD_STREAM_H
+
+# include "bit.h"
+
+# define MAD_BUFFER_GUARD 8
+# define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD)
+
+enum mad_error {
+ MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */
+ MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */
+
+ MAD_ERROR_NOMEM = 0x0031, /* not enough memory */
+
+ MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */
+ MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */
+ MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */
+ MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */
+ MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */
+
+ MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */
+ MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */
+ MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */
+ MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */
+ MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */
+ MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */
+ MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */
+ MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */
+ MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */
+ MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */
+ MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */
+ MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */
+};
+
+# define MAD_RECOVERABLE(error) ((error) & 0xff00)
+
+struct mad_stream {
+ unsigned char const *buffer; /* input bitstream buffer */
+ unsigned char const *bufend; /* end of buffer */
+ unsigned long skiplen; /* bytes to skip before next frame */
+
+ int sync; /* stream sync found */
+ unsigned long freerate; /* free bitrate (fixed) */
+
+ unsigned char const *this_frame; /* start of current frame */
+ unsigned char const *next_frame; /* start of next frame */
+ struct mad_bitptr ptr; /* current processing bit pointer */
+
+ struct mad_bitptr anc_ptr; /* ancillary bits pointer */
+ unsigned int anc_bitlen; /* number of ancillary bits */
+
+ unsigned char (*main_data)[MAD_BUFFER_MDLEN];
+ /* Layer III main_data() */
+ unsigned int md_len; /* bytes in main_data */
+
+ int options; /* decoding options (see below) */
+ enum mad_error error; /* error code (see above) */
+};
+
+enum {
+ MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */
+ MAD_OPTION_HALFSAMPLERATE = 0x0002, /* generate PCM at 1/2 sample rate */
+# if 0 /* not yet implemented */
+ MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */
+ MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */
+ MAD_OPTION_SINGLECHANNEL = 0x0030, /* combine channels */
+# endif
+};
+
+void mad_stream_init(struct mad_stream *);
+void mad_stream_finish(struct mad_stream *);
+
+# define mad_stream_options(stream, opts) ((stream)->options = (opts))
+
+void mad_stream_buffer(struct mad_stream *,
+ unsigned char const *, unsigned long);
+void mad_stream_skip(struct mad_stream *, unsigned long);
+
+int mad_stream_sync(struct mad_stream *);
+
+# endif
diff --git a/core/multimedia/opieplayer/libmad/synth.c b/core/multimedia/opieplayer/libmad/synth.c
new file mode 100644
index 0000000..e1914c9
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/synth.c
@@ -0,0 +1,855 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifdef HAVE_CONFIG_H
+# include "libmad_config.h"
+# endif
+
+# include "libmad_global.h"
+
+# include "fixed.h"
+# include "frame.h"
+# include "synth.h"
+
+/*
+ * NAME: synth->init()
+ * DESCRIPTION: initialize synth struct
+ */
+void mad_synth_init(struct mad_synth *synth)
+{
+ mad_synth_mute(synth);
+
+ synth->phase = 0;
+
+ synth->pcm.samplerate = 0;
+ synth->pcm.channels = 0;
+ synth->pcm.length = 0;
+}
+
+/*
+ * NAME: synth->mute()
+ * DESCRIPTION: zero all polyphase filterbank values, resetting synthesis
+ */
+void mad_synth_mute(struct mad_synth *synth)
+{
+ unsigned int ch, s, v;
+
+ for (ch = 0; ch < 2; ++ch) {
+ for (s = 0; s < 16; ++s) {
+ for (v = 0; v < 8; ++v) {
+ synth->filter[ch][0][0][s][v] = synth->filter[ch][0][1][s][v] =
+ synth->filter[ch][1][0][s][v] = synth->filter[ch][1][1][s][v] = 0;
+ }
+ }
+ }
+}
+
+/*
+ * An optional optimization called here the Subband Synthesis Optimization
+ * (SSO) improves the performance of subband synthesis at the expense of
+ * accuracy.
+ *
+ * The idea is to simplify 32x32->64-bit multiplication to 32x32->32 such
+ * that extra scaling and rounding are not necessary. This often allows the
+ * compiler to use faster 32-bit multiply-accumulate instructions instead of
+ * explicit 64-bit multiply, shift, and add instructions.
+ *
+ * SSO works like this: a full 32x32->64-bit multiply of two mad_fixed_t
+ * values requires the result to be right-shifted 28 bits to be properly
+ * scaled to the same fixed-point format. Right shifts can be applied at any
+ * time to either operand or to the result, so the optimization involves
+ * careful placement of these shifts to minimize the loss of accuracy.
+ *
+ * First, a 14-bit shift is applied with rounding at compile-time to the D[]
+ * table of coefficients for the subband synthesis window. This only loses 2
+ * bits of accuracy because the lower 12 bits are always zero. A second
+ * 12-bit shift occurs after the DCT calculation. This loses 12 bits of
+ * accuracy. Finally, a third 2-bit shift occurs just before the sample is
+ * saved in the PCM buffer. 14 + 12 + 2 == 28 bits.
+ */
+
+/* FPM_DEFAULT without OPT_SSO will actually lose accuracy and performance */
+
+# if defined(FPM_DEFAULT) && !defined(OPT_SSO)
+# define OPT_SSO
+# endif
+
+/* second SSO shift, with rounding */
+
+# if defined(OPT_SSO)
+# define SHIFT(x) (((x) + (1L << 11)) >> 12)
+# else
+# define SHIFT(x) (x)
+# endif
+
+/* possible DCT speed optimization */
+
+# if defined(OPT_SPEED) && defined(MAD_F_MLX)
+# define OPT_DCTO
+# define MUL(x, y) \
+ ({ mad_fixed64hi_t hi; \
+ mad_fixed64lo_t lo; \
+ MAD_F_MLX(hi, lo, (x), (y)); \
+ hi << (32 - MAD_F_SCALEBITS - 3); \
+ })
+# else
+# undef OPT_DCTO
+# define MUL(x, y) mad_f_mul((x), (y))
+# endif
+
+/*
+ * NAME: dct32()
+ * DESCRIPTION: perform fast in[32]->out[32] DCT
+ */
+static
+void dct32(mad_fixed_t const in[32], unsigned int slot,
+ mad_fixed_t lo[16][8], mad_fixed_t hi[16][8])
+{
+ mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7;
+ mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15;
+ mad_fixed_t t16, t17, t18, t19, t20, t21, t22, t23;
+ mad_fixed_t t24, t25, t26, t27, t28, t29, t30, t31;
+ mad_fixed_t t32, t33, t34, t35, t36, t37, t38, t39;
+ mad_fixed_t t40, t41, t42, t43, t44, t45, t46, t47;
+ mad_fixed_t t48, t49, t50, t51, t52, t53, t54, t55;
+ mad_fixed_t t56, t57, t58, t59, t60, t61, t62, t63;
+ mad_fixed_t t64, t65, t66, t67, t68, t69, t70, t71;
+ mad_fixed_t t72, t73, t74, t75, t76, t77, t78, t79;
+ mad_fixed_t t80, t81, t82, t83, t84, t85, t86, t87;
+ mad_fixed_t t88, t89, t90, t91, t92, t93, t94, t95;
+ mad_fixed_t t96, t97, t98, t99, t100, t101, t102, t103;
+ mad_fixed_t t104, t105, t106, t107, t108, t109, t110, t111;
+ mad_fixed_t t112, t113, t114, t115, t116, t117, t118, t119;
+ mad_fixed_t t120, t121, t122, t123, t124, t125, t126, t127;
+ mad_fixed_t t128, t129, t130, t131, t132, t133, t134, t135;
+ mad_fixed_t t136, t137, t138, t139, t140, t141, t142, t143;
+ mad_fixed_t t144, t145, t146, t147, t148, t149, t150, t151;
+ mad_fixed_t t152, t153, t154, t155, t156, t157, t158, t159;
+ mad_fixed_t t160, t161, t162, t163, t164, t165, t166, t167;
+ mad_fixed_t t168, t169, t170, t171, t172, t173, t174, t175;
+ mad_fixed_t t176;
+
+ /* costab[i] = cos(PI / (2 * 32) * i) */
+
+# if defined(OPT_DCTO)
+ enum {
+ costab1 = MAD_F(0x7fd8878e),
+ costab2 = MAD_F(0x7f62368f),
+ costab3 = MAD_F(0x7e9d55fc),
+ costab4 = MAD_F(0x7d8a5f40),
+ costab5 = MAD_F(0x7c29fbee),
+ costab6 = MAD_F(0x7a7d055b),
+ costab7 = MAD_F(0x78848414),
+ costab8 = MAD_F(0x7641af3d),
+ costab9 = MAD_F(0x73b5ebd1),
+ costab10 = MAD_F(0x70e2cbc6),
+ costab11 = MAD_F(0x6dca0d14),
+ costab12 = MAD_F(0x6a6d98a4),
+ costab13 = MAD_F(0x66cf8120),
+ costab14 = MAD_F(0x62f201ac),
+ costab15 = MAD_F(0x5ed77c8a),
+ costab16 = MAD_F(0x5a82799a),
+ costab17 = MAD_F(0x55f5a4d2),
+ costab18 = MAD_F(0x5133cc94),
+ costab19 = MAD_F(0x4c3fdff4),
+ costab20 = MAD_F(0x471cece7),
+ costab21 = MAD_F(0x41ce1e65),
+ costab22 = MAD_F(0x3c56ba70),
+ costab23 = MAD_F(0x36ba2014),
+ costab24 = MAD_F(0x30fbc54d),
+ costab25 = MAD_F(0x2b1f34eb),
+ costab26 = MAD_F(0x25280c5e),
+ costab27 = MAD_F(0x1f19f97b),
+ costab28 = MAD_F(0x18f8b83c),
+ costab29 = MAD_F(0x12c8106f),
+ costab30 = MAD_F(0x0c8bd35e),
+ costab31 = MAD_F(0x0647d97c)
+ };
+# else
+ enum {
+ costab1 = MAD_F(0x0ffb10f2), /* 0.998795456 */
+ costab2 = MAD_F(0x0fec46d2), /* 0.995184727 */
+ costab3 = MAD_F(0x0fd3aac0), /* 0.989176510 */
+ costab4 = MAD_F(0x0fb14be8), /* 0.980785280 */
+ costab5 = MAD_F(0x0f853f7e), /* 0.970031253 */
+ costab6 = MAD_F(0x0f4fa0ab), /* 0.956940336 */
+ costab7 = MAD_F(0x0f109082), /* 0.941544065 */
+ costab8 = MAD_F(0x0ec835e8), /* 0.923879533 */
+ costab9 = MAD_F(0x0e76bd7a), /* 0.903989293 */
+ costab10 = MAD_F(0x0e1c5979), /* 0.881921264 */
+ costab11 = MAD_F(0x0db941a3), /* 0.857728610 */
+ costab12 = MAD_F(0x0d4db315), /* 0.831469612 */
+ costab13 = MAD_F(0x0cd9f024), /* 0.803207531 */
+ costab14 = MAD_F(0x0c5e4036), /* 0.773010453 */
+ costab15 = MAD_F(0x0bdaef91), /* 0.740951125 */
+ costab16 = MAD_F(0x0b504f33), /* 0.707106781 */
+ costab17 = MAD_F(0x0abeb49a), /* 0.671558955 */
+ costab18 = MAD_F(0x0a267993), /* 0.634393284 */
+ costab19 = MAD_F(0x0987fbfe), /* 0.595699304 */
+ costab20 = MAD_F(0x08e39d9d), /* 0.555570233 */
+ costab21 = MAD_F(0x0839c3cd), /* 0.514102744 */
+ costab22 = MAD_F(0x078ad74e), /* 0.471396737 */
+ costab23 = MAD_F(0x06d74402), /* 0.427555093 */
+ costab24 = MAD_F(0x061f78aa), /* 0.382683432 */
+ costab25 = MAD_F(0x0563e69d), /* 0.336889853 */
+ costab26 = MAD_F(0x04a5018c), /* 0.290284677 */
+ costab27 = MAD_F(0x03e33f2f), /* 0.242980180 */
+ costab28 = MAD_F(0x031f1708), /* 0.195090322 */
+ costab29 = MAD_F(0x0259020e), /* 0.146730474 */
+ costab30 = MAD_F(0x01917a6c), /* 0.098017140 */
+ costab31 = MAD_F(0x00c8fb30) /* 0.049067674 */
+ };
+# endif
+
+ t0 = in[0] + in[31]; t16 = MUL(in[0] - in[31], costab1);
+ t1 = in[15] + in[16]; t17 = MUL(in[15] - in[16], costab31);
+
+ t41 = t16 + t17;
+ t59 = MUL(t16 - t17, costab2);
+ t33 = t0 + t1;
+ t50 = MUL(t0 - t1, costab2);
+
+ t2 = in[7] + in[24]; t18 = MUL(in[7] - in[24], costab15);
+ t3 = in[8] + in[23]; t19 = MUL(in[8] - in[23], costab17);
+
+ t42 = t18 + t19;
+ t60 = MUL(t18 - t19, costab30);
+ t34 = t2 + t3;
+ t51 = MUL(t2 - t3, costab30);
+
+ t4 = in[3] + in[28]; t20 = MUL(in[3] - in[28], costab7);
+ t5 = in[12] + in[19]; t21 = MUL(in[12] - in[19], costab25);
+
+ t43 = t20 + t21;
+ t61 = MUL(t20 - t21, costab14);
+ t35 = t4 + t5;
+ t52 = MUL(t4 - t5, costab14);
+
+ t6 = in[4] + in[27]; t22 = MUL(in[4] - in[27], costab9);
+ t7 = in[11] + in[20]; t23 = MUL(in[11] - in[20], costab23);
+
+ t44 = t22 + t23;
+ t62 = MUL(t22 - t23, costab18);
+ t36 = t6 + t7;
+ t53 = MUL(t6 - t7, costab18);
+
+ t8 = in[1] + in[30]; t24 = MUL(in[1] - in[30], costab3);
+ t9 = in[14] + in[17]; t25 = MUL(in[14] - in[17], costab29);
+
+ t45 = t24 + t25;
+ t63 = MUL(t24 - t25, costab6);
+ t37 = t8 + t9;
+ t54 = MUL(t8 - t9, costab6);
+
+ t10 = in[6] + in[25]; t26 = MUL(in[6] - in[25], costab13);
+ t11 = in[9] + in[22]; t27 = MUL(in[9] - in[22], costab19);
+
+ t46 = t26 + t27;
+ t64 = MUL(t26 - t27, costab26);
+ t38 = t10 + t11;
+ t55 = MUL(t10 - t11, costab26);
+
+ t12 = in[2] + in[29]; t28 = MUL(in[2] - in[29], costab5);
+ t13 = in[13] + in[18]; t29 = MUL(in[13] - in[18], costab27);
+
+ t47 = t28 + t29;
+ t65 = MUL(t28 - t29, costab10);
+ t39 = t12 + t13;
+ t56 = MUL(t12 - t13, costab10);
+
+ t14 = in[5] + in[26]; t30 = MUL(in[5] - in[26], costab11);
+ t15 = in[10] + in[21]; t31 = MUL(in[10] - in[21], costab21);
+
+ t48 = t30 + t31;
+ t66 = MUL(t30 - t31, costab22);
+ t40 = t14 + t15;
+ t57 = MUL(t14 - t15, costab22);
+
+ t69 = t33 + t34; t89 = MUL(t33 - t34, costab4);
+ t70 = t35 + t36; t90 = MUL(t35 - t36, costab28);
+ t71 = t37 + t38; t91 = MUL(t37 - t38, costab12);
+ t72 = t39 + t40; t92 = MUL(t39 - t40, costab20);
+ t73 = t41 + t42; t94 = MUL(t41 - t42, costab4);
+ t74 = t43 + t44; t95 = MUL(t43 - t44, costab28);
+ t75 = t45 + t46; t96 = MUL(t45 - t46, costab12);
+ t76 = t47 + t48; t97 = MUL(t47 - t48, costab20);
+
+ t78 = t50 + t51; t100 = MUL(t50 - t51, costab4);
+ t79 = t52 + t53; t101 = MUL(t52 - t53, costab28);
+ t80 = t54 + t55; t102 = MUL(t54 - t55, costab12);
+ t81 = t56 + t57; t103 = MUL(t56 - t57, costab20);
+
+ t83 = t59 + t60; t106 = MUL(t59 - t60, costab4);
+ t84 = t61 + t62; t107 = MUL(t61 - t62, costab28);
+ t85 = t63 + t64; t108 = MUL(t63 - t64, costab12);
+ t86 = t65 + t66; t109 = MUL(t65 - t66, costab20);
+
+ t113 = t69 + t70;
+ t114 = t71 + t72;
+
+ /* 0 */ hi[15][slot] = SHIFT(t113 + t114);
+ /* 16 */ lo[ 0][slot] = SHIFT(MUL(t113 - t114, costab16));
+
+ t115 = t73 + t74;
+ t116 = t75 + t76;
+
+ t32 = t115 + t116;
+
+ /* 1 */ hi[14][slot] = SHIFT(t32);
+
+ t118 = t78 + t79;
+ t119 = t80 + t81;
+
+ t58 = t118 + t119;
+
+ /* 2 */ hi[13][slot] = SHIFT(t58);
+
+ t121 = t83 + t84;
+ t122 = t85 + t86;
+
+ t67 = t121 + t122;
+
+ t49 = (t67 << 1) - t32;
+
+ /* 3 */ hi[12][slot] = SHIFT(t49);
+
+ t125 = t89 + t90;
+ t126 = t91 + t92;
+
+ t93 = t125 + t126;
+
+ /* 4 */ hi[11][slot] = SHIFT(t93);
+
+ t128 = t94 + t95;
+ t129 = t96 + t97;
+
+ t98 = t128 + t129;
+
+ t68 = (t98 << 1) - t49;
+
+ /* 5 */ hi[10][slot] = SHIFT(t68);
+
+ t132 = t100 + t101;
+ t133 = t102 + t103;
+
+ t104 = t132 + t133;
+
+ t82 = (t104 << 1) - t58;
+
+ /* 6 */ hi[ 9][slot] = SHIFT(t82);
+
+ t136 = t106 + t107;
+ t137 = t108 + t109;
+
+ t110 = t136 + t137;
+
+ t87 = (t110 << 1) - t67;
+
+ t77 = (t87 << 1) - t68;
+
+ /* 7 */ hi[ 8][slot] = SHIFT(t77);
+
+ t141 = MUL(t69 - t70, costab8);
+ t142 = MUL(t71 - t72, costab24);
+ t143 = t141 + t142;
+
+ /* 8 */ hi[ 7][slot] = SHIFT(t143);
+ /* 24 */ lo[ 8][slot] =
+ SHIFT((MUL(t141 - t142, costab16) << 1) - t143);
+
+ t144 = MUL(t73 - t74, costab8);
+ t145 = MUL(t75 - t76, costab24);
+ t146 = t144 + t145;
+
+ t88 = (t146 << 1) - t77;
+
+ /* 9 */ hi[ 6][slot] = SHIFT(t88);
+
+ t148 = MUL(t78 - t79, costab8);
+ t149 = MUL(t80 - t81, costab24);
+ t150 = t148 + t149;
+
+ t105 = (t150 << 1) - t82;
+
+ /* 10 */ hi[ 5][slot] = SHIFT(t105);
+
+ t152 = MUL(t83 - t84, costab8);
+ t153 = MUL(t85 - t86, costab24);
+ t154 = t152 + t153;
+
+ t111 = (t154 << 1) - t87;
+
+ t99 = (t111 << 1) - t88;
+
+ /* 11 */ hi[ 4][slot] = SHIFT(t99);
+
+ t157 = MUL(t89 - t90, costab8);
+ t158 = MUL(t91 - t92, costab24);
+ t159 = t157 + t158;
+
+ t127 = (t159 << 1) - t93;
+
+ /* 12 */ hi[ 3][slot] = SHIFT(t127);
+
+ t160 = (MUL(t125 - t126, costab16) << 1) - t127;
+
+ /* 20 */ lo[ 4][slot] = SHIFT(t160);
+ /* 28 */ lo[12][slot] =
+ SHIFT((((MUL(t157 - t158, costab16) << 1) - t159) << 1) - t160);
+
+ t161 = MUL(t94 - t95, costab8);
+ t162 = MUL(t96 - t97, costab24);
+ t163 = t161 + t162;
+
+ t130 = (t163 << 1) - t98;
+
+ t112 = (t130 << 1) - t99;
+
+ /* 13 */ hi[ 2][slot] = SHIFT(t112);
+
+ t164 = (MUL(t128 - t129, costab16) << 1) - t130;
+
+ t166 = MUL(t100 - t101, costab8);
+ t167 = MUL(t102 - t103, costab24);
+ t168 = t166 + t167;
+
+ t134 = (t168 << 1) - t104;
+
+ t120 = (t134 << 1) - t105;
+
+ /* 14 */ hi[ 1][slot] = SHIFT(t120);
+
+ t135 = (MUL(t118 - t119, costab16) << 1) - t120;
+
+ /* 18 */ lo[ 2][slot] = SHIFT(t135);
+
+ t169 = (MUL(t132 - t133, costab16) << 1) - t134;
+
+ t151 = (t169 << 1) - t135;
+
+ /* 22 */ lo[ 6][slot] = SHIFT(t151);
+
+ t170 = (((MUL(t148 - t149, costab16) << 1) - t150) << 1) - t151;
+
+ /* 26 */ lo[10][slot] = SHIFT(t170);
+ /* 30 */ lo[14][slot] =
+ SHIFT((((((MUL(t166 - t167, costab16) << 1) -
+ t168) << 1) - t169) << 1) - t170);
+
+ t171 = MUL(t106 - t107, costab8);
+ t172 = MUL(t108 - t109, costab24);
+ t173 = t171 + t172;
+
+ t138 = (t173 << 1) - t110;
+
+ t123 = (t138 << 1) - t111;
+
+ t139 = (MUL(t121 - t122, costab16) << 1) - t123;
+
+ t117 = (t123 << 1) - t112;
+
+ /* 15 */ hi[ 0][slot] = SHIFT(t117);
+
+ t124 = (MUL(t115 - t116, costab16) << 1) - t117;
+
+ /* 17 */ lo[ 1][slot] = SHIFT(t124);
+
+ t131 = (t139 << 1) - t124;
+
+ /* 19 */ lo[ 3][slot] = SHIFT(t131);
+
+ t140 = (t164 << 1) - t131;
+
+ /* 21 */ lo[ 5][slot] = SHIFT(t140);
+
+ t174 = (MUL(t136 - t137, costab16) << 1) - t138;
+
+ t155 = (t174 << 1) - t139;
+
+ t147 = (t155 << 1) - t140;
+
+ /* 23 */ lo[ 7][slot] = SHIFT(t147);
+
+ t156 = (((MUL(t144 - t145, costab16) << 1) - t146) << 1) - t147;
+
+ /* 25 */ lo[ 9][slot] = SHIFT(t156);
+
+ t175 = (((MUL(t152 - t153, costab16) << 1) - t154) << 1) - t155;
+
+ t165 = (t175 << 1) - t156;
+
+ /* 27 */ lo[11][slot] = SHIFT(t165);
+
+ t176 = (((((MUL(t161 - t162, costab16) << 1) -
+ t163) << 1) - t164) << 1) - t165;
+
+ /* 29 */ lo[13][slot] = SHIFT(t176);
+ /* 31 */ lo[15][slot] =
+ SHIFT((((((((MUL(t171 - t172, costab16) << 1) -
+ t173) << 1) - t174) << 1) - t175) << 1) - t176);
+
+ /*
+ * Totals:
+ * 80 multiplies
+ * 80 additions
+ * 119 subtractions
+ * 49 shifts (not counting SSO)
+ */
+}
+
+# undef MUL
+# undef SHIFT
+
+/* third SSO shift and/or D[] optimization preshift */
+
+# if defined(OPT_SSO)
+# if MAD_F_FRACBITS != 28
+# error "MAD_F_FRACBITS must be 28 to use OPT_SSO"
+# endif
+# define ML0(hi, lo, x, y) ((lo) = (x) * (y))
+# define MLA(hi, lo, x, y) ((lo) += (x) * (y))
+# define MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo))
+# define SHIFT(x) ((x) >> 2)
+# define PRESHIFT(x) ((MAD_F(x) + (1L << 13)) >> 14)
+# else
+# define ML0(hi, lo, x, y) MAD_F_ML0((hi), (lo), (x), (y))
+# define MLA(hi, lo, x, y) MAD_F_MLA((hi), (lo), (x), (y))
+# define MLZ(hi, lo) MAD_F_MLZ((hi), (lo))
+# define SHIFT(x) (x)
+# if defined(MAD_F_SCALEBITS)
+# undef MAD_F_SCALEBITS
+# define MAD_F_SCALEBITS (MAD_F_FRACBITS - 12)
+# define PRESHIFT(x) (MAD_F(x) >> 12)
+# else
+# define PRESHIFT(x) MAD_F(x)
+# endif
+# endif
+
+static
+mad_fixed_t const D[17][32] = {
+# include "D.dat"
+};
+
+# if defined(ASO_SYNTH)
+void synth_full(struct mad_synth *, struct mad_frame const *,
+ unsigned int, unsigned int);
+# else
+/*
+ * NAME: synth->full()
+ * DESCRIPTION: perform full frequency PCM synthesis
+ */
+static
+void synth_full(struct mad_synth *synth, struct mad_frame const *frame,
+ unsigned int nch, unsigned int ns)
+{
+ unsigned int phase, ch, s, sb, pe, po;
+ mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8];
+ mad_fixed_t const (*sbsample)[36][32];
+ register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
+ register mad_fixed_t const (*Dptr)[32], *ptr;
+ register mad_fixed64hi_t hi;
+ register mad_fixed64lo_t lo;
+
+ for (ch = 0; ch < nch; ++ch) {
+ sbsample = &frame->sbsample[ch];
+ filter = &synth->filter[ch];
+ phase = synth->phase;
+ pcm1 = synth->pcm.samples[ch];
+
+ for (s = 0; s < ns; ++s) {
+ dct32((*sbsample)[s], phase >> 1,
+ (*filter)[0][phase & 1], (*filter)[1][phase & 1]);
+
+ pe = phase & ~1;
+ po = ((phase - 1) & 0xf) | 1;
+
+ /* calculate 32 samples */
+
+ fe = &(*filter)[0][ phase & 1][0];
+ fx = &(*filter)[0][~phase & 1][0];
+ fo = &(*filter)[1][~phase & 1][0];
+
+ Dptr = &D[0];
+
+ ptr = *Dptr + pe;
+ ML0(hi, lo, (*fe)[0], ptr[ 0]);
+ MLA(hi, lo, (*fe)[1], ptr[14]);
+ MLA(hi, lo, (*fe)[2], ptr[12]);
+ MLA(hi, lo, (*fe)[3], ptr[10]);
+ MLA(hi, lo, (*fe)[4], ptr[ 8]);
+ MLA(hi, lo, (*fe)[5], ptr[ 6]);
+ MLA(hi, lo, (*fe)[6], ptr[ 4]);
+ MLA(hi, lo, (*fe)[7], ptr[ 2]);
+
+ ptr = *Dptr + po;
+ MLA(hi, lo, (*fx)[0], -ptr[ 0]);
+ MLA(hi, lo, (*fx)[1], -ptr[14]);
+ MLA(hi, lo, (*fx)[2], -ptr[12]);
+ MLA(hi, lo, (*fx)[3], -ptr[10]);
+ MLA(hi, lo, (*fx)[4], -ptr[ 8]);
+ MLA(hi, lo, (*fx)[5], -ptr[ 6]);
+ MLA(hi, lo, (*fx)[6], -ptr[ 4]);
+ MLA(hi, lo, (*fx)[7], -ptr[ 2]);
+
+ *pcm1++ = SHIFT(MLZ(hi, lo));
+
+ pcm2 = pcm1 + 30;
+
+ for (sb = 1; sb < 16; ++sb) {
+ ++fe;
+ ++Dptr;
+
+ /* D[32 - sb][i] == -D[sb][31 - i] */
+
+ ptr = *Dptr + pe;
+ ML0(hi, lo, (*fe)[7], ptr[ 2]);
+ MLA(hi, lo, (*fe)[6], ptr[ 4]);
+ MLA(hi, lo, (*fe)[5], ptr[ 6]);
+ MLA(hi, lo, (*fe)[4], ptr[ 8]);
+ MLA(hi, lo, (*fe)[3], ptr[10]);
+ MLA(hi, lo, (*fe)[2], ptr[12]);
+ MLA(hi, lo, (*fe)[1], ptr[14]);
+ MLA(hi, lo, (*fe)[0], ptr[ 0]);
+
+ ptr = *Dptr + po;
+ MLA(hi, lo, (*fo)[0], -ptr[ 0]);
+ MLA(hi, lo, (*fo)[1], -ptr[14]);
+ MLA(hi, lo, (*fo)[2], -ptr[12]);
+ MLA(hi, lo, (*fo)[3], -ptr[10]);
+ MLA(hi, lo, (*fo)[4], -ptr[ 8]);
+ MLA(hi, lo, (*fo)[5], -ptr[ 6]);
+ MLA(hi, lo, (*fo)[6], -ptr[ 4]);
+ MLA(hi, lo, (*fo)[7], -ptr[ 2]);
+
+ *pcm1++ = SHIFT(MLZ(hi, lo));
+
+ ptr = *Dptr - po;
+ ML0(hi, lo, (*fo)[7], ptr[31 - 2]);
+ MLA(hi, lo, (*fo)[6], ptr[31 - 4]);
+ MLA(hi, lo, (*fo)[5], ptr[31 - 6]);
+ MLA(hi, lo, (*fo)[4], ptr[31 - 8]);
+ MLA(hi, lo, (*fo)[3], ptr[31 - 10]);
+ MLA(hi, lo, (*fo)[2], ptr[31 - 12]);
+ MLA(hi, lo, (*fo)[1], ptr[31 - 14]);
+ MLA(hi, lo, (*fo)[0], ptr[31 - 16]);
+
+ ptr = *Dptr - pe;
+ MLA(hi, lo, (*fe)[0], ptr[31 - 16]);
+ MLA(hi, lo, (*fe)[1], ptr[31 - 14]);
+ MLA(hi, lo, (*fe)[2], ptr[31 - 12]);
+ MLA(hi, lo, (*fe)[3], ptr[31 - 10]);
+ MLA(hi, lo, (*fe)[4], ptr[31 - 8]);
+ MLA(hi, lo, (*fe)[5], ptr[31 - 6]);
+ MLA(hi, lo, (*fe)[6], ptr[31 - 4]);
+ MLA(hi, lo, (*fe)[7], ptr[31 - 2]);
+
+ *pcm2-- = SHIFT(MLZ(hi, lo));
+
+ ++fo;
+ }
+
+ ++Dptr;
+
+ ptr = *Dptr + po;
+ ML0(hi, lo, (*fo)[0], ptr[ 0]);
+ MLA(hi, lo, (*fo)[1], ptr[14]);
+ MLA(hi, lo, (*fo)[2], ptr[12]);
+ MLA(hi, lo, (*fo)[3], ptr[10]);
+ MLA(hi, lo, (*fo)[4], ptr[ 8]);
+ MLA(hi, lo, (*fo)[5], ptr[ 6]);
+ MLA(hi, lo, (*fo)[6], ptr[ 4]);
+ MLA(hi, lo, (*fo)[7], ptr[ 2]);
+
+ *pcm1 = SHIFT(-MLZ(hi, lo));
+ pcm1 += 16;
+
+ phase = (phase + 1) % 16;
+ }
+ }
+}
+# endif
+
+/*
+ * NAME: synth->half()
+ * DESCRIPTION: perform half frequency PCM synthesis
+ */
+static
+void synth_half(struct mad_synth *synth, struct mad_frame const *frame,
+ unsigned int nch, unsigned int ns)
+{
+ unsigned int phase, ch, s, sb, pe, po;
+ mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8];
+ mad_fixed_t const (*sbsample)[36][32];
+ register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8];
+ register mad_fixed_t const (*Dptr)[32], *ptr;
+ register mad_fixed64hi_t hi;
+ register mad_fixed64lo_t lo;
+
+ for (ch = 0; ch < nch; ++ch) {
+ sbsample = &frame->sbsample[ch];
+ filter = &synth->filter[ch];
+ phase = synth->phase;
+ pcm1 = synth->pcm.samples[ch];
+
+ for (s = 0; s < ns; ++s) {
+ dct32((*sbsample)[s], phase >> 1,
+ (*filter)[0][phase & 1], (*filter)[1][phase & 1]);
+
+ pe = phase & ~1;
+ po = ((phase - 1) & 0xf) | 1;
+
+ /* calculate 16 samples */
+
+ fe = &(*filter)[0][ phase & 1][0];
+ fx = &(*filter)[0][~phase & 1][0];
+ fo = &(*filter)[1][~phase & 1][0];
+
+ Dptr = &D[0];
+
+ ptr = *Dptr + pe;
+ ML0(hi, lo, (*fe)[0], ptr[ 0]);
+ MLA(hi, lo, (*fe)[1], ptr[14]);
+ MLA(hi, lo, (*fe)[2], ptr[12]);
+ MLA(hi, lo, (*fe)[3], ptr[10]);
+ MLA(hi, lo, (*fe)[4], ptr[ 8]);
+ MLA(hi, lo, (*fe)[5], ptr[ 6]);
+ MLA(hi, lo, (*fe)[6], ptr[ 4]);
+ MLA(hi, lo, (*fe)[7], ptr[ 2]);
+
+ ptr = *Dptr + po;
+ MLA(hi, lo, (*fx)[0], -ptr[ 0]);
+ MLA(hi, lo, (*fx)[1], -ptr[14]);
+ MLA(hi, lo, (*fx)[2], -ptr[12]);
+ MLA(hi, lo, (*fx)[3], -ptr[10]);
+ MLA(hi, lo, (*fx)[4], -ptr[ 8]);
+ MLA(hi, lo, (*fx)[5], -ptr[ 6]);
+ MLA(hi, lo, (*fx)[6], -ptr[ 4]);
+ MLA(hi, lo, (*fx)[7], -ptr[ 2]);
+
+ *pcm1++ = SHIFT(MLZ(hi, lo));
+
+ pcm2 = pcm1 + 14;
+
+ for (sb = 1; sb < 16; ++sb) {
+ ++fe;
+ ++Dptr;
+
+ /* D[32 - sb][i] == -D[sb][31 - i] */
+
+ if (!(sb & 1)) {
+ ptr = *Dptr + pe;
+ ML0(hi, lo, (*fe)[7], ptr[ 2]);
+ MLA(hi, lo, (*fe)[6], ptr[ 4]);
+ MLA(hi, lo, (*fe)[5], ptr[ 6]);
+ MLA(hi, lo, (*fe)[4], ptr[ 8]);
+ MLA(hi, lo, (*fe)[3], ptr[10]);
+ MLA(hi, lo, (*fe)[2], ptr[12]);
+ MLA(hi, lo, (*fe)[1], ptr[14]);
+ MLA(hi, lo, (*fe)[0], ptr[ 0]);
+
+ ptr = *Dptr + po;
+ MLA(hi, lo, (*fo)[0], -ptr[ 0]);
+ MLA(hi, lo, (*fo)[1], -ptr[14]);
+ MLA(hi, lo, (*fo)[2], -ptr[12]);
+ MLA(hi, lo, (*fo)[3], -ptr[10]);
+ MLA(hi, lo, (*fo)[4], -ptr[ 8]);
+ MLA(hi, lo, (*fo)[5], -ptr[ 6]);
+ MLA(hi, lo, (*fo)[6], -ptr[ 4]);
+ MLA(hi, lo, (*fo)[7], -ptr[ 2]);
+
+ *pcm1++ = SHIFT(MLZ(hi, lo));
+
+ ptr = *Dptr - po;
+ ML0(hi, lo, (*fo)[7], ptr[31 - 2]);
+ MLA(hi, lo, (*fo)[6], ptr[31 - 4]);
+ MLA(hi, lo, (*fo)[5], ptr[31 - 6]);
+ MLA(hi, lo, (*fo)[4], ptr[31 - 8]);
+ MLA(hi, lo, (*fo)[3], ptr[31 - 10]);
+ MLA(hi, lo, (*fo)[2], ptr[31 - 12]);
+ MLA(hi, lo, (*fo)[1], ptr[31 - 14]);
+ MLA(hi, lo, (*fo)[0], ptr[31 - 16]);
+
+ ptr = *Dptr - pe;
+ MLA(hi, lo, (*fe)[0], ptr[31 - 16]);
+ MLA(hi, lo, (*fe)[1], ptr[31 - 14]);
+ MLA(hi, lo, (*fe)[2], ptr[31 - 12]);
+ MLA(hi, lo, (*fe)[3], ptr[31 - 10]);
+ MLA(hi, lo, (*fe)[4], ptr[31 - 8]);
+ MLA(hi, lo, (*fe)[5], ptr[31 - 6]);
+ MLA(hi, lo, (*fe)[6], ptr[31 - 4]);
+ MLA(hi, lo, (*fe)[7], ptr[31 - 2]);
+
+ *pcm2-- = SHIFT(MLZ(hi, lo));
+ }
+
+ ++fo;
+ }
+
+ ++Dptr;
+
+ ptr = *Dptr + po;
+ ML0(hi, lo, (*fo)[0], ptr[ 0]);
+ MLA(hi, lo, (*fo)[1], ptr[14]);
+ MLA(hi, lo, (*fo)[2], ptr[12]);
+ MLA(hi, lo, (*fo)[3], ptr[10]);
+ MLA(hi, lo, (*fo)[4], ptr[ 8]);
+ MLA(hi, lo, (*fo)[5], ptr[ 6]);
+ MLA(hi, lo, (*fo)[6], ptr[ 4]);
+ MLA(hi, lo, (*fo)[7], ptr[ 2]);
+
+ *pcm1 = SHIFT(-MLZ(hi, lo));
+ pcm1 += 8;
+
+ phase = (phase + 1) % 16;
+ }
+ }
+}
+
+/*
+ * NAME: synth->frame()
+ * DESCRIPTION: perform PCM synthesis of frame subband samples
+ */
+void mad_synth_frame(struct mad_synth *synth, struct mad_frame const *frame)
+{
+ unsigned int nch, ns;
+ void (*synth_frame)(struct mad_synth *, struct mad_frame const *,
+ unsigned int, unsigned int);
+
+ nch = MAD_NCHANNELS(&frame->header);
+ ns = MAD_NSBSAMPLES(&frame->header);
+
+ synth->pcm.samplerate = frame->header.samplerate;
+ synth->pcm.channels = nch;
+ synth->pcm.length = 32 * ns;
+
+ synth_frame = synth_full;
+
+ if (frame->options & MAD_OPTION_HALFSAMPLERATE) {
+ synth->pcm.samplerate /= 2;
+ synth->pcm.length /= 2;
+
+ synth_frame = synth_half;
+ }
+
+ synth_frame(synth, frame, nch, ns);
+
+ synth->phase = (synth->phase + ns) % 16;
+}
diff --git a/core/multimedia/opieplayer/libmad/synth.h b/core/multimedia/opieplayer/libmad/synth.h
new file mode 100644
index 0000000..64f6a86
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/synth.h
@@ -0,0 +1,50 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifndef LIBMAD_SYNTH_H
+# define LIBMAD_SYNTH_H
+
+# include "fixed.h"
+# include "frame.h"
+
+struct mad_synth {
+ mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */
+ /* [ch][eo][peo][s][v] */
+
+ unsigned int phase; /* current processing phase */
+
+ struct mad_pcm {
+ unsigned int samplerate; /* sampling frequency (Hz) */
+ unsigned short channels; /* number of channels */
+ unsigned short length; /* number of samples per channel */
+ mad_fixed_t samples[2][1152]; /* PCM output samples */
+ } pcm;
+};
+
+void mad_synth_init(struct mad_synth *);
+
+# define mad_synth_finish(synth) /* nothing */
+
+void mad_synth_mute(struct mad_synth *);
+
+void mad_synth_frame(struct mad_synth *, struct mad_frame const *);
+
+# endif
diff --git a/core/multimedia/opieplayer/libmad/timer.c b/core/multimedia/opieplayer/libmad/timer.c
new file mode 100644
index 0000000..b30680c
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/timer.c
@@ -0,0 +1,480 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifdef HAVE_CONFIG_H
+# include "libmad_config.h"
+# endif
+
+# include "libmad_global.h"
+
+# include <stdio.h>
+# include <assert.h>
+
+# include "timer.h"
+
+mad_timer_t const mad_timer_zero = { 0, 0 };
+
+/*
+ * NAME: timer->compare()
+ * DESCRIPTION: indicate relative order of two timers
+ */
+int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2)
+{
+ signed long diff;
+
+ diff = timer1.seconds - timer2.seconds;
+ if (diff < 0)
+ return -1;
+ else if (diff > 0)
+ return +1;
+
+ diff = timer1.fraction - timer2.fraction;
+ if (diff < 0)
+ return -1;
+ else if (diff > 0)
+ return +1;
+
+ return 0;
+}
+
+/*
+ * NAME: timer->negate()
+ * DESCRIPTION: invert the sign of a timer
+ */
+void mad_timer_negate(mad_timer_t *timer)
+{
+ timer->seconds = -timer->seconds;
+
+ if (timer->fraction) {
+ timer->seconds -= 1;
+ timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction;
+ }
+}
+
+/*
+ * NAME: timer->abs()
+ * DESCRIPTION: return the absolute value of a timer
+ */
+mad_timer_t mad_timer_abs(mad_timer_t timer)
+{
+ if (mad_timer_sign(timer) < 0)
+ mad_timer_negate(&timer);
+
+ return timer;
+}
+
+/*
+ * NAME: reduce_timer()
+ * DESCRIPTION: carry timer fraction into seconds
+ */
+static
+void reduce_timer(mad_timer_t *timer)
+{
+ timer->seconds += timer->fraction / MAD_TIMER_RESOLUTION;
+ timer->fraction %= MAD_TIMER_RESOLUTION;
+}
+
+/*
+ * NAME: gcd()
+ * DESCRIPTION: compute greatest common denominator
+ */
+static
+unsigned long gcd(unsigned long num1, unsigned long num2)
+{
+ unsigned long tmp;
+
+ while (num2) {
+ tmp = num2;
+ num2 = num1 % num2;
+ num1 = tmp;
+ }
+
+ return num1;
+}
+
+/*
+ * NAME: reduce_rational()
+ * DESCRIPTION: convert rational expression to lowest terms
+ */
+static
+void reduce_rational(unsigned long *numer, unsigned long *denom)
+{
+ unsigned long factor;
+
+ factor = gcd(*numer, *denom);
+
+ assert(factor != 0);
+
+ *numer /= factor;
+ *denom /= factor;
+}
+
+/*
+ * NAME: scale_rational()
+ * DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing
+ */
+static
+unsigned long scale_rational(unsigned long numer, unsigned long denom,
+ unsigned long scale)
+{
+ reduce_rational(&numer, &denom);
+ reduce_rational(&scale, &denom);
+
+ assert(denom != 0);
+
+ if (denom < scale)
+ return numer * (scale / denom) + numer * (scale % denom) / denom;
+ if (denom < numer)
+ return scale * (numer / denom) + scale * (numer % denom) / denom;
+
+ return numer * scale / denom;
+}
+
+/*
+ * NAME: timer->set()
+ * DESCRIPTION: set timer to specific value
+ */
+void mad_timer_set(mad_timer_t *timer, unsigned long seconds,
+ unsigned long fraction, unsigned long fracparts)
+{
+ timer->seconds = seconds;
+
+ if (fraction == 0)
+ fracparts = 0;
+ else if (fracparts == 0) {
+ fracparts = fraction;
+ fraction = 1;
+ }
+
+ switch (fracparts) {
+ case 0:
+ timer->fraction = 0;
+ break;
+
+ case MAD_TIMER_RESOLUTION:
+ timer->fraction = fraction;
+ break;
+
+ case 8000:
+ timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 8000);
+ break;
+
+ case 11025:
+ timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 11025);
+ break;
+
+ case 12000:
+ timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 12000);
+ break;
+
+ case 16000:
+ timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 16000);
+ break;
+
+ case 22050:
+ timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 22050);
+ break;
+
+ case 24000:
+ timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 24000);
+ break;
+
+ case 32000:
+ timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 32000);
+ break;
+
+ case 44100:
+ timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 44100);
+ break;
+
+ case 48000:
+ timer->fraction = fraction * (MAD_TIMER_RESOLUTION / 48000);
+ break;
+
+ default:
+ timer->fraction =
+ scale_rational(fraction, fracparts, MAD_TIMER_RESOLUTION);
+ break;
+ }
+
+ if (timer->fraction >= MAD_TIMER_RESOLUTION)
+ reduce_timer(timer);
+}
+
+/*
+ * NAME: timer->add()
+ * DESCRIPTION: add one timer to another
+ */
+void mad_timer_add(mad_timer_t *timer, mad_timer_t incr)
+{
+ timer->seconds += incr.seconds;
+ timer->fraction += incr.fraction;
+
+ if (timer->fraction >= MAD_TIMER_RESOLUTION)
+ reduce_timer(timer);
+}
+
+/*
+ * NAME: timer->multiply()
+ * DESCRIPTION: multiply a timer by a scalar value
+ */
+void mad_timer_multiply(mad_timer_t *timer, signed long scalar)
+{
+ mad_timer_t addend;
+ unsigned long factor;
+
+ factor = scalar;
+ if (scalar < 0) {
+ mad_timer_negate(timer);
+ factor = -scalar;
+ }
+
+ addend = *timer;
+ *timer = mad_timer_zero;
+
+ while (factor) {
+ if (factor & 1)
+ mad_timer_add(timer, addend);
+
+ mad_timer_add(&addend, addend);
+ factor >>= 1;
+ }
+}
+
+/*
+ * NAME: timer->count()
+ * DESCRIPTION: return timer value in selected units
+ */
+signed long mad_timer_count(mad_timer_t timer, enum mad_units units)
+{
+ switch (units) {
+ case MAD_UNITS_HOURS:
+ return timer.seconds / 60 / 60;
+
+ case MAD_UNITS_MINUTES:
+ return timer.seconds / 60;
+
+ case MAD_UNITS_SECONDS:
+ return timer.seconds;
+
+ case MAD_UNITS_DECISECONDS:
+ case MAD_UNITS_CENTISECONDS:
+ case MAD_UNITS_MILLISECONDS:
+
+ case MAD_UNITS_8000_HZ:
+ case MAD_UNITS_11025_HZ:
+ case MAD_UNITS_12000_HZ:
+ case MAD_UNITS_16000_HZ:
+ case MAD_UNITS_22050_HZ:
+ case MAD_UNITS_24000_HZ:
+ case MAD_UNITS_32000_HZ:
+ case MAD_UNITS_44100_HZ:
+ case MAD_UNITS_48000_HZ:
+
+ case MAD_UNITS_24_FPS:
+ case MAD_UNITS_25_FPS:
+ case MAD_UNITS_30_FPS:
+ case MAD_UNITS_48_FPS:
+ case MAD_UNITS_50_FPS:
+ case MAD_UNITS_60_FPS:
+ case MAD_UNITS_75_FPS:
+ return timer.seconds * (signed long) units +
+ (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION,
+ units);
+
+ case MAD_UNITS_23_976_FPS:
+ case MAD_UNITS_24_975_FPS:
+ case MAD_UNITS_29_97_FPS:
+ case MAD_UNITS_47_952_FPS:
+ case MAD_UNITS_49_95_FPS:
+ case MAD_UNITS_59_94_FPS:
+ return (mad_timer_count(timer, -units) + 1) * 1000 / 1001;
+ }
+
+ /* unsupported units */
+ return 0;
+}
+
+/*
+ * NAME: timer->fraction()
+ * DESCRIPTION: return fractional part of timer in arbitrary terms
+ */
+unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long fracparts)
+{
+ timer = mad_timer_abs(timer);
+
+ switch (fracparts) {
+ case 0:
+ return MAD_TIMER_RESOLUTION / timer.fraction;
+
+ case MAD_TIMER_RESOLUTION:
+ return timer.fraction;
+
+ default:
+ return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, fracparts);
+ }
+}
+
+/*
+ * NAME: timer->string()
+ * DESCRIPTION: write a string representation of a timer using a template
+ */
+void mad_timer_string(mad_timer_t timer,
+ char *dest, char const *format, enum mad_units units,
+ enum mad_units fracunits, unsigned long subparts)
+{
+ unsigned long hours, minutes, seconds, sub;
+ unsigned int frac;
+
+ timer = mad_timer_abs(timer);
+
+ seconds = timer.seconds;
+ frac = sub = 0;
+
+ switch (fracunits) {
+ case MAD_UNITS_HOURS:
+ case MAD_UNITS_MINUTES:
+ case MAD_UNITS_SECONDS:
+ break;
+
+ case MAD_UNITS_DECISECONDS:
+ case MAD_UNITS_CENTISECONDS:
+ case MAD_UNITS_MILLISECONDS:
+
+ case MAD_UNITS_8000_HZ:
+ case MAD_UNITS_11025_HZ:
+ case MAD_UNITS_12000_HZ:
+ case MAD_UNITS_16000_HZ:
+ case MAD_UNITS_22050_HZ:
+ case MAD_UNITS_24000_HZ:
+ case MAD_UNITS_32000_HZ:
+ case MAD_UNITS_44100_HZ:
+ case MAD_UNITS_48000_HZ:
+
+ case MAD_UNITS_24_FPS:
+ case MAD_UNITS_25_FPS:
+ case MAD_UNITS_30_FPS:
+ case MAD_UNITS_48_FPS:
+ case MAD_UNITS_50_FPS:
+ case MAD_UNITS_60_FPS:
+ case MAD_UNITS_75_FPS:
+ {
+ unsigned long fracparts;
+
+ fracparts = MAD_TIMER_RESOLUTION / fracunits;
+
+ frac = timer.fraction / fracparts;
+ sub = scale_rational(timer.fraction % fracparts, fracparts, subparts);
+ }
+ break;
+
+ case MAD_UNITS_23_976_FPS:
+ case MAD_UNITS_24_975_FPS:
+ case MAD_UNITS_29_97_FPS:
+ case MAD_UNITS_47_952_FPS:
+ case MAD_UNITS_49_95_FPS:
+ case MAD_UNITS_59_94_FPS:
+ /* drop-frame encoding */
+ /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */
+ {
+ unsigned long frame, cycle, d, m;
+
+ frame = mad_timer_count(timer, fracunits);
+
+ cycle = -fracunits * 60 * 10 - (10 - 1) * 2;
+
+ d = frame / cycle;
+ m = frame % cycle;
+ frame += (10 - 1) * 2 * d;
+ if (m > 2)
+ frame += 2 * ((m - 2) / (cycle / 10));
+
+ frac = frame % -fracunits;
+ seconds = frame / -fracunits;
+ }
+ break;
+ }
+
+ switch (units) {
+ case MAD_UNITS_HOURS:
+ minutes = seconds / 60;
+ hours = minutes / 60;
+
+ sprintf(dest, format,
+ hours,
+ (unsigned int) (minutes % 60),
+ (unsigned int) (seconds % 60),
+ frac, sub);
+ break;
+
+ case MAD_UNITS_MINUTES:
+ minutes = seconds / 60;
+
+ sprintf(dest, format,
+ minutes,
+ (unsigned int) (seconds % 60),
+ frac, sub);
+ break;
+
+ case MAD_UNITS_SECONDS:
+ sprintf(dest, format,
+ seconds,
+ frac, sub);
+ break;
+
+ case MAD_UNITS_23_976_FPS:
+ case MAD_UNITS_24_975_FPS:
+ case MAD_UNITS_29_97_FPS:
+ case MAD_UNITS_47_952_FPS:
+ case MAD_UNITS_49_95_FPS:
+ case MAD_UNITS_59_94_FPS:
+ if (fracunits < 0) {
+ /* not yet implemented */
+ sub = 0;
+ }
+
+ /* fall through */
+
+ case MAD_UNITS_DECISECONDS:
+ case MAD_UNITS_CENTISECONDS:
+ case MAD_UNITS_MILLISECONDS:
+
+ case MAD_UNITS_8000_HZ:
+ case MAD_UNITS_11025_HZ:
+ case MAD_UNITS_12000_HZ:
+ case MAD_UNITS_16000_HZ:
+ case MAD_UNITS_22050_HZ:
+ case MAD_UNITS_24000_HZ:
+ case MAD_UNITS_32000_HZ:
+ case MAD_UNITS_44100_HZ:
+ case MAD_UNITS_48000_HZ:
+
+ case MAD_UNITS_24_FPS:
+ case MAD_UNITS_25_FPS:
+ case MAD_UNITS_30_FPS:
+ case MAD_UNITS_48_FPS:
+ case MAD_UNITS_50_FPS:
+ case MAD_UNITS_60_FPS:
+ case MAD_UNITS_75_FPS:
+ sprintf(dest, format, mad_timer_count(timer, units), sub);
+ break;
+ }
+}
diff --git a/core/multimedia/opieplayer/libmad/timer.h b/core/multimedia/opieplayer/libmad/timer.h
new file mode 100644
index 0000000..67fe16a
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/timer.h
@@ -0,0 +1,100 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifndef LIBMAD_TIMER_H
+# define LIBMAD_TIMER_H
+
+typedef struct {
+ signed long seconds; /* whole seconds */
+ unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */
+} mad_timer_t;
+
+extern mad_timer_t const mad_timer_zero;
+
+# define MAD_TIMER_RESOLUTION 352800000UL
+
+enum mad_units {
+ MAD_UNITS_HOURS = -2,
+ MAD_UNITS_MINUTES = -1,
+ MAD_UNITS_SECONDS = 0,
+
+ /* metric units */
+
+ MAD_UNITS_DECISECONDS = 10,
+ MAD_UNITS_CENTISECONDS = 100,
+ MAD_UNITS_MILLISECONDS = 1000,
+
+ /* audio sample units */
+
+ MAD_UNITS_8000_HZ = 8000,
+ MAD_UNITS_11025_HZ = 11025,
+ MAD_UNITS_12000_HZ = 12000,
+
+ MAD_UNITS_16000_HZ = 16000,
+ MAD_UNITS_22050_HZ = 22050,
+ MAD_UNITS_24000_HZ = 24000,
+
+ MAD_UNITS_32000_HZ = 32000,
+ MAD_UNITS_44100_HZ = 44100,
+ MAD_UNITS_48000_HZ = 48000,
+
+ /* video frame/field units */
+
+ MAD_UNITS_24_FPS = 24,
+ MAD_UNITS_25_FPS = 25,
+ MAD_UNITS_30_FPS = 30,
+ MAD_UNITS_48_FPS = 48,
+ MAD_UNITS_50_FPS = 50,
+ MAD_UNITS_60_FPS = 60,
+
+ /* CD audio frames */
+
+ MAD_UNITS_75_FPS = 75,
+
+ /* video drop-frame units */
+
+ MAD_UNITS_23_976_FPS = -24,
+ MAD_UNITS_24_975_FPS = -25,
+ MAD_UNITS_29_97_FPS = -30,
+ MAD_UNITS_47_952_FPS = -48,
+ MAD_UNITS_49_95_FPS = -50,
+ MAD_UNITS_59_94_FPS = -60
+};
+
+# define mad_timer_reset(timer) (*(timer) = mad_timer_zero)
+
+int mad_timer_compare(mad_timer_t, mad_timer_t);
+
+# define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero)
+
+void mad_timer_negate(mad_timer_t *);
+mad_timer_t mad_timer_abs(mad_timer_t);
+
+void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long);
+void mad_timer_add(mad_timer_t *, mad_timer_t);
+void mad_timer_multiply(mad_timer_t *, signed long);
+
+signed long mad_timer_count(mad_timer_t, enum mad_units);
+unsigned long mad_timer_fraction(mad_timer_t, unsigned long);
+void mad_timer_string(mad_timer_t, char *, char const *,
+ enum mad_units, enum mad_units, unsigned long);
+
+# endif
diff --git a/core/multimedia/opieplayer/libmad/version.c b/core/multimedia/opieplayer/libmad/version.c
new file mode 100644
index 0000000..413d54b
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmad/version.c
@@ -0,0 +1,91 @@
+/*
+ * mad - MPEG audio decoder
+ * Copyright (C) 2000-2001 Robert Leslie
+ *
+ * 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
+ *
+ * $Id$
+ */
+
+# ifdef HAVE_CONFIG_H
+# include "libmad_config.h"
+# endif
+
+# include "libmad_global.h"
+
+# include "libmad_version.h"
+
+char const mad_version[] = "MPEG Audio Decoder version " MAD_VERSION;
+char const mad_copyright[] = "Copyright (C) " MAD_PUBLISHYEAR " " MAD_AUTHOR;
+char const mad_author[] = MAD_AUTHOR " <" MAD_EMAIL ">";
+
+char const mad_build[] =
+# if defined(FPM_64BIT)
+ "FPM_64BIT "
+# elif defined(FPM_INTEL)
+ "FPM_INTEL "
+# elif defined(FPM_ARM)
+ "FPM_ARM "
+# elif defined(FPM_MIPS)
+ "FPM_MIPS "
+# elif defined(FPM_SPARC)
+ "FPM_SPARC "
+# elif defined(FPM_PPC)
+ "FPM_PPC "
+# elif defined(FPM_DEFAULT)
+ "FPM_DEFAULT "
+# endif
+
+# if defined(ASO_IMDCT)
+ "ASO_IMDCT "
+# endif
+# if defined(ASO_INTERLEAVE1)
+ "ASO_INTERLEAVE1 "
+# endif
+# if defined(ASO_INTERLEAVE2)
+ "ASO_INTERLEAVE2 "
+# endif
+# if defined(ASO_ZEROCHECK)
+ "ASO_ZEROCHECK "
+# endif
+
+# if defined(OPT_SPEED)
+ "OPT_SPEED "
+# elif defined(OPT_ACCURACY)
+ "OPT_ACCURACY "
+# endif
+
+# if defined(OPT_SSO)
+ "OPT_SSO "
+# endif
+
+# if defined(OPT_DCTO) /* never defined here */
+ "OPT_DCTO "
+# endif
+
+# if defined(OPT_STRICT)
+ "OPT_STRICT "
+# endif
+
+# if defined(EXPERIMENTAL)
+ "EXPERIMENTAL "
+# endif
+
+# if defined(DEBUG)
+ "DEBUG "
+# elif defined(NDEBUG)
+ "NDEBUG "
+# endif
+;
diff --git a/core/multimedia/opieplayer/libmpeg3/.cvsignore b/core/multimedia/opieplayer/libmpeg3/.cvsignore
new file mode 100644
index 0000000..d7bb3c1
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/.cvsignore
@@ -0,0 +1,5 @@
+global_config
+dump
+mpeg3toc
+mpeg3cat
+Makefile
diff --git a/core/multimedia/opieplayer/libmpeg3/COPYING b/core/multimedia/opieplayer/libmpeg3/COPYING
new file mode 100644
index 0000000..60549be
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ 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) 19yy 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.
+
+ <signature of Ty Coon>, 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/core/multimedia/opieplayer/libmpeg3/Makefile.in b/core/multimedia/opieplayer/libmpeg3/Makefile.in
new file mode 100644
index 0000000..1817902
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/Makefile.in
@@ -0,0 +1,774 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB) -DQCONFIG=\"qpe\"
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB) -DQCONFIG=\"qpe\"
+INCPATH = -I$(QPEDIR)/include -I..
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe -lpthread -lm $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../../plugins/codecs/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = mpeg3plugin
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = libmpeg3plugin.h \
+ libmpeg3pluginimpl.h
+SOURCES = libmpeg3plugin.cpp \
+ libmpeg3pluginimpl.cpp \
+ bitstream.c \
+ libmpeg3.c \
+ mpeg3atrack.c \
+ mpeg3css.c \
+ mpeg3demux.c \
+ mpeg3io.c \
+ mpeg3title.c \
+ mpeg3vtrack.c \
+ audio/ac3.c \
+ audio/bit_allocation.c \
+ audio/dct.c \
+ audio/exponents.c \
+ audio/header.c \
+ audio/layer2.c \
+ audio/layer3.c \
+ audio/mantissa.c \
+ audio/mpeg3audio.c \
+ audio/pcm.c \
+ audio/synthesizers.c \
+ audio/tables.c \
+ video/getpicture.c \
+ video/headers.c \
+ video/idct.c \
+ video/macroblocks.c \
+ video/mmxtest.c \
+ video/motion.c \
+ video/mpeg3video.c \
+ video/output.c \
+ video/reconstruct.c \
+ video/seek.c \
+ video/slice.c \
+ video/vlc.c
+OBJECTS = libmpeg3plugin.o \
+ libmpeg3pluginimpl.o \
+ bitstream.o \
+ libmpeg3.o \
+ mpeg3atrack.o \
+ mpeg3css.o \
+ mpeg3demux.o \
+ mpeg3io.o \
+ mpeg3title.o \
+ mpeg3vtrack.o \
+ audio/ac3.o \
+ audio/bit_allocation.o \
+ audio/dct.o \
+ audio/exponents.o \
+ audio/header.o \
+ audio/layer2.o \
+ audio/layer3.o \
+ audio/mantissa.o \
+ audio/mpeg3audio.o \
+ audio/pcm.o \
+ audio/synthesizers.o \
+ audio/tables.o \
+ video/getpicture.o \
+ video/headers.o \
+ video/idct.o \
+ video/macroblocks.o \
+ video/mmxtest.o \
+ video/motion.o \
+ video/mpeg3video.o \
+ video/output.o \
+ video/reconstruct.o \
+ video/seek.o \
+ video/slice.o \
+ video/vlc.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC =
+OBJMOC =
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
+
+$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK_LIB)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake libmpeg3.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+libmpeg3plugin.o: libmpeg3plugin.cpp \
+ libmpeg3plugin.h \
+ libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ mpeg3protos.h \
+ ../mediaplayerplugininterface.h
+
+libmpeg3pluginimpl.o: libmpeg3pluginimpl.cpp \
+ libmpeg3plugin.h \
+ libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ mpeg3protos.h \
+ ../mediaplayerplugininterface.h \
+ libmpeg3pluginimpl.h \
+ ../mediaplayerplugininterface.h
+
+bitstream.o: bitstream.c \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ mpeg3protos.h
+
+libmpeg3.o: libmpeg3.c \
+ libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ mpeg3protos.h
+
+mpeg3atrack.o: mpeg3atrack.c \
+ libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ mpeg3protos.h
+
+mpeg3css.o: mpeg3css.c \
+ mpeg3css.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h
+
+mpeg3demux.o: mpeg3demux.c \
+ libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ mpeg3protos.h
+
+mpeg3io.o: mpeg3io.c \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ mpeg3protos.h
+
+mpeg3title.o: mpeg3title.c \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ mpeg3protos.h
+
+mpeg3vtrack.o: mpeg3vtrack.c \
+ libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ mpeg3protos.h
+
+audio/ac3.o: audio/ac3.c \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ audio/../mpeg3protos.h
+
+audio/bit_allocation.o: audio/bit_allocation.c \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ audio/../mpeg3protos.h
+
+audio/dct.o: audio/dct.c \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ audio/../mpeg3protos.h \
+ audio/tables.h \
+ audio/fptables.h
+
+audio/exponents.o: audio/exponents.c \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ audio/../mpeg3protos.h
+
+audio/header.o: audio/header.c \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/tables.h \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ audio/../mpeg3protos.h
+
+audio/layer2.o: audio/layer2.c \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ audio/../mpeg3protos.h \
+ audio/tables.h
+
+audio/layer3.o: audio/layer3.c \
+ audio/huffman.h \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ audio/../mpeg3protos.h \
+ audio/tables.h
+
+audio/mantissa.o: audio/mantissa.c \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ audio/../mpeg3protos.h
+
+audio/mpeg3audio.o: audio/mpeg3audio.c \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ audio/../mpeg3protos.h \
+ audio/mpeg3audio.h \
+ audio/tables.h
+
+audio/pcm.o: audio/pcm.c \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ audio/../mpeg3protos.h
+
+audio/synthesizers.o: audio/synthesizers.c \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ audio/../mpeg3protos.h \
+ audio/tables.h
+
+audio/tables.o: audio/tables.c \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ audio/mpeg3audio.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ audio/../mpeg3protos.h \
+ audio/tables.h \
+ audio/fptables.h
+
+video/getpicture.o: video/getpicture.c \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ video/../mpeg3private.inc \
+ video/idct.h \
+ video/slice.h \
+ video/../timecode.h \
+ video/../mpeg3protos.h \
+ video/mpeg3video.h \
+ video/vlc.h
+
+video/headers.o: video/headers.c \
+ video/../mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ video/../mpeg3private.inc \
+ video/idct.h \
+ video/slice.h \
+ video/../timecode.h \
+ video/../mpeg3protos.h \
+ video/mpeg3video.h
+
+video/idct.o: video/idct.c \
+ video/idct.h
+
+video/macroblocks.o: video/macroblocks.c \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ video/../mpeg3private.inc \
+ video/idct.h \
+ video/slice.h \
+ video/../timecode.h \
+ video/../mpeg3protos.h \
+ video/mpeg3video.h \
+ video/vlc.h
+
+video/mmxtest.o: video/mmxtest.c \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ video/../mpeg3private.inc \
+ video/idct.h \
+ video/slice.h \
+ video/../timecode.h \
+ video/../mpeg3protos.h
+
+video/motion.o: video/motion.c \
+ video/mpeg3video.h \
+ audio/../bitstream.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ video/../mpeg3private.inc \
+ video/idct.h \
+ video/slice.h \
+ video/../timecode.h \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ video/../mpeg3protos.h \
+ video/vlc.h
+
+video/mpeg3video.o: video/mpeg3video.c \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ video/../mpeg3private.inc \
+ video/idct.h \
+ video/slice.h \
+ video/../timecode.h \
+ video/../mpeg3protos.h \
+ video/mpeg3video.h \
+ video/mpeg3videoprotos.h
+
+video/output.o: video/output.c \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ video/../mpeg3private.inc \
+ video/idct.h \
+ video/slice.h \
+ video/../timecode.h \
+ video/../mpeg3protos.h \
+ video/mpeg3video.h
+
+video/reconstruct.o: video/reconstruct.c \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ video/../mpeg3private.inc \
+ video/idct.h \
+ video/slice.h \
+ video/../timecode.h \
+ video/../mpeg3protos.h \
+ video/mpeg3video.h
+
+video/seek.o: video/seek.c \
+ video/../mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ video/../mpeg3private.inc \
+ video/idct.h \
+ video/slice.h \
+ video/../timecode.h \
+ video/../mpeg3protos.h \
+ video/mpeg3video.h
+
+video/slice.o: video/slice.c \
+ audio/../libmpeg3.h \
+ mpeg3private.h \
+ mpeg3atrack.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ audio/mpeg3audio.h \
+ audio/ac3.h \
+ audio/mpeg3real.h \
+ audio/../bitstream.h \
+ mpeg3vtrack.h \
+ video/mpeg3video.h \
+ video/../mpeg3private.inc \
+ video/idct.h \
+ video/slice.h \
+ video/../timecode.h \
+ video/../mpeg3protos.h \
+ video/mpeg3video.h \
+ video/mpeg3videoprotos.h
+
+video/vlc.o: video/vlc.c \
+ video/mpeg3video.h \
+ audio/../bitstream.h \
+ mpeg3demux.h \
+ mpeg3title.h \
+ mpeg3io.h \
+ mpeg3css.h \
+ mpeg3private.inc \
+ video/../mpeg3private.inc \
+ video/idct.h \
+ video/slice.h \
+ video/../timecode.h \
+ video/vlc.h
+
+
diff --git a/core/multimedia/opieplayer/libmpeg3/README b/core/multimedia/opieplayer/libmpeg3/README
new file mode 100644
index 0000000..7a2a061
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/README
@@ -0,0 +1,35 @@
+/********************************************************
+ * LibMPEG3
+ * Author: Adam Williams <broadcast@earthling.net>
+ * Page: heroine.linuxbox.com
+ *
+ * libmpeg3 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.
+ *
+ * libmpeg3 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.
+ *
+ *******************************************************/
+
+
+/**********************************************************
+ * Credits:
+ *********************************************************/
+
+AC3 decoder:
+
+ Written by Aaron Holtzman (aholtzma@engr.uvic.ca)
+
+
+
+Problems:
+
+ Streams where the multiplexing packet size changes at random.
diff --git a/core/multimedia/opieplayer/libmpeg3/VERSION b/core/multimedia/opieplayer/libmpeg3/VERSION
new file mode 100644
index 0000000..55772e2
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/VERSION
@@ -0,0 +1 @@
+libmpeg3-1.2.1
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/Makefile b/core/multimedia/opieplayer/libmpeg3/audio/Makefile
new file mode 100644
index 0000000..eaa0e0b
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/Makefile
@@ -0,0 +1,35 @@
+include ../global_config
+export CFLAGS
+export CFLAGS_lessopt
+
+OBJS = \
+ ac3.o \
+ bit_allocation.o \
+ dct.o \
+ exponents.o \
+ header.o \
+ layer2.o \
+ layer3.o \
+ mantissa.o \
+ mpeg3audio.o \
+ pcm.o \
+ synthesizers.o \
+ tables.o
+
+all: $(OBJS)
+
+dct.o: dct.c
+ $(CC) -c `./c_flags dct.c` -o $@ $<
+
+synthesizers.o: synthesizers.c
+ $(CC) -c `./c_flags synthesizers.c` -o $@ $<
+
+
+.c.o:
+ $(CC) -c `./c_flags` -o $@ $<
+
+.s.o:
+ $(CC) -f elf $*.s
+
+clean:
+ rm -f *.o
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/ac3.c b/core/multimedia/opieplayer/libmpeg3/audio/ac3.c
new file mode 100644
index 0000000..7a3b664
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/ac3.c
@@ -0,0 +1,691 @@
+/*
+ *
+ * ac3.c Copyright (C) Aaron Holtzman - May 1999
+ *
+ *
+ * This file is part of libmpeg3
+ *
+ * libmpeg3 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.
+ *
+ * libmpeg3 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 "mpeg3audio.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define MPEG3AC3_MAGIC_NUMBER 0xdeadbeef
+
+
+int mpeg3_ac3_samplerates[] = { 48000, 44100, 32000 };
+
+struct mpeg3_framesize_s
+{
+ unsigned short bit_rate;
+ unsigned short frm_size[3];
+};
+
+struct mpeg3_framesize_s framesize_codes[] =
+{
+ { 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 } }
+};
+
+/* Audio channel modes */
+short mpeg3_ac3_acmodes[] = {2, 1, 2, 3, 3, 4, 4, 5};
+
+/* Rematrix tables */
+struct rematrix_band_s
+{
+ int start;
+ int end;
+};
+
+struct rematrix_band_s mpeg3_rematrix_band[] =
+{
+ {13, 24},
+ {25, 36},
+ {37, 60},
+ {61, 252}
+};
+
+int mpeg3_min(int x, int y)
+{
+ return (x < y) ? x : y;
+}
+
+int mpeg3_max(int x, int y)
+{
+ return (x > y) ? x : y;
+}
+
+int mpeg3audio_read_ac3_header(mpeg3audio_t *audio)
+{
+ unsigned int code, crc;
+ unsigned int i;
+ mpeg3_ac3bsi_t *bsi = &(audio->ac3_bsi);
+
+/* Get the sync code */
+ code = mpeg3bits_getbits(audio->astream, 16);
+ while(!mpeg3bits_eof(audio->astream) && code != MPEG3_AC3_START_CODE)
+ {
+ code <<= 8;
+ code &= 0xffff;
+ code |= mpeg3bits_getbits(audio->astream, 8);
+ }
+
+ if(mpeg3bits_eof(audio->astream)) return 1;
+
+/* Get crc1 - we don't actually use this data though */
+/* The crc can be the same as the sync code or come after a sync code repeated twice */
+ crc = mpeg3bits_getbits(audio->astream, 16);
+
+/* Got the sync code. Read the entire frame into a buffer if possible. */
+ if(audio->avg_framesize > 0)
+ {
+ if(mpeg3bits_read_buffer(audio->astream, audio->ac3_buffer, audio->framesize - 4))
+ return 1;
+ mpeg3bits_use_ptr(audio->astream, audio->ac3_buffer);
+ }
+
+/* Get the sampling rate code */
+ audio->sampling_frequency_code = mpeg3bits_getbits(audio->astream, 2);
+
+/* Get the frame size code */
+ audio->ac3_framesize_code = mpeg3bits_getbits(audio->astream, 6);
+
+ audio->bitrate = framesize_codes[audio->ac3_framesize_code].bit_rate;
+ audio->avg_framesize = audio->framesize = 2 * framesize_codes[audio->ac3_framesize_code].frm_size[audio->sampling_frequency_code];
+
+/* Check the AC-3 version number */
+ bsi->bsid = mpeg3bits_getbits(audio->astream, 5);
+
+/* Get the audio service provided by the steram */
+ bsi->bsmod = mpeg3bits_getbits(audio->astream, 3);
+
+/* Get the audio coding mode (ie how many channels)*/
+ bsi->acmod = mpeg3bits_getbits(audio->astream, 3);
+
+/* Predecode the number of full bandwidth channels as we use this
+ * number a lot */
+ bsi->nfchans = mpeg3_ac3_acmodes[bsi->acmod];
+ audio->channels = bsi->nfchans;
+
+/* If it is in use, get the centre channel mix level */
+ if((bsi->acmod & 0x1) && (bsi->acmod != 0x1))
+ bsi->cmixlev = mpeg3bits_getbits(audio->astream, 2);
+
+/* If it is in use, get the surround channel mix level */
+ if(bsi->acmod & 0x4)
+ bsi->surmixlev = mpeg3bits_getbits(audio->astream, 2);
+
+/* Get the dolby surround mode if in 2/0 mode */
+ if(bsi->acmod == 0x2)
+ bsi->dsurmod= mpeg3bits_getbits(audio->astream, 2);
+
+/* Is the low frequency effects channel on? */
+ bsi->lfeon = mpeg3bits_getbits(audio->astream, 1);
+
+/* Get the dialogue normalization level */
+ bsi->dialnorm = mpeg3bits_getbits(audio->astream, 5);
+
+/* Does compression gain exist? */
+ bsi->compre = mpeg3bits_getbits(audio->astream, 1);
+ if (bsi->compre)
+ {
+/* Get compression gain */
+ bsi->compr = mpeg3bits_getbits(audio->astream, 8);
+ }
+
+/* Does language code exist? */
+ bsi->langcode = mpeg3bits_getbits(audio->astream, 1);
+ if (bsi->langcode)
+ {
+/* Get langauge code */
+ bsi->langcod = mpeg3bits_getbits(audio->astream, 8);
+ }
+
+/* Does audio production info exist? */
+ bsi->audprodie = mpeg3bits_getbits(audio->astream, 1);
+ if (bsi->audprodie)
+ {
+/* Get mix level */
+ bsi->mixlevel = mpeg3bits_getbits(audio->astream, 5);
+
+/* Get room type */
+ bsi->roomtyp = mpeg3bits_getbits(audio->astream, 2);
+ }
+
+/* If we're in dual mono mode then get some extra info */
+ if (bsi->acmod == 0)
+ {
+/* Get the dialogue normalization level two */
+ bsi->dialnorm2 = mpeg3bits_getbits(audio->astream, 5);
+
+/* Does compression gain two exist? */
+ bsi->compr2e = mpeg3bits_getbits(audio->astream, 1);
+ if (bsi->compr2e)
+ {
+/* Get compression gain two */
+ bsi->compr2 = mpeg3bits_getbits(audio->astream, 8);
+ }
+
+/* Does language code two exist? */
+ bsi->langcod2e = mpeg3bits_getbits(audio->astream, 1);
+ if (bsi->langcod2e)
+ {
+/* Get langauge code two */
+ bsi->langcod2 = mpeg3bits_getbits(audio->astream, 8);
+ }
+
+/* Does audio production info two exist? */
+ bsi->audprodi2e = mpeg3bits_getbits(audio->astream, 1);
+ if (bsi->audprodi2e)
+ {
+/* Get mix level two */
+ bsi->mixlevel2 = mpeg3bits_getbits(audio->astream, 5);
+
+/* Get room type two */
+ bsi->roomtyp2 = mpeg3bits_getbits(audio->astream, 2);
+ }
+ }
+
+/* Get the copyright bit */
+ bsi->copyrightb = mpeg3bits_getbits(audio->astream, 1);
+
+/* Get the original bit */
+ bsi->origbs = mpeg3bits_getbits(audio->astream, 1);
+
+/* Does timecode one exist? */
+ bsi->timecod1e = mpeg3bits_getbits(audio->astream, 1);
+
+ if(bsi->timecod1e)
+ bsi->timecod1 = mpeg3bits_getbits(audio->astream, 14);
+
+/* Does timecode two exist? */
+ bsi->timecod2e = mpeg3bits_getbits(audio->astream, 1);
+
+ if(bsi->timecod2e)
+ bsi->timecod2 = mpeg3bits_getbits(audio->astream, 14);
+
+/* Does addition info exist? */
+ bsi->addbsie = mpeg3bits_getbits(audio->astream, 1);
+
+ if(bsi->addbsie)
+ {
+/* Get how much info is there */
+ bsi->addbsil = mpeg3bits_getbits(audio->astream, 6);
+
+/* Get the additional info */
+ for(i = 0; i < (bsi->addbsil + 1); i++)
+ bsi->addbsi[i] = mpeg3bits_getbits(audio->astream, 8);
+ }
+
+ if(mpeg3bits_eof(audio->astream))
+ {
+ mpeg3bits_use_demuxer(audio->astream);
+ return 1;
+ }
+// return mpeg3bits_error(audio->astream);
+}
+
+int mpeg3audio_read_ac3_audblk(mpeg3audio_t *audio)
+{
+ int i, j;
+ mpeg3_ac3bsi_t *bsi = &(audio->ac3_bsi);
+ mpeg3_ac3audblk_t *audblk = &(audio->ac3_audblk);
+
+ for(i = 0; i < bsi->nfchans; i++)
+ {
+/* Is this channel an interleaved 256 + 256 block ? */
+ audblk->blksw[i] = mpeg3bits_getbits(audio->astream, 1);
+ }
+
+ for(i = 0; i < bsi->nfchans; i++)
+ {
+/* Should we dither this channel? */
+ audblk->dithflag[i] = mpeg3bits_getbits(audio->astream, 1);
+ }
+
+/* Does dynamic range control exist? */
+ audblk->dynrnge = mpeg3bits_getbits(audio->astream, 1);
+ if(audblk->dynrnge)
+ {
+/* Get dynamic range info */
+ audblk->dynrng = mpeg3bits_getbits(audio->astream, 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? */
+ audblk->dynrng2e = mpeg3bits_getbits(audio->astream, 1);
+ if (audblk->dynrng2e)
+ {
+/* Get dynamic range info */
+ audblk->dynrng2 = mpeg3bits_getbits(audio->astream, 8);
+ }
+ }
+
+/* Does coupling strategy exist? */
+ audblk->cplstre = mpeg3bits_getbits(audio->astream, 1);
+ if(audblk->cplstre)
+ {
+/* Is coupling turned on? */
+ audblk->cplinu = mpeg3bits_getbits(audio->astream, 1);
+ if(audblk->cplinu)
+ {
+ for(i = 0; i < bsi->nfchans; i++)
+ audblk->chincpl[i] = mpeg3bits_getbits(audio->astream, 1);
+
+ if(bsi->acmod == 0x2)
+ audblk->phsflginu = mpeg3bits_getbits(audio->astream, 1);
+
+ audblk->cplbegf = mpeg3bits_getbits(audio->astream, 4);
+ audblk->cplendf = mpeg3bits_getbits(audio->astream, 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] = mpeg3bits_getbits(audio->astream, 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? */
+ audblk->cplcoe[i] = mpeg3bits_getbits(audio->astream, 1);
+
+ if(audblk->cplcoe[i])
+ {
+ audblk->mstrcplco[i] = mpeg3bits_getbits(audio->astream, 2);
+ for(j = 0; j < audblk->ncplbnd; j++)
+ {
+ audblk->cplcoexp[i][j] = mpeg3bits_getbits(audio->astream, 4);
+ audblk->cplcomant[i][j] = mpeg3bits_getbits(audio->astream, 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] = mpeg3bits_getbits(audio->astream, 1);
+ }
+ }
+ }
+
+/* If we're in dual mono mode, there may be a rematrix strategy */
+ if(bsi->acmod == 0x2)
+ {
+ audblk->rematstr = mpeg3bits_getbits(audio->astream, 1);
+ if(audblk->rematstr)
+ {
+ if (audblk->cplinu == 0)
+ {
+ for(i = 0; i < 4; i++)
+ audblk->rematflg[i] = mpeg3bits_getbits(audio->astream, 1);
+ }
+ if((audblk->cplbegf > 2) && audblk->cplinu)
+ {
+ for(i = 0; i < 4; i++)
+ audblk->rematflg[i] = mpeg3bits_getbits(audio->astream, 1);
+ }
+ if((audblk->cplbegf <= 2) && audblk->cplinu)
+ {
+ for(i = 0; i < 3; i++)
+ audblk->rematflg[i] = mpeg3bits_getbits(audio->astream, 1);
+ }
+ if((audblk->cplbegf == 0) && audblk->cplinu)
+ for(i = 0; i < 2; i++)
+ audblk->rematflg[i] = mpeg3bits_getbits(audio->astream, 1);
+
+ }
+ }
+
+ if (audblk->cplinu)
+ {
+/* Get the coupling channel exponent strategy */
+ audblk->cplexpstr = mpeg3bits_getbits(audio->astream, 2);
+
+ if(audblk->cplexpstr == 0)
+ audblk->ncplgrps = 0;
+ else
+ audblk->ncplgrps = (audblk->cplendmant - audblk->cplstrtmant) /
+ (3 << (audblk->cplexpstr - 1));
+
+ }
+
+ for(i = 0; i < bsi->nfchans; i++)
+ {
+ audblk->chexpstr[i] = mpeg3bits_getbits(audio->astream, 2);
+ }
+
+/* Get the exponent strategy for lfe channel */
+ if(bsi->lfeon)
+ audblk->lfeexpstr = mpeg3bits_getbits(audio->astream, 1);
+
+/* Determine the bandwidths of all the fbw channels */
+ for(i = 0; i < bsi->nfchans; i++)
+ {
+ unsigned short grp_size;
+
+ if(audblk->chexpstr[i] != MPEG3_EXP_REUSE)
+ {
+ if (audblk->cplinu && audblk->chincpl[i])
+ {
+ audblk->endmant[i] = audblk->cplstrtmant;
+ }
+ else
+ {
+ audblk->chbwcod[i] = mpeg3bits_getbits(audio->astream, 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 != MPEG3_EXP_REUSE))
+ {
+ audblk->cplabsexp = mpeg3bits_getbits(audio->astream, 4);
+ for(i = 0; i< audblk->ncplgrps; i++)
+ audblk->cplexps[i] = mpeg3bits_getbits(audio->astream, 7);
+ }
+
+/* Get the fwb channel exponents */
+ for(i = 0; i < bsi->nfchans; i++)
+ {
+ if(audblk->chexpstr[i] != MPEG3_EXP_REUSE)
+ {
+ audblk->exps[i][0] = mpeg3bits_getbits(audio->astream, 4);
+ for(j = 1; j <= audblk->nchgrps[i]; j++)
+ audblk->exps[i][j] = mpeg3bits_getbits(audio->astream, 7);
+ audblk->gainrng[i] = mpeg3bits_getbits(audio->astream, 2);
+ }
+ }
+
+/* Get the lfe channel exponents */
+ if(bsi->lfeon && (audblk->lfeexpstr != MPEG3_EXP_REUSE))
+ {
+ audblk->lfeexps[0] = mpeg3bits_getbits(audio->astream, 4);
+ audblk->lfeexps[1] = mpeg3bits_getbits(audio->astream, 7);
+ audblk->lfeexps[2] = mpeg3bits_getbits(audio->astream, 7);
+ }
+
+/* Get the parametric bit allocation parameters */
+ audblk->baie = mpeg3bits_getbits(audio->astream, 1);
+
+ if(audblk->baie)
+ {
+ audblk->sdcycod = mpeg3bits_getbits(audio->astream, 2);
+ audblk->fdcycod = mpeg3bits_getbits(audio->astream, 2);
+ audblk->sgaincod = mpeg3bits_getbits(audio->astream, 2);
+ audblk->dbpbcod = mpeg3bits_getbits(audio->astream, 2);
+ audblk->floorcod = mpeg3bits_getbits(audio->astream, 3);
+ }
+
+
+/* Get the SNR off set info if it exists */
+ audblk->snroffste = mpeg3bits_getbits(audio->astream, 1);
+
+ if(audblk->snroffste)
+ {
+ audblk->csnroffst = mpeg3bits_getbits(audio->astream, 6);
+
+ if(audblk->cplinu)
+ {
+ audblk->cplfsnroffst = mpeg3bits_getbits(audio->astream, 4);
+ audblk->cplfgaincod = mpeg3bits_getbits(audio->astream, 3);
+ }
+
+ for(i = 0; i < bsi->nfchans; i++)
+ {
+ audblk->fsnroffst[i] = mpeg3bits_getbits(audio->astream, 4);
+ audblk->fgaincod[i] = mpeg3bits_getbits(audio->astream, 3);
+ }
+ if(bsi->lfeon)
+ {
+
+ audblk->lfefsnroffst = mpeg3bits_getbits(audio->astream, 4);
+ audblk->lfefgaincod = mpeg3bits_getbits(audio->astream, 3);
+ }
+ }
+
+/* Get coupling leakage info if it exists */
+ if(audblk->cplinu)
+ {
+ audblk->cplleake = mpeg3bits_getbits(audio->astream, 1);
+
+ if(audblk->cplleake)
+ {
+ audblk->cplfleak = mpeg3bits_getbits(audio->astream, 3);
+ audblk->cplsleak = mpeg3bits_getbits(audio->astream, 3);
+ }
+ }
+
+/* Get the delta bit alloaction info */
+ audblk->deltbaie = mpeg3bits_getbits(audio->astream, 1);
+
+ if(audblk->deltbaie)
+ {
+ if(audblk->cplinu)
+ audblk->cpldeltbae = mpeg3bits_getbits(audio->astream, 2);
+
+ for(i = 0; i < bsi->nfchans; i++)
+ audblk->deltbae[i] = mpeg3bits_getbits(audio->astream, 2);
+
+ if (audblk->cplinu && (audblk->cpldeltbae == DELTA_BIT_NEW))
+ {
+ audblk->cpldeltnseg = mpeg3bits_getbits(audio->astream, 3);
+ for(i = 0; i < audblk->cpldeltnseg + 1; i++)
+ {
+ audblk->cpldeltoffst[i] = mpeg3bits_getbits(audio->astream, 5);
+ audblk->cpldeltlen[i] = mpeg3bits_getbits(audio->astream, 4);
+ audblk->cpldeltba[i] = mpeg3bits_getbits(audio->astream, 3);
+ }
+ }
+
+ for(i = 0; i < bsi->nfchans; i++)
+ {
+ if (audblk->deltbae[i] == DELTA_BIT_NEW)
+ {
+ audblk->deltnseg[i] = mpeg3bits_getbits(audio->astream, 3);
+ for(j = 0; j < audblk->deltnseg[i] + 1; j++)
+ {
+ audblk->deltoffst[i][j] = mpeg3bits_getbits(audio->astream, 5);
+ audblk->deltlen[i][j] = mpeg3bits_getbits(audio->astream, 4);
+ audblk->deltba[i][j] = mpeg3bits_getbits(audio->astream, 3);
+ }
+ }
+ }
+ }
+
+/* Check to see if there's any dummy info to get */
+ if((audblk->skiple = mpeg3bits_getbits(audio->astream, 1)))
+ {
+ unsigned int skip_data;
+ audblk->skipl = mpeg3bits_getbits(audio->astream, 9);
+ for(i = 0; i < audblk->skipl ; i++)
+ {
+ skip_data = mpeg3bits_getbits(audio->astream, 8);
+ }
+ }
+
+ return mpeg3bits_error(audio->astream);
+}
+
+
+/* This routine simply does stereo rematrixing for the 2 channel
+ * stereo mode */
+int mpeg3audio_ac3_rematrix(mpeg3_ac3audblk_t *audblk,
+ mpeg3ac3_stream_samples_t samples)
+{
+ int num_bands;
+ int start;
+ int end;
+ int i, j;
+ mpeg3_real_t left, right;
+
+ 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 = mpeg3_rematrix_band[i].start;
+ end = mpeg3_min(mpeg3_rematrix_band[i].end, 12 * audblk->cplbegf + 36);
+
+ for(j = start; j < end; j++)
+ {
+ left = samples[0][j] + samples[1][j];
+ right = samples[0][j] - samples[1][j];
+ samples[0][j] = left;
+ samples[1][j] = right;
+ }
+ }
+ return 0;
+}
+
+
+int mpeg3audio_ac3_reset_frame(mpeg3audio_t *audio)
+{
+ memset(&audio->ac3_bit_allocation, 0, sizeof(mpeg3_ac3_bitallocation_t));
+ memset(&audio->ac3_mantissa, 0, sizeof(mpeg3_ac3_mantissa_t));
+ memset(&audio->ac3_audblk, 0, sizeof(mpeg3_ac3audblk_t));
+
+ return 0;
+}
+
+int mpeg3audio_do_ac3(mpeg3audio_t *audio)
+{
+ int result = 0, i;
+
+/* Reset the coefficients and exponents */
+ mpeg3audio_ac3_reset_frame(audio);
+
+ for(i = 0; i < 6 && !result; i++)
+ {
+ memset(audio->ac3_samples, 0, sizeof(mpeg3_real_t) * 256 * (audio->ac3_bsi.nfchans + audio->ac3_bsi.lfeon));
+/* Extract most of the audblk info from the bitstream
+ * (minus the mantissas */
+ result |= mpeg3audio_read_ac3_audblk(audio);
+
+/* Take the differential exponent data and turn it into
+ * absolute exponents */
+ if(!result) result |= mpeg3audio_ac3_exponent_unpack(audio,
+ &(audio->ac3_bsi),
+ &(audio->ac3_audblk));
+
+/* Figure out how many bits per mantissa */
+ if(!result) result |= mpeg3audio_ac3_bit_allocate(audio,
+ audio->sampling_frequency_code,
+ &(audio->ac3_bsi),
+ &(audio->ac3_audblk));
+
+/* Extract the mantissas from the data stream */
+ if(!result) result |= mpeg3audio_ac3_coeff_unpack(audio,
+ &(audio->ac3_bsi),
+ &(audio->ac3_audblk),
+ audio->ac3_samples);
+
+ if(audio->ac3_bsi.acmod == 0x2)
+ if(!result) result |= mpeg3audio_ac3_rematrix(&(audio->ac3_audblk),
+ audio->ac3_samples);
+
+/* Convert the frequency data into time samples */
+ if(!result) result |= mpeg3audio_ac3_imdct(audio,
+ &(audio->ac3_bsi),
+ &(audio->ac3_audblk),
+ audio->ac3_samples);
+
+ if(audio->pcm_point / audio->channels >= audio->pcm_allocated - MPEG3AUDIO_PADDING * audio->channels)
+ {
+/* Need more room */
+ mpeg3audio_replace_buffer(audio, audio->pcm_allocated + MPEG3AUDIO_PADDING * audio->channels);
+ }
+ }
+
+ mpeg3bits_use_demuxer(audio->astream);
+
+ return result;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/ac3.h b/core/multimedia/opieplayer/libmpeg3/audio/ac3.h
new file mode 100644
index 0000000..9161c36
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/ac3.h
@@ -0,0 +1,308 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef AC3_H
+#define AC3_H
+
+#include "mpeg3real.h"
+
+#define MAX_AC3_FRAMESIZE 1920 * 2 + 512
+
+extern int mpeg3_ac3_samplerates[3];
+
+/* Exponent strategy constants */
+#define MPEG3_EXP_REUSE (0)
+#define MPEG3_EXP_D15 (1)
+#define MPEG3_EXP_D25 (2)
+#define MPEG3_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)
+
+
+typedef mpeg3_real_t mpeg3ac3_stream_samples_t[6][256];
+
+typedef struct
+{
+/* Bit stream identification == 0x8 */
+ int bsid;
+/* Bit stream mode */
+ int bsmod;
+/* Audio coding mode */
+ int acmod;
+/* If we're using the centre channel then */
+/* centre mix level */
+ int cmixlev;
+/* If we're using the surround channel then */
+/* surround mix level */
+ int surmixlev;
+/* If we're in 2/0 mode then */
+/* Dolby surround mix level - NOT USED - */
+ int dsurmod;
+/* Low frequency effects on */
+ int lfeon;
+/* Dialogue Normalization level */
+ int dialnorm;
+/* Compression exists */
+ int compre;
+/* Compression level */
+ int compr;
+/* Language code exists */
+ int langcode;
+/* Language code */
+ int langcod;
+/* Audio production info exists*/
+ unsigned int audprodie;
+ int mixlevel;
+ int roomtyp;
+/* If we're in dual mono mode (acmod == 0) then extra stuff */
+ int dialnorm2;
+ int compr2e;
+ int compr2;
+ int langcod2e;
+ int langcod2;
+ int audprodi2e;
+ int mixlevel2;
+ int roomtyp2;
+/* Copyright bit */
+ int copyrightb;
+/* Original bit */
+ int origbs;
+/* Timecode 1 exists */
+ int timecod1e;
+/* Timecode 1 */
+ unsigned int timecod1;
+/* Timecode 2 exists */
+ int timecod2e;
+/* Timecode 2 */
+ unsigned int timecod2;
+/* Additional bit stream info exists */
+ int addbsie;
+/* Additional bit stream length - 1 (in bytes) */
+ int addbsil;
+/* Additional bit stream information (max 64 bytes) */
+ unsigned char addbsi[64];
+
+/* Information not in the AC-3 bitstream, but derived */
+/* Number of channels (excluding LFE)
+ * Derived from acmod */
+ int nfchans;
+} mpeg3_ac3bsi_t;
+
+typedef struct
+{
+/* block switch bit indexed by channel num */
+ unsigned short blksw[5];
+/* dither enable bit indexed by channel num */
+ unsigned short dithflag[5];
+/* dynamic range gain exists */
+ int dynrnge;
+/* dynamic range gain */
+ int dynrng;
+/* if acmod==0 then */
+/* dynamic range 2 gain exists */
+ int dynrng2e;
+/* dynamic range 2 gain */
+ int dynrng2;
+/* coupling strategy exists */
+ int cplstre;
+/* coupling in use */
+ int cplinu;
+/* channel coupled */
+ unsigned short chincpl[5];
+/* if acmod==2 then */
+/* Phase flags in use */
+ int phsflginu;
+/* coupling begin frequency code */
+ int cplbegf;
+/* coupling end frequency code */
+ int cplendf;
+/* coupling band structure bits */
+ unsigned short cplbndstrc[18];
+/* Do coupling co-ords exist for this channel? */
+ unsigned short cplcoe[5];
+/* Master coupling co-ordinate */
+ unsigned short mstrcplco[5];
+/* Per coupling band coupling co-ordinates */
+ unsigned short cplcoexp[5][18];
+ unsigned short cplcomant[5][18];
+/* Phase flags for dual mono */
+ unsigned short phsflg[18];
+/* Is there a rematrixing strategy */
+ unsigned int rematstr;
+/* Rematrixing bits */
+ unsigned short rematflg[4];
+/* Coupling exponent strategy */
+ int cplexpstr;
+/* Exponent strategy for full bandwidth channels */
+ unsigned short chexpstr[5];
+/* Exponent strategy for lfe channel */
+ int lfeexpstr;
+/* Channel bandwidth for independent channels */
+ unsigned short chbwcod[5];
+/* The absolute coupling exponent */
+ int cplabsexp;
+/* Coupling channel exponents (D15 mode gives 18 * 12 /3 encoded exponents */
+ unsigned short cplexps[18 * 12 / 3];
+/* fbw channel exponents */
+ unsigned short exps[5][252 / 3];
+/* channel gain range */
+ unsigned short gainrng[5];
+/* low frequency exponents */
+ unsigned short lfeexps[3];
+
+/* Bit allocation info */
+ int baie;
+/* Slow decay code */
+ int sdcycod;
+/* Fast decay code */
+ int fdcycod;
+/* Slow gain code */
+ int sgaincod;
+/* dB per bit code */
+ int dbpbcod;
+/* masking floor code */
+ int floorcod;
+
+/* SNR offset info */
+ int snroffste;
+/* coarse SNR offset */
+ int csnroffst;
+/* coupling fine SNR offset */
+ int cplfsnroffst;
+/* coupling fast gain code */
+ int cplfgaincod;
+/* fbw fine SNR offset */
+ unsigned short fsnroffst[5];
+/* fbw fast gain code */
+ unsigned short fgaincod[5];
+/* lfe fine SNR offset */
+ int lfefsnroffst;
+/* lfe fast gain code */
+ int lfefgaincod;
+
+/* Coupling leak info */
+ int cplleake;
+/* coupling fast leak initialization */
+ int cplfleak;
+/* coupling slow leak initialization */
+ int cplsleak;
+
+/* delta bit allocation info */
+ int deltbaie;
+/* coupling delta bit allocation exists */
+ int cpldeltbae;
+/* fbw delta bit allocation exists */
+ unsigned short deltbae[5];
+/* number of cpl delta bit segments */
+ int cpldeltnseg;
+/* coupling delta bit allocation offset */
+ short cpldeltoffst[8];
+/* coupling delta bit allocation length */
+ short cpldeltlen[8];
+/* coupling delta bit allocation length */
+ short cpldeltba[8];
+/* number of delta bit segments */
+ unsigned short deltnseg[5];
+/* fbw delta bit allocation offset */
+ short deltoffst[5][8];
+/* fbw delta bit allocation length */
+ short deltlen[5][8];
+/* fbw delta bit allocation length */
+ short deltba[5][8];
+
+/* skip length exists */
+ int skiple;
+/* skip length */
+ int skipl;
+
+/* channel mantissas */
+ short chmant[5][256];
+
+/* coupling mantissas */
+ unsigned short cplmant[256];
+
+/* coupling mantissas */
+ unsigned short lfemant[7];
+
+/* -- Information not in the bitstream, but derived thereof -- */
+
+/* Number of coupling sub-bands */
+ int ncplsubnd;
+
+/* Number of combined coupling sub-bands
+ * Derived from ncplsubnd and cplbndstrc */
+ int ncplbnd;
+
+/* Number of exponent groups by channel
+ * Derived from strmant, endmant */
+ int nchgrps[5];
+
+/* Number of coupling exponent groups
+ * Derived from cplbegf, cplendf, cplexpstr */
+ int ncplgrps;
+
+/* End mantissa numbers of fbw channels */
+ unsigned short endmant[5];
+
+/* Start and end mantissa numbers for the coupling channel */
+ int cplstrtmant;
+ int cplendmant;
+
+/* Decoded exponent info */
+ unsigned short fbw_exp[5][256];
+ unsigned short cpl_exp[256];
+ unsigned short lfe_exp[7];
+
+/* Bit allocation pointer results */
+ short fbw_bap[5][256];
+/*FIXME figure out exactly how many entries there should be (253-37?) */
+ short cpl_bap[256];
+ short lfe_bap[7];
+} mpeg3_ac3audblk_t;
+
+/* Bit allocation data */
+typedef struct
+{
+ int sdecay;
+ int fdecay;
+ int sgain;
+ int dbknee;
+ int floor;
+ short psd[256];
+ short bndpsd[256];
+ short excite[256];
+ short mask[256];
+} mpeg3_ac3_bitallocation_t;
+
+/* Mantissa data */
+typedef struct
+{
+ unsigned short m_1[3];
+ unsigned short m_2[3];
+ unsigned short m_4[2];
+ unsigned short m_1_pointer;
+ unsigned short m_2_pointer;
+ unsigned short m_4_pointer;
+} mpeg3_ac3_mantissa_t;
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/bit_allocation.c b/core/multimedia/opieplayer/libmpeg3/audio/bit_allocation.c
new file mode 100644
index 0000000..29df7d7
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/bit_allocation.c
@@ -0,0 +1,586 @@
+/*
+ *
+ * Copyright (C) Aaron Holtzman - May 1999
+ *
+ *
+ * This file is part of libmpeg3
+ *
+ * libmpeg3 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.
+ *
+ * libmpeg3 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 "mpeg3audio.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include <string.h>
+#include <stdlib.h>
+
+/* Bit allocation tables */
+
+static short mpeg3_slowdec[] = { 0x0f, 0x11, 0x13, 0x15 };
+static short mpeg3_fastdec[] = { 0x3f, 0x53, 0x67, 0x7b };
+static short mpeg3_slowgain[] = { 0x540, 0x4d8, 0x478, 0x410 };
+static short mpeg3_dbpbtab[] = { 0x000, 0x700, 0x900, 0xb00 };
+
+static unsigned short mpeg3_floortab[] = { 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800 };
+static short mpeg3_fastgain[] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400 };
+
+
+static short mpeg3_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 short mpeg3_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 short mpeg3_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 short mpeg3_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 short mpeg3_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 short mpeg3_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
+};
+
+
+inline int logadd(int a, int b)
+{
+ int c;
+ int address;
+
+ c = a - b;
+ address = mpeg3_min((abs(c) >> 1), 255);
+
+ if(c >= 0)
+ return(a + mpeg3_latab[address]);
+ else
+ return(b + mpeg3_latab[address]);
+}
+
+
+int mpeg3audio_ac3_calc_lowcomp(int a, int b0, int b1, int bin)
+{
+ if(bin < 7)
+ {
+ if((b0 + 256) == b1)
+ a = 384;
+ else
+ if(b0 > b1)
+ a = mpeg3_max(0, a - 64);
+ }
+ else if(bin < 20)
+ {
+ if((b0 + 256) == b1)
+ a = 320;
+ else if(b0 > b1)
+ a = mpeg3_max(0, a - 64) ;
+ }
+ else
+ a = mpeg3_max(0, a - 128);
+
+ return(a);
+}
+
+void mpeg3audio_ac3_ba_compute_psd(int start,
+ int end,
+ unsigned short exps[],
+ short psd[],
+ short bndpsd[])
+{
+ int bin,i,j,k;
+ int lastbin = 0;
+
+/* Map the exponents into dBs */
+ for (bin = start; bin < end; bin++)
+ {
+ psd[bin] = (3072 - (exps[bin] << 7));
+ }
+
+/* Integrate the psd function over each bit allocation band */
+ j = start;
+ k = mpeg3_masktab[start];
+
+ do
+ {
+ lastbin = mpeg3_min(mpeg3_bndtab[k] + mpeg3_bndsz[k], end);
+ bndpsd[k] = psd[j];
+ j++;
+
+ for(i = j; i < lastbin; i++)
+ {
+ bndpsd[k] = logadd(bndpsd[k], psd[j]);
+ j++;
+ }
+
+ k++;
+ }while(end > lastbin);
+}
+
+void mpeg3audio_ac3_ba_compute_excitation(mpeg3audio_t *audio,
+ int start,
+ int end,
+ int fgain,
+ int fastleak,
+ int slowleak,
+ int is_lfe,
+ short bndpsd[],
+ short excite[])
+{
+ int bin;
+ int bndstrt;
+ int bndend;
+ int lowcomp = 0;
+ int begin = 0;
+
+/* Compute excitation function */
+ bndstrt = mpeg3_masktab[start];
+ bndend = mpeg3_masktab[end - 1] + 1;
+
+ if(bndstrt == 0) /* For fbw and lfe channels */
+ {
+ lowcomp = mpeg3audio_ac3_calc_lowcomp(lowcomp, bndpsd[0], bndpsd[1], 0);
+ excite[0] = bndpsd[0] - fgain - lowcomp;
+ lowcomp = mpeg3audio_ac3_calc_lowcomp(lowcomp, bndpsd[1], bndpsd[2], 1);
+ excite[1] = bndpsd[1] - fgain - lowcomp;
+ begin = 7 ;
+
+/* Note: Do not call mpeg3audio_ac3_calc_lowcomp() for the last band of the lfe channel, (bin = 6) */
+ for (bin = 2; bin < 7; bin++)
+ {
+ if(!(is_lfe && (bin == 6)))
+ lowcomp = mpeg3audio_ac3_calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin);
+ fastleak = bndpsd[bin] - fgain;
+ slowleak = bndpsd[bin] - audio->ac3_bit_allocation.sgain;
+ excite[bin] = fastleak - lowcomp;
+
+ if(!(is_lfe && (bin == 6)))
+ {
+ if(bndpsd[bin] <= bndpsd[bin+1])
+ {
+ begin = bin + 1 ;
+ break;
+ }
+ }
+ }
+
+ for (bin = begin; bin < mpeg3_min(bndend, 22); bin++)
+ {
+ if (!(is_lfe && (bin == 6)))
+ lowcomp = mpeg3audio_ac3_calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin);
+ fastleak -= audio->ac3_bit_allocation.fdecay;
+ fastleak = mpeg3_max(fastleak, bndpsd[bin] - fgain);
+ slowleak -= audio->ac3_bit_allocation.sdecay;
+ slowleak = mpeg3_max(slowleak, bndpsd[bin] - audio->ac3_bit_allocation.sgain);
+ excite[bin] = mpeg3_max(fastleak - lowcomp, slowleak);
+ }
+ begin = 22;
+ }
+ else /* For coupling channel */
+ {
+ begin = bndstrt;
+ }
+
+ for (bin = begin; bin < bndend; bin++)
+ {
+ fastleak -= audio->ac3_bit_allocation.fdecay;
+ fastleak = mpeg3_max(fastleak, bndpsd[bin] - fgain);
+ slowleak -= audio->ac3_bit_allocation.sdecay;
+ slowleak = mpeg3_max(slowleak, bndpsd[bin] - audio->ac3_bit_allocation.sgain);
+ excite[bin] = mpeg3_max(fastleak, slowleak) ;
+ }
+}
+
+void mpeg3audio_ac3_ba_compute_mask(mpeg3audio_t *audio,
+ int start,
+ int end,
+ int fscod,
+ int deltbae,
+ int deltnseg,
+ short deltoffst[],
+ short deltba[],
+ short deltlen[],
+ short excite[],
+ short mask[])
+{
+ int bin, k;
+ int bndstrt;
+ int bndend;
+ int delta;
+
+ bndstrt = mpeg3_masktab[start];
+ bndend = mpeg3_masktab[end - 1] + 1;
+
+/* Compute the masking curve */
+
+ for (bin = bndstrt; bin < bndend; bin++)
+ {
+ if (audio->ac3_bit_allocation.bndpsd[bin] < audio->ac3_bit_allocation.dbknee)
+ {
+ excite[bin] += ((audio->ac3_bit_allocation.dbknee - audio->ac3_bit_allocation.bndpsd[bin]) >> 2);
+ }
+ mask[bin] = mpeg3_max(excite[bin], mpeg3_hth[fscod][bin]);
+ }
+
+/* Perform delta bit modulation if necessary */
+ if ((deltbae == DELTA_BIT_REUSE) || (deltbae == DELTA_BIT_NEW))
+ {
+ int band = 0;
+ int 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++;
+ }
+ }
+ }
+}
+
+void mpeg3audio_ac3_ba_compute_bap(mpeg3audio_t *audio,
+ int start,
+ int end,
+ int snroffset,
+ short psd[],
+ short mask[],
+ short bap[])
+{
+ int i, j, k;
+ short lastbin = 0;
+ short address = 0;
+
+/* Compute the bit allocation pointer for each bin */
+ i = start;
+ j = mpeg3_masktab[start];
+
+ do
+ {
+ lastbin = mpeg3_min(mpeg3_bndtab[j] + mpeg3_bndsz[j], end);
+ mask[j] -= snroffset;
+ mask[j] -= audio->ac3_bit_allocation.floor;
+
+ if(mask[j] < 0)
+ mask[j] = 0;
+
+ mask[j] &= 0x1fe0;
+ mask[j] += audio->ac3_bit_allocation.floor;
+ for(k = i; k < lastbin; k++)
+ {
+ address = (psd[i] - mask[j]) >> 5;
+ address = mpeg3_min(63, mpeg3_max(0, address));
+ bap[i] = mpeg3_baptab[address];
+ i++;
+ }
+ j++;
+ }while (end > lastbin);
+}
+
+int mpeg3audio_ac3_bit_allocate(mpeg3audio_t *audio,
+ unsigned int fscod,
+ mpeg3_ac3bsi_t *bsi,
+ mpeg3_ac3audblk_t *audblk)
+{
+ int result = 0;
+ int i;
+ int fgain;
+ int snroffset;
+ int start;
+ int end;
+ int fastleak;
+ int slowleak;
+
+/*printf("mpeg3audio_ac3_bit_allocate %d %d %d %d %d\n", audblk->sdcycod, audblk->fdcycod, audblk->sgaincod, audblk->dbpbcod, audblk->floorcod); */
+/* 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 0;
+
+/* Do some setup before we do the bit alloc */
+ audio->ac3_bit_allocation.sdecay = mpeg3_slowdec[audblk->sdcycod];
+ audio->ac3_bit_allocation.fdecay = mpeg3_fastdec[audblk->fdcycod];
+ audio->ac3_bit_allocation.sgain = mpeg3_slowgain[audblk->sgaincod];
+ audio->ac3_bit_allocation.dbknee = mpeg3_dbpbtab[audblk->dbpbcod];
+ audio->ac3_bit_allocation.floor = mpeg3_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(short) * 256 * 5);
+ memset(audblk->cpl_bap, 0, sizeof(short) * 256);
+ memset(audblk->lfe_bap, 0, sizeof(short) * 7);
+ return 0;
+ }
+
+ for(i = 0; i < bsi->nfchans; i++)
+ {
+ start = 0;
+ end = audblk->endmant[i];
+ fgain = mpeg3_fastgain[audblk->fgaincod[i]];
+ snroffset = (((audblk->csnroffst - 15) << 4) + audblk->fsnroffst[i]) << 2 ;
+ fastleak = 0;
+ slowleak = 0;
+
+ mpeg3audio_ac3_ba_compute_psd(start,
+ end,
+ audblk->fbw_exp[i],
+ audio->ac3_bit_allocation.psd,
+ audio->ac3_bit_allocation.bndpsd);
+
+ mpeg3audio_ac3_ba_compute_excitation(audio,
+ start,
+ end ,
+ fgain,
+ fastleak,
+ slowleak,
+ 0,
+ audio->ac3_bit_allocation.bndpsd,
+ audio->ac3_bit_allocation.excite);
+
+ mpeg3audio_ac3_ba_compute_mask(audio,
+ start,
+ end,
+ fscod,
+ audblk->deltbae[i],
+ audblk->deltnseg[i],
+ audblk->deltoffst[i],
+ audblk->deltba[i],
+ audblk->deltlen[i],
+ audio->ac3_bit_allocation.excite,
+ audio->ac3_bit_allocation.mask);
+
+ mpeg3audio_ac3_ba_compute_bap(audio,
+ start,
+ end,
+ snroffset,
+ audio->ac3_bit_allocation.psd,
+ audio->ac3_bit_allocation.mask,
+ audblk->fbw_bap[i]);
+ }
+
+ if(audblk->cplinu)
+ {
+ start = audblk->cplstrtmant;
+ end = audblk->cplendmant;
+ fgain = mpeg3_fastgain[audblk->cplfgaincod];
+ snroffset = (((audblk->csnroffst - 15) << 4) + audblk->cplfsnroffst) << 2 ;
+ fastleak = (audblk->cplfleak << 8) + 768;
+ slowleak = (audblk->cplsleak << 8) + 768;
+
+ mpeg3audio_ac3_ba_compute_psd(start,
+ end,
+ audblk->cpl_exp,
+ audio->ac3_bit_allocation.psd,
+ audio->ac3_bit_allocation.bndpsd);
+
+ mpeg3audio_ac3_ba_compute_excitation(audio,
+ start,
+ end ,
+ fgain,
+ fastleak,
+ slowleak,
+ 0,
+ audio->ac3_bit_allocation.bndpsd,
+ audio->ac3_bit_allocation.excite);
+
+ mpeg3audio_ac3_ba_compute_mask(audio,
+ start,
+ end,
+ fscod,
+ audblk->cpldeltbae,
+ audblk->cpldeltnseg,
+ audblk->cpldeltoffst,
+ audblk->cpldeltba,
+ audblk->cpldeltlen,
+ audio->ac3_bit_allocation.excite,
+ audio->ac3_bit_allocation.mask);
+
+ mpeg3audio_ac3_ba_compute_bap(audio,
+ start,
+ end,
+ snroffset,
+ audio->ac3_bit_allocation.psd,
+ audio->ac3_bit_allocation.mask,
+ audblk->cpl_bap);
+ }
+
+ if(bsi->lfeon)
+ {
+ start = 0;
+ end = 7;
+ fgain = mpeg3_fastgain[audblk->lfefgaincod];
+ snroffset = (((audblk->csnroffst - 15) << 4) + audblk->lfefsnroffst) << 2 ;
+ fastleak = 0;
+ slowleak = 0;
+
+ mpeg3audio_ac3_ba_compute_psd(start,
+ end,
+ audblk->lfe_exp,
+ audio->ac3_bit_allocation.psd,
+ audio->ac3_bit_allocation.bndpsd);
+
+ mpeg3audio_ac3_ba_compute_excitation(audio,
+ start,
+ end ,
+ fgain,
+ fastleak,
+ slowleak,
+ 1,
+ audio->ac3_bit_allocation.bndpsd,
+ audio->ac3_bit_allocation.excite);
+
+/* Perform no delta bit allocation for lfe */
+ mpeg3audio_ac3_ba_compute_mask(audio,
+ start,
+ end,
+ fscod,
+ 2,
+ 0,
+ 0,
+ 0,
+ 0,
+ audio->ac3_bit_allocation.excite,
+ audio->ac3_bit_allocation.mask);
+
+ mpeg3audio_ac3_ba_compute_bap(audio,
+ start,
+ end,
+ snroffset,
+ audio->ac3_bit_allocation.psd,
+ audio->ac3_bit_allocation.mask,
+ audblk->lfe_bap);
+ }
+
+ return result;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/c_flags b/core/multimedia/opieplayer/libmpeg3/audio/c_flags
new file mode 100755
index 0000000..d7943d0
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/c_flags
@@ -0,0 +1 @@
+echo $CFLAGS
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/dct.c b/core/multimedia/opieplayer/libmpeg3/audio/dct.c
new file mode 100644
index 0000000..1fd52ce
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/dct.c
@@ -0,0 +1,1135 @@
+/*
+ *
+ * This file is part of libmpeg3
+ *
+ * libmpeg3 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.
+ *
+ * libmpeg3 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.
+ *
+ */
+
+/*
+ * 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 "mpeg3audio.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "tables.h"
+
+#include <math.h>
+
+int mpeg3audio_dct64_1(mpeg3_real_t *out0, mpeg3_real_t *out1, mpeg3_real_t *b1, mpeg3_real_t *b2, mpeg3_real_t *samples)
+{
+ register mpeg3_real_t *costab = mpeg3_pnts[0];
+
+ b1[0x00] = samples[0x00] + samples[0x1F];
+ b1[0x01] = samples[0x01] + samples[0x1E];
+ b1[0x1F] = (samples[0x00] - samples[0x1F]) * costab[0x0];
+ b1[0x1E] = (samples[0x01] - samples[0x1E]) * costab[0x1];
+
+ b1[0x02] = samples[0x02] + samples[0x1D];
+ b1[0x03] = samples[0x03] + samples[0x1C];
+ b1[0x1D] = (samples[0x02] - samples[0x1D]) * costab[0x2];
+ b1[0x1C] = (samples[0x03] - samples[0x1C]) * costab[0x3];
+
+ b1[0x04] = samples[0x04] + samples[0x1B];
+ b1[0x05] = samples[0x05] + samples[0x1A];
+ b1[0x1B] = (samples[0x04] - samples[0x1B]) * costab[0x4];
+ b1[0x1A] = (samples[0x05] - samples[0x1A]) * costab[0x5];
+
+ b1[0x06] = samples[0x06] + samples[0x19];
+ b1[0x07] = samples[0x07] + samples[0x18];
+ b1[0x19] = (samples[0x06] - samples[0x19]) * costab[0x6];
+ b1[0x18] = (samples[0x07] - samples[0x18]) * costab[0x7];
+
+ b1[0x08] = samples[0x08] + samples[0x17];
+ b1[0x09] = samples[0x09] + samples[0x16];
+ b1[0x17] = (samples[0x08] - samples[0x17]) * costab[0x8];
+ b1[0x16] = (samples[0x09] - samples[0x16]) * costab[0x9];
+
+ b1[0x0A] = samples[0x0A] + samples[0x15];
+ b1[0x0B] = samples[0x0B] + samples[0x14];
+ b1[0x15] = (samples[0x0A] - samples[0x15]) * costab[0xA];
+ b1[0x14] = (samples[0x0B] - samples[0x14]) * costab[0xB];
+
+ b1[0x0C] = samples[0x0C] + samples[0x13];
+ b1[0x0D] = samples[0x0D] + samples[0x12];
+ b1[0x13] = (samples[0x0C] - samples[0x13]) * costab[0xC];
+ b1[0x12] = (samples[0x0D] - samples[0x12]) * costab[0xD];
+
+ b1[0x0E] = samples[0x0E] + samples[0x11];
+ b1[0x0F] = samples[0x0F] + samples[0x10];
+ b1[0x11] = (samples[0x0E] - samples[0x11]) * costab[0xE];
+ b1[0x10] = (samples[0x0F] - samples[0x10]) * costab[0xF];
+
+ costab = mpeg3_pnts[1];
+
+ b2[0x00] = b1[0x00] + b1[0x0F];
+ b2[0x01] = b1[0x01] + b1[0x0E];
+ b2[0x0F] = (b1[0x00] - b1[0x0F]) * costab[0];
+ b2[0x0E] = (b1[0x01] - b1[0x0E]) * costab[1];
+
+ b2[0x02] = b1[0x02] + b1[0x0D];
+ b2[0x03] = b1[0x03] + b1[0x0C];
+ b2[0x0D] = (b1[0x02] - b1[0x0D]) * costab[2];
+ b2[0x0C] = (b1[0x03] - b1[0x0C]) * costab[3];
+
+ b2[0x04] = b1[0x04] + b1[0x0B];
+ b2[0x05] = b1[0x05] + b1[0x0A];
+ b2[0x0B] = (b1[0x04] - b1[0x0B]) * costab[4];
+ b2[0x0A] = (b1[0x05] - b1[0x0A]) * costab[5];
+
+ b2[0x06] = b1[0x06] + b1[0x09];
+ b2[0x07] = b1[0x07] + b1[0x08];
+ b2[0x09] = (b1[0x06] - b1[0x09]) * costab[6];
+ b2[0x08] = (b1[0x07] - b1[0x08]) * costab[7];
+
+ /* */
+
+ b2[0x10] = b1[0x10] + b1[0x1F];
+ b2[0x11] = b1[0x11] + b1[0x1E];
+ b2[0x1F] = (b1[0x1F] - b1[0x10]) * costab[0];
+ b2[0x1E] = (b1[0x1E] - b1[0x11]) * costab[1];
+
+ b2[0x12] = b1[0x12] + b1[0x1D];
+ b2[0x13] = b1[0x13] + b1[0x1C];
+ b2[0x1D] = (b1[0x1D] - b1[0x12]) * costab[2];
+ b2[0x1C] = (b1[0x1C] - b1[0x13]) * costab[3];
+
+ b2[0x14] = b1[0x14] + b1[0x1B];
+ b2[0x15] = b1[0x15] + b1[0x1A];
+ b2[0x1B] = (b1[0x1B] - b1[0x14]) * costab[4];
+ b2[0x1A] = (b1[0x1A] - b1[0x15]) * costab[5];
+
+ b2[0x16] = b1[0x16] + b1[0x19];
+ b2[0x17] = b1[0x17] + b1[0x18];
+ b2[0x19] = (b1[0x19] - b1[0x16]) * costab[6];
+ b2[0x18] = (b1[0x18] - b1[0x17]) * costab[7];
+
+ costab = mpeg3_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 mpeg3_real_t const cos0 = mpeg3_pnts[3][0];
+ register mpeg3_real_t const cos1 = mpeg3_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 mpeg3_real_t const cos0 = mpeg3_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];
+
+ out0[0x10*14] = b1[0x08] + b1[0x0C];
+ out0[0x10*10] = b1[0x0C] + b1[0x0a];
+ out0[0x10* 6] = b1[0x0A] + b1[0x0E];
+ out0[0x10* 2] = b1[0x0E] + b1[0x09];
+ out1[0x10* 2] = b1[0x09] + b1[0x0D];
+ out1[0x10* 6] = b1[0x0D] + b1[0x0B];
+ out1[0x10*10] = b1[0x0B] + b1[0x0F];
+ out1[0x10*14] = b1[0x0F];
+
+ {
+ register mpeg3_real_t tmp;
+ tmp = b1[0x18] + b1[0x1C];
+ out0[0x10*15] = tmp + b1[0x10];
+ out0[0x10*13] = tmp + b1[0x14];
+ tmp = b1[0x1C] + b1[0x1A];
+ out0[0x10*11] = tmp + b1[0x14];
+ out0[0x10* 9] = tmp + b1[0x12];
+ tmp = b1[0x1A] + b1[0x1E];
+ out0[0x10* 7] = tmp + b1[0x12];
+ out0[0x10* 5] = tmp + b1[0x16];
+ tmp = b1[0x1E] + b1[0x19];
+ out0[0x10* 3] = tmp + b1[0x16];
+ out0[0x10* 1] = tmp + b1[0x11];
+ tmp = b1[0x19] + b1[0x1D];
+ out1[0x10* 1] = tmp + b1[0x11];
+ out1[0x10* 3] = tmp + b1[0x15];
+ tmp = b1[0x1D] + b1[0x1B];
+ out1[0x10* 5] = tmp + b1[0x15];
+ out1[0x10* 7] = tmp + b1[0x13];
+ tmp = b1[0x1B] + b1[0x1F];
+ out1[0x10* 9] = tmp + b1[0x13];
+ out1[0x10*11] = tmp + b1[0x17];
+ out1[0x10*13] = b1[0x17] + b1[0x1F];
+ out1[0x10*15] = b1[0x1F];
+ }
+ return 0;
+}
+
+/*
+ * the call via dct64 is a trick to force GCC to use
+ * (new) registers for the b1,b2 pointer to the bufs[xx] field
+ */
+int mpeg3audio_dct64(mpeg3_real_t *a, mpeg3_real_t *b, mpeg3_real_t *c)
+{
+ mpeg3_real_t bufs[0x40];
+ return mpeg3audio_dct64_1(a, b, bufs, bufs + 0x20, c);
+}
+
+/*//////////////////////////////////////////////////////////////// */
+/* */
+/* 9 Point Inverse Discrete Cosine Transform */
+/* */
+/* This piece of code is Copyright 1997 Mikko Tommila and is freely usable */
+/* by anybody. The algorithm itself is of course in the public domain. */
+/* */
+/* Again derived heuristically from the 9-point WFTA. */
+/* */
+/* The algorithm is optimized (?) for speed, not for small rounding errors or */
+/* good readability. */
+/* */
+/* 36 additions, 11 multiplications */
+/* */
+/* Again this is very likely sub-optimal. */
+/* */
+/* The code is optimized to use a minimum number of temporary variables, */
+/* so it should compile quite well even on 8-register Intel x86 processors. */
+/* This makes the code quite obfuscated and very difficult to understand. */
+/* */
+/* References: */
+/* [1] S. Winograd: "On Computing the Discrete Fourier Transform", */
+/* Mathematics of Computation, Volume 32, Number 141, January 1978, */
+/* Pages 175-199 */
+
+
+/*------------------------------------------------------------------*/
+/* */
+/* Function: Calculation of the inverse MDCT */
+/* */
+/*------------------------------------------------------------------*/
+
+int mpeg3audio_dct36(mpeg3_real_t *inbuf, mpeg3_real_t *o1, mpeg3_real_t *o2, mpeg3_real_t *wintab, mpeg3_real_t *tsbuf)
+{
+ mpeg3_real_t tmp[18];
+
+ {
+ register mpeg3_real_t *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];
+
+
+ {
+ mpeg3_real_t t3;
+ {
+ mpeg3_real_t t0, t1, t2;
+
+ t0 = mpeg3_COS6_2 * (in[8] + in[16] - in[4]);
+ t1 = mpeg3_COS6_2 * in[12];
+
+ t3 = in[0];
+ t2 = t3 - t1 - t1;
+ tmp[1] = tmp[7] = t2 - t0;
+ tmp[4] = t2 + t0 + t0;
+ t3 += t1;
+
+ t2 = mpeg3_COS6_1 * (in[10] + in[14] - in[2]);
+ tmp[1] -= t2;
+ tmp[7] += t2;
+ }
+ {
+ mpeg3_real_t t0, t1, t2;
+
+ t0 = mpeg3_cos9[0] * (in[4] + in[8] );
+ t1 = mpeg3_cos9[1] * (in[8] - in[16]);
+ t2 = mpeg3_cos9[2] * (in[4] + in[16]);
+
+ tmp[2] = tmp[6] = t3 - t0 - t2;
+ tmp[0] = tmp[8] = t3 + t0 + t1;
+ tmp[3] = tmp[5] = t3 - t1 + t2;
+ }
+ }
+ {
+ mpeg3_real_t t1, t2, t3;
+
+ t1 = mpeg3_cos18[0] * (in[2] + in[10]);
+ t2 = mpeg3_cos18[1] * (in[10] - in[14]);
+ t3 = mpeg3_COS6_1 * in[6];
+
+ {
+ mpeg3_real_t t0 = t1 + t2 + t3;
+ tmp[0] += t0;
+ tmp[8] -= t0;
+ }
+
+ t2 -= t3;
+ t1 -= t3;
+
+ t3 = mpeg3_cos18[2] * (in[2] + in[14]);
+
+ t1 += t3;
+ tmp[3] += t1;
+ tmp[5] -= t1;
+
+ t2 -= t3;
+ tmp[2] += t2;
+ tmp[6] -= t2;
+ }
+
+
+ {
+ mpeg3_real_t t0, t1, t2, t3, t4, t5, t6, t7;
+
+ t1 = mpeg3_COS6_2 * in[13];
+ t2 = mpeg3_COS6_2 * (in[9] + in[17] - in[5]);
+
+ t3 = in[1] + t1;
+ t4 = in[1] - t1 - t1;
+ t5 = t4 - t2;
+
+ t0 = mpeg3_cos9[0] * (in[5] + in[9]);
+ t1 = mpeg3_cos9[1] * (in[9] - in[17]);
+
+ tmp[13] = (t4 + t2 + t2) * mpeg3_tfcos36[17-13];
+ t2 = mpeg3_cos9[2] * (in[5] + in[17]);
+
+ t6 = t3 - t0 - t2;
+ t0 += t3 + t1;
+ t3 += t2 - t1;
+
+ t2 = mpeg3_cos18[0] * (in[3] + in[11]);
+ t4 = mpeg3_cos18[1] * (in[11] - in[15]);
+ t7 = mpeg3_COS6_1 * in[7];
+
+ t1 = t2 + t4 + t7;
+ tmp[17] = (t0 + t1) * mpeg3_tfcos36[17-17];
+ tmp[9] = (t0 - t1) * mpeg3_tfcos36[17-9];
+ t1 = mpeg3_cos18[2] * (in[3] + in[15]);
+ t2 += t1 - t7;
+
+ tmp[14] = (t3 + t2) * mpeg3_tfcos36[17-14];
+ t0 = mpeg3_COS6_1 * (in[11] + in[15] - in[3]);
+ tmp[12] = (t3 - t2) * mpeg3_tfcos36[17-12];
+
+ t4 -= t1 + t7;
+
+ tmp[16] = (t5 - t0) * mpeg3_tfcos36[17-16];
+ tmp[10] = (t5 + t0) * mpeg3_tfcos36[17-10];
+ tmp[15] = (t6 + t4) * mpeg3_tfcos36[17-15];
+ tmp[11] = (t6 - t4) * mpeg3_tfcos36[17-11];
+ }
+
+#define MACRO(v) \
+ { \
+ mpeg3_real_t tmpval; \
+ tmpval = tmp[(v)] + tmp[17-(v)]; \
+ out2[9+(v)] = tmpval * w[27+(v)]; \
+ out2[8-(v)] = tmpval * w[26-(v)]; \
+ tmpval = tmp[(v)] - tmp[17-(v)]; \
+ ts[SBLIMIT*(8-(v))] = out1[8-(v)] + tmpval * w[8-(v)]; \
+ ts[SBLIMIT*(9+(v))] = out1[9+(v)] + tmpval * w[9+(v)]; \
+ }
+
+ {
+ register mpeg3_real_t *out2 = o2;
+ register mpeg3_real_t *w = wintab;
+ register mpeg3_real_t *out1 = o1;
+ register mpeg3_real_t *ts = tsbuf;
+
+ MACRO(0);
+ MACRO(1);
+ MACRO(2);
+ MACRO(3);
+ MACRO(4);
+ MACRO(5);
+ MACRO(6);
+ MACRO(7);
+ MACRO(8);
+ }
+ }
+ return 0;
+}
+
+/*
+ * new DCT12
+ */
+int mpeg3audio_dct12(mpeg3_real_t *in,mpeg3_real_t *rawout1,mpeg3_real_t *rawout2,register mpeg3_real_t *wi,register mpeg3_real_t *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 *= mpeg3_COS6_1; \
+ in3 *= mpeg3_COS6_1; \
+
+#define DCT12_PART2 \
+ in0 += in4 * mpeg3_COS6_2; \
+ \
+ in4 = in0 + in2; \
+ in0 -= in2; \
+ \
+ in1 += in5 * mpeg3_COS6_2; \
+ \
+ in5 = (in1 + in3) * mpeg3_tfcos12[0]; \
+ in1 = (in1 - in3) * mpeg3_tfcos12[2]; \
+ \
+ in3 = in4 + in5; \
+ in4 -= in5; \
+ \
+ in2 = in0 + in1; \
+ in0 -= in1;
+
+
+ {
+ mpeg3_real_t in0,in1,in2,in3,in4,in5;
+ register mpeg3_real_t *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
+
+ {
+ mpeg3_real_t tmp0,tmp1 = (in0 - in4);
+ {
+ mpeg3_real_t tmp2 = (in1 - in5) * mpeg3_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++;
+
+ {
+ mpeg3_real_t in0,in1,in2,in3,in4,in5;
+ register mpeg3_real_t *out2 = rawout2;
+
+ DCT12_PART1
+
+ {
+ mpeg3_real_t tmp0,tmp1 = (in0 - in4);
+ {
+ mpeg3_real_t tmp2 = (in1 - in5) * mpeg3_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++;
+
+ {
+ mpeg3_real_t in0,in1,in2,in3,in4,in5;
+ register mpeg3_real_t *out2 = rawout2;
+ out2[12]=out2[13]=out2[14]=out2[15]=out2[16]=out2[17]=0.0;
+
+ DCT12_PART1
+
+ {
+ mpeg3_real_t tmp0,tmp1 = (in0 - in4);
+ {
+ mpeg3_real_t tmp2 = (in1 - in5) * mpeg3_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];
+ }
+ return 0;
+}
+
+/* AC3 IMDCT tables */
+
+/* Twiddle factors for IMDCT */
+#if !defined(USE_FIXED_POINT) || defined(PRINT_FIXED_POINT_TABLES)
+static mpeg3_real_t mpeg3_xcos1[AC3_N / 4];
+static mpeg3_real_t mpeg3_xsin1[AC3_N / 4];
+static mpeg3_real_t mpeg3_xcos2[AC3_N / 8];
+static mpeg3_real_t mpeg3_xsin2[AC3_N / 8];
+#else
+#define USE_FP_TABLES
+#include "fptables.h"
+#endif
+
+/* 128 point bit-reverse LUT */
+static unsigned char mpeg3_bit_reverse_512[] =
+{
+ 0x00, 0x40, 0x20, 0x60, 0x10, 0x50, 0x30, 0x70,
+ 0x08, 0x48, 0x28, 0x68, 0x18, 0x58, 0x38, 0x78,
+ 0x04, 0x44, 0x24, 0x64, 0x14, 0x54, 0x34, 0x74,
+ 0x0c, 0x4c, 0x2c, 0x6c, 0x1c, 0x5c, 0x3c, 0x7c,
+ 0x02, 0x42, 0x22, 0x62, 0x12, 0x52, 0x32, 0x72,
+ 0x0a, 0x4a, 0x2a, 0x6a, 0x1a, 0x5a, 0x3a, 0x7a,
+ 0x06, 0x46, 0x26, 0x66, 0x16, 0x56, 0x36, 0x76,
+ 0x0e, 0x4e, 0x2e, 0x6e, 0x1e, 0x5e, 0x3e, 0x7e,
+ 0x01, 0x41, 0x21, 0x61, 0x11, 0x51, 0x31, 0x71,
+ 0x09, 0x49, 0x29, 0x69, 0x19, 0x59, 0x39, 0x79,
+ 0x05, 0x45, 0x25, 0x65, 0x15, 0x55, 0x35, 0x75,
+ 0x0d, 0x4d, 0x2d, 0x6d, 0x1d, 0x5d, 0x3d, 0x7d,
+ 0x03, 0x43, 0x23, 0x63, 0x13, 0x53, 0x33, 0x73,
+ 0x0b, 0x4b, 0x2b, 0x6b, 0x1b, 0x5b, 0x3b, 0x7b,
+ 0x07, 0x47, 0x27, 0x67, 0x17, 0x57, 0x37, 0x77,
+ 0x0f, 0x4f, 0x2f, 0x6f, 0x1f, 0x5f, 0x3f, 0x7f
+};
+
+static unsigned char mpeg3_bit_reverse_256[] =
+{
+ 0x00, 0x20, 0x10, 0x30, 0x08, 0x28, 0x18, 0x38,
+ 0x04, 0x24, 0x14, 0x34, 0x0c, 0x2c, 0x1c, 0x3c,
+ 0x02, 0x22, 0x12, 0x32, 0x0a, 0x2a, 0x1a, 0x3a,
+ 0x06, 0x26, 0x16, 0x36, 0x0e, 0x2e, 0x1e, 0x3e,
+ 0x01, 0x21, 0x11, 0x31, 0x09, 0x29, 0x19, 0x39,
+ 0x05, 0x25, 0x15, 0x35, 0x0d, 0x2d, 0x1d, 0x3d,
+ 0x03, 0x23, 0x13, 0x33, 0x0b, 0x2b, 0x1b, 0x3b,
+ 0x07, 0x27, 0x17, 0x37, 0x0f, 0x2f, 0x1f, 0x3f
+};
+
+/* Windowing function for Modified DCT - Thank you acroread */
+static mpeg3_real_t mpeg3_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
+};
+
+mpeg3_complex_t cmplx_mult(mpeg3_complex_t a, mpeg3_complex_t b)
+{
+ mpeg3_complex_t ret;
+
+ ret.real = a.real * b.real - a.imag * b.imag;
+ ret.imag = a.real * b.imag + a.imag * b.real;
+
+ return ret;
+}
+
+int mpeg3audio_imdct_init(mpeg3audio_t *audio)
+{
+ int i, k;
+ mpeg3_complex_t angle_step;
+ mpeg3_complex_t current_angle;
+
+/* Twiddle factors to turn IFFT into IMDCT */
+ for(i = 0; i < AC3_N / 4; i++)
+ {
+ mpeg3_xcos1[i] = -cos(2.0f * M_PI * (8 * i + 1 ) / ( 8 * AC3_N));
+ mpeg3_xsin1[i] = -sin(2.0f * M_PI * (8 * i + 1 ) / ( 8 * AC3_N));
+ }
+
+/* More twiddle factors to turn IFFT into IMDCT */
+ for(i = 0; i < AC3_N / 8; i++)
+ {
+ mpeg3_xcos2[i] = -cos(2.0f * M_PI * (8 * i + 1 ) / ( 4 * AC3_N));
+ mpeg3_xsin2[i] = -sin(2.0f * M_PI * (8 * i + 1 ) / ( 4 * AC3_N));
+ }
+
+/* Canonical twiddle factors for FFT */
+#if defined(USE_FIXED_POINT) && !defined(PRINT_FIXED_POINT_TABLES)
+ for(i = 0; i < 7; i++)
+ {
+ audio->ac3_w[i] = (mpeg3_complex_t*)ac3_w_fixedpoints[i];
+ }
+#else
+ audio->ac3_w[0] = audio->ac3_w_1;
+ audio->ac3_w[1] = audio->ac3_w_2;
+ audio->ac3_w[2] = audio->ac3_w_4;
+ audio->ac3_w[3] = audio->ac3_w_8;
+ audio->ac3_w[4] = audio->ac3_w_16;
+ audio->ac3_w[5] = audio->ac3_w_32;
+ audio->ac3_w[6] = audio->ac3_w_64;
+
+ for(i = 0; i < 7; i++)
+ {
+ angle_step.real = cos(-2.0f * M_PI / (1 << (i + 1)));
+ angle_step.imag = sin(-2.0f * M_PI / (1 << (i + 1)));
+
+ current_angle.real = 1.0f;
+ current_angle.imag = 0.0f;
+
+ for (k = 0; k < 1 << i; k++)
+ {
+ audio->ac3_w[i][k] = current_angle;
+ current_angle = cmplx_mult(current_angle, angle_step);
+ }
+ }
+
+#ifdef PRINT_FIXED_POINT_TABLES
+ printf("#ifdef USE_FP_TABLES\n");
+ printf("static long mpeg3_xcos1_fixedpoints[] = {");
+ for(i = 0; i < AC3_N / 4; i++) {
+ printf("%c0x%08x,", i%8?' ':'\n', mpeg3_xcos1[i].fixedPoint());
+ }
+ printf("\n};\nstatic mpeg3_real_t *mpeg3_xcos1 = \n"
+ "(mpeg3_real_t*)mpeg3_xcos1_fixedpoints;\n");
+
+ printf("static long mpeg3_xsin1_fixedpoints[] = {");
+ for(i = 0; i < AC3_N / 4; i++) {
+ printf("%c0x%08x,", i%8?' ':'\n', mpeg3_xsin1[i].fixedPoint());
+ }
+ printf("\n};\nstatic mpeg3_real_t *mpeg3_xsin1 = \n"
+ "(mpeg3_real_t*)mpeg3_xsin1_fixedpoints;\n");
+
+
+ printf("static long mpeg3_xcos2_fixedpoints[] = {");
+ for(i = 0; i < AC3_N / 4; i++) {
+ printf("%c0x%08x,", i%8?' ':'\n', mpeg3_xcos2[i].fixedPoint());
+ }
+ printf("\n};\nstatic mpeg3_real_t *mpeg3_xcos2 = \n"
+ "(mpeg3_real_t*)mpeg3_xcos2_fixedpoints;\n");
+
+ printf("static long mpeg3_xsin2_fixedpoints[] = {");
+ for(i = 0; i < AC3_N / 4; i++) {
+ printf("%c0x%08x,", i%8?' ':'\n', mpeg3_xsin2[i].fixedPoint());
+ }
+ printf("\n};\nstatic mpeg3_real_t *mpeg3_xsin2 = \n"
+ "(mpeg3_real_t*)mpeg3_xsin2_fixedpoints;\n");
+
+
+ printf("typedef struct { long r, i; } fixed_cmplx;\n");
+ for(i = 0; i < 7; i++)
+ {
+ printf("fixed_cmplx ac3_w_d%d[] = { ", 1<<i);
+ for (k = 0; k < 1 << i; k++)
+ {
+ printf("%s{ 0x%08x, 0x%08x },", k%4?" ":"\n ",
+ audio->ac3_w[i][k].real.fixedPoint(),
+ audio->ac3_w[i][k].imag.fixedPoint());
+ }
+ printf("};\n");
+ }
+
+ printf("fixed_cmplx *ac3_w_fixedpoints[] = {\n");
+ for(i = 0; i < 7; i++)
+ {
+ printf("ac3_w_d%d, ", 1<<i);
+ }
+ printf("};\n");
+ printf("#endif\n");
+#endif
+#endif
+
+ return 0;
+}
+
+
+inline void swap_cmplx(mpeg3_complex_t *a, mpeg3_complex_t *b)
+{
+ mpeg3_complex_t tmp;
+
+ tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+void mpeg3audio_ac3_imdct_do_512(mpeg3audio_t *audio,
+ mpeg3_real_t data[],
+ mpeg3_real_t *y,
+ int step,
+ mpeg3_real_t *delay)
+{
+ int i, k;
+ int p, q;
+ int m;
+ int two_m;
+ int two_m_plus_one;
+
+ mpeg3_real_t tmp_a_i;
+ mpeg3_real_t tmp_a_r;
+ mpeg3_real_t tmp_b_i;
+ mpeg3_real_t tmp_b_r;
+
+ mpeg3_real_t *y_ptr;
+ mpeg3_real_t *delay_ptr;
+ mpeg3_real_t *window_ptr;
+ mpeg3_complex_t *buf = audio->ac3_imdct_buf;
+
+/* Pre IFFT complex multiply plus IFFT cmplx conjugate */
+ for(i = 0; i < AC3_N / 4; i++)
+ {
+ buf[i].real = (data[AC3_N / 2 - 2 * i - 1] * mpeg3_xcos1[i]) - (data[2 * i] * mpeg3_xsin1[i]);
+ buf[i].imag = -((data[2 * i] * mpeg3_xcos1[i]) + (data[AC3_N / 2 - 2 * i - 1] * mpeg3_xsin1[i]));
+ }
+
+/* Bit reversed shuffling */
+ for(i = 0; i < AC3_N / 4; i++)
+ {
+ k = mpeg3_bit_reverse_512[i];
+ if(k < i)
+ swap_cmplx(&buf[i], &buf[k]);
+ }
+
+/* FFT Merge */
+ for(m = 0; m < 7; m++)
+ {
+ if(m)
+ two_m = (1 << m);
+ else
+ two_m = 1;
+
+ two_m_plus_one = (1 << (m + 1));
+
+ for(k = 0; k < two_m; k++)
+ {
+ for(i = 0; i < AC3_N / 4; i += two_m_plus_one)
+ {
+ p = k + i;
+ q = p + two_m;
+ tmp_a_r = buf[p].real;
+ tmp_a_i = buf[p].imag;
+ tmp_b_r = buf[q].real * audio->ac3_w[m][k].real - buf[q].imag * audio->ac3_w[m][k].imag;
+ tmp_b_i = buf[q].imag * audio->ac3_w[m][k].real + buf[q].real * audio->ac3_w[m][k].imag;
+ buf[p].real = tmp_a_r + tmp_b_r;
+ buf[p].imag = tmp_a_i + tmp_b_i;
+ buf[q].real = tmp_a_r - tmp_b_r;
+ buf[q].imag = tmp_a_i - tmp_b_i;
+ }
+ }
+ }
+
+/* Post IFFT complex multiply plus IFFT complex conjugate*/
+ for(i = 0; i < AC3_N / 4; i++)
+ {
+ tmp_a_r = buf[i].real;
+ tmp_a_i = -buf[i].imag;
+ buf[i].real = (tmp_a_r * mpeg3_xcos1[i]) - (tmp_a_i * mpeg3_xsin1[i]);
+ buf[i].imag = (tmp_a_r * mpeg3_xsin1[i]) + (tmp_a_i * mpeg3_xcos1[i]);
+ }
+
+ y_ptr = y;
+ delay_ptr = delay;
+ window_ptr = mpeg3_window;
+
+/* Window and convert to real valued signal */
+ for(i = 0; i < AC3_N / 8; i++)
+ {
+ *y_ptr = -buf[AC3_N / 8 + i].imag * *window_ptr++ + *delay_ptr++;
+ y_ptr += step;
+ *y_ptr = buf[AC3_N / 8 - i - 1].real * *window_ptr++ + *delay_ptr++;
+ y_ptr += step;
+ }
+
+ for(i = 0; i < AC3_N / 8; i++)
+ {
+ *y_ptr = -buf[i].real * *window_ptr++ + *delay_ptr++;
+ y_ptr += step;
+ *y_ptr = buf[AC3_N / 4 - i - 1].imag * *window_ptr++ + *delay_ptr++;
+ y_ptr += step;
+ }
+
+/* The trailing edge of the window goes into the delay line */
+ delay_ptr = delay;
+
+ for(i = 0; i < AC3_N / 8; i++)
+ {
+ *delay_ptr++ = -buf[AC3_N / 8 + i].real * *--window_ptr;
+ *delay_ptr++ = buf[AC3_N / 8 - i - 1].imag * *--window_ptr;
+ }
+
+ for(i = 0; i < AC3_N / 8; i++)
+ {
+ *delay_ptr++ = buf[i].imag * *--window_ptr;
+ *delay_ptr++ = -buf[AC3_N / 4 - i - 1].real * *--window_ptr;
+ }
+}
+
+void mpeg3audio_ac3_imdct_do_256(mpeg3audio_t *audio,
+ mpeg3_real_t data[],
+ mpeg3_real_t *y,
+ int step,
+ mpeg3_real_t *delay)
+{
+ int i, k;
+ int p, q;
+ int m;
+ int two_m;
+ int two_m_plus_one;
+ mpeg3_complex_t *buf = audio->ac3_imdct_buf;
+ mpeg3_real_t *y_ptr;
+ mpeg3_real_t *delay_ptr;
+ mpeg3_real_t *window_ptr;
+
+ mpeg3_real_t tmp_a_i;
+ mpeg3_real_t tmp_a_r;
+ mpeg3_real_t tmp_b_i;
+ mpeg3_real_t tmp_b_r;
+
+ mpeg3_complex_t *buf_1, *buf_2;
+
+ buf_1 = &buf[0];
+ buf_2 = &buf[64];
+
+/* Pre IFFT complex multiply plus IFFT cmplx conjugate */
+ for(k = 0; k < AC3_N / 8; k++)
+ {
+ p = 2 * (AC3_N / 4 - 2 * k - 1);
+ q = 2 * (2 * k);
+
+ buf_1[k].real = data[p] * mpeg3_xcos2[k] - data[q] * mpeg3_xsin2[k];
+ buf_1[k].imag = - (data[q] * mpeg3_xcos2[k] + data[p] * mpeg3_xsin2[k]);
+ buf_2[k].real = data[p + 1] * mpeg3_xcos2[k] - data[q + 1] * mpeg3_xsin2[k];
+ buf_2[k].imag = - (data[q + 1] * mpeg3_xcos2[k] + data[p + 1] * mpeg3_xsin2[k]);
+ }
+
+/* IFFT Bit reversed shuffling */
+ for(i = 0; i < AC3_N / 8; i++)
+ {
+ k = mpeg3_bit_reverse_256[i];
+ if(k < i)
+ {
+ swap_cmplx(&buf_1[i], &buf_1[k]);
+ swap_cmplx(&buf_2[i], &buf_2[k]);
+ }
+ }
+
+/* FFT Merge */
+ for(m = 0; m < 6; m++)
+ {
+ if(m)
+ two_m = (1 << m);
+ else
+ two_m = 1;
+
+ two_m_plus_one = (1 << (m + 1));
+
+ for(k = 0; k < two_m; k++)
+ {
+ for(i = 0; i < AC3_N / 8; i += two_m_plus_one)
+ {
+ p = k + i;
+ q = p + two_m;
+/* Do block 1 */
+ tmp_a_r = buf_1[p].real;
+ tmp_a_i = buf_1[p].imag;
+ tmp_b_r = buf_1[q].real * audio->ac3_w[m][k].real - buf_1[q].imag * audio->ac3_w[m][k].imag;
+ tmp_b_i = buf_1[q].imag * audio->ac3_w[m][k].real + buf_1[q].real * audio->ac3_w[m][k].imag;
+ buf_1[p].real = tmp_a_r + tmp_b_r;
+ buf_1[p].imag = tmp_a_i + tmp_b_i;
+ buf_1[q].real = tmp_a_r - tmp_b_r;
+ buf_1[q].imag = tmp_a_i - tmp_b_i;
+
+/* Do block 2 */
+ tmp_a_r = buf_2[p].real;
+ tmp_a_i = buf_2[p].imag;
+ tmp_b_r = buf_2[q].real * audio->ac3_w[m][k].real - buf_2[q].imag * audio->ac3_w[m][k].imag;
+ tmp_b_i = buf_2[q].imag * audio->ac3_w[m][k].real + buf_2[q].real * audio->ac3_w[m][k].imag;
+ buf_2[p].real = tmp_a_r + tmp_b_r;
+ buf_2[p].imag = tmp_a_i + tmp_b_i;
+ buf_2[q].real = tmp_a_r - tmp_b_r;
+ buf_2[q].imag = tmp_a_i - tmp_b_i;
+ }
+ }
+ }
+
+/* Post IFFT complex multiply */
+ for(i = 0; i < AC3_N / 8; i++)
+ {
+ tmp_a_r = buf_1[i].real;
+ tmp_a_i = -buf_1[i].imag;
+ buf_1[i].real = (tmp_a_r * mpeg3_xcos2[i]) - (tmp_a_i * mpeg3_xsin2[i]);
+ buf_1[i].imag = (tmp_a_r * mpeg3_xsin2[i]) + (tmp_a_i * mpeg3_xcos2[i]);
+ tmp_a_r = buf_2[i].real;
+ tmp_a_i = -buf_2[i].imag;
+ buf_2[i].real = (tmp_a_r * mpeg3_xcos2[i]) - (tmp_a_i * mpeg3_xsin2[i]);
+ buf_2[i].imag = (tmp_a_r * mpeg3_xsin2[i]) + (tmp_a_i * mpeg3_xcos2[i]);
+ }
+
+/* Window and convert to real valued signal */
+ y_ptr = y;
+ delay_ptr = delay;
+ window_ptr = mpeg3_window;
+
+ for(i = 0; i < AC3_N / 8; i++)
+ {
+ *y_ptr = -buf[AC3_N / 8 + i].imag * *window_ptr++ + *delay_ptr++;
+ y_ptr += step;
+ *y_ptr = buf[AC3_N / 8 - i - 1].real * *window_ptr++ + *delay_ptr++;
+ y_ptr += step;
+ }
+
+ for(i = 0; i < AC3_N / 8; i++)
+ {
+ *y_ptr = -buf[i].real * *window_ptr++ + *delay_ptr++;
+ y_ptr += step;
+ *y_ptr = buf[AC3_N / 4 - i - 1].imag * *window_ptr++ + *delay_ptr++;
+ y_ptr += step;
+ }
+
+/* The trailing edge of the window goes into the delay line */
+ delay_ptr = delay;
+
+ for(i = 0; i < AC3_N / 8; i++)
+ {
+ *delay_ptr++ = -buf[AC3_N / 8 + i].real * *--window_ptr;
+ *delay_ptr++ = buf[AC3_N / 8 - i - 1].imag * *--window_ptr;
+ }
+
+ for(i = 0; i < AC3_N / 8; i++)
+ {
+ *delay_ptr++ = buf[i].imag * *--window_ptr;
+ *delay_ptr++ = -buf[AC3_N / 4 - i - 1].real * *--window_ptr;
+ }
+}
+
+int mpeg3audio_ac3_imdct(mpeg3audio_t *audio,
+ mpeg3_ac3bsi_t *bsi,
+ mpeg3_ac3audblk_t *audblk,
+ mpeg3ac3_stream_samples_t samples)
+{
+ int i;
+
+ for(i = 0; i < bsi->nfchans; i++)
+ {
+ if(audblk->blksw[i])
+ mpeg3audio_ac3_imdct_do_256(audio,
+ samples[i],
+ audio->pcm_sample + audio->pcm_point + i,
+ bsi->nfchans,
+ audio->ac3_delay[i]);
+ else
+ mpeg3audio_ac3_imdct_do_512(audio,
+ samples[i],
+ audio->pcm_sample + audio->pcm_point + i,
+ bsi->nfchans,
+ audio->ac3_delay[i]);
+ }
+ audio->pcm_point += AC3_N / 2 * bsi->nfchans;
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/exponents.c b/core/multimedia/opieplayer/libmpeg3/audio/exponents.c
new file mode 100644
index 0000000..deda9b9
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/exponents.c
@@ -0,0 +1,141 @@
+/*
+ *
+ * exponents.c Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of libmpeg3
+ *
+ * libmpeg3 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.
+ *
+ * libmpeg3 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 "mpeg3audio.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include <stdio.h>
+
+/* Exponent defines */
+#define UNPACK_FBW 1
+#define UNPACK_CPL 2
+#define UNPACK_LFE 4
+
+static inline int mpeg3audio_ac3_exp_unpack_ch(unsigned int type,
+ unsigned int expstr,
+ unsigned int ngrps,
+ unsigned int initial_exp,
+ unsigned short exps[],
+ unsigned short *dest)
+{
+ int i, j;
+ int exp_acc;
+ int exp_1, exp_2, exp_3;
+
+ if(expstr == MPEG3_EXP_REUSE)
+ return 0;
+
+/* Handle the initial absolute exponent */
+ exp_acc = initial_exp;
+ j = 0;
+
+/* In the case of a fbw channel then the initial absolute value 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)
+ {
+ fprintf(stderr, "mpeg3audio_ac3_exp_unpack_ch: Invalid exponent %d\n", exps[i]);
+ return 1;
+ }
+
+ exp_1 = exps[i] / 25;
+ exp_2 = (exps[i] % 25) / 5;
+ exp_3 = (exps[i] % 25) % 5;
+
+ exp_acc += (exp_1 - 2);
+
+ switch(expstr)
+ {
+ case MPEG3_EXP_D45:
+ dest[j++] = exp_acc;
+ dest[j++] = exp_acc;
+ case MPEG3_EXP_D25:
+ dest[j++] = exp_acc;
+ case MPEG3_EXP_D15:
+ dest[j++] = exp_acc;
+ }
+
+ exp_acc += (exp_2 - 2);
+
+ switch(expstr)
+ {
+ case MPEG3_EXP_D45:
+ dest[j++] = exp_acc;
+ dest[j++] = exp_acc;
+ case MPEG3_EXP_D25:
+ dest[j++] = exp_acc;
+ case MPEG3_EXP_D15:
+ dest[j++] = exp_acc;
+ }
+
+ exp_acc += (exp_3 - 2);
+
+ switch(expstr)
+ {
+ case MPEG3_EXP_D45:
+ dest[j++] = exp_acc;
+ dest[j++] = exp_acc;
+ case MPEG3_EXP_D25:
+ dest[j++] = exp_acc;
+ case MPEG3_EXP_D15:
+ dest[j++] = exp_acc;
+ }
+ }
+ return 0;
+}
+
+int mpeg3audio_ac3_exponent_unpack(mpeg3audio_t *audio,
+ mpeg3_ac3bsi_t *bsi,
+ mpeg3_ac3audblk_t *audblk)
+{
+ int i, result = 0;
+
+ for(i = 0; i < bsi->nfchans; i++)
+ result |= mpeg3audio_ac3_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 && !result)
+ result |= mpeg3audio_ac3_exp_unpack_ch(UNPACK_CPL,
+ audblk->cplexpstr,
+ audblk->ncplgrps,
+ audblk->cplabsexp << 1,
+ audblk->cplexps,
+ &audblk->cpl_exp[audblk->cplstrtmant]);
+
+ if(bsi->lfeon && !result)
+ result |= mpeg3audio_ac3_exp_unpack_ch(UNPACK_LFE,
+ audblk->lfeexpstr,
+ 2,
+ audblk->lfeexps[0],
+ &audblk->lfeexps[1],
+ audblk->lfe_exp);
+ return result;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/fptables.h b/core/multimedia/opieplayer/libmpeg3/audio/fptables.h
new file mode 100644
index 0000000..2836984
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/fptables.h
@@ -0,0 +1,1556 @@
+#ifdef USE_FP_TABLES
+static long mpeg3_xcos1_fixedpoints[] = {
+0xffff8001, 0xffff8004, 0xffff800c, 0xffff8019, 0xffff802a, 0xffff8041, 0xffff805d, 0xffff807e,
+0xffff80a3, 0xffff80ce, 0xffff80fd, 0xffff8131, 0xffff816b, 0xffff81a9, 0xffff81ec, 0xffff8233,
+0xffff8280, 0xffff82d1, 0xffff8328, 0xffff8383, 0xffff83e3, 0xffff8447, 0xffff84b1, 0xffff851f,
+0xffff8592, 0xffff860a, 0xffff8686, 0xffff8707, 0xffff878d, 0xffff8817, 0xffff88a6, 0xffff893a,
+0xffff89d2, 0xffff8a6f, 0xffff8b10, 0xffff8bb6, 0xffff8c60, 0xffff8d0f, 0xffff8dc2, 0xffff8e7a,
+0xffff8f35, 0xffff8ff6, 0xffff90ba, 0xffff9183, 0xffff9250, 0xffff9322, 0xffff93f7, 0xffff94d1,
+0xffff95af, 0xffff9691, 0xffff9777, 0xffff9861, 0xffff994f, 0xffff9a41, 0xffff9b37, 0xffff9c31,
+0xffff9d2e, 0xffff9e30, 0xffff9f35, 0xffffa03e, 0xffffa14b, 0xffffa25b, 0xffffa36f, 0xffffa487,
+0xffffa5a2, 0xffffa6c0, 0xffffa7e2, 0xffffa907, 0xffffaa30, 0xffffab5c, 0xffffac8b, 0xffffadbe,
+0xffffaef4, 0xffffb02c, 0xffffb168, 0xffffb2a7, 0xffffb3e9, 0xffffb52e, 0xffffb676, 0xffffb7c0,
+0xffffb90d, 0xffffba5d, 0xffffbbb0, 0xffffbd06, 0xffffbe5e, 0xffffbfb8, 0xffffc115, 0xffffc274,
+0xffffc3d6, 0xffffc53a, 0xffffc6a1, 0xffffc809, 0xffffc974, 0xffffcae1, 0xffffcc50, 0xffffcdc0,
+0xffffcf33, 0xffffd0a8, 0xffffd21e, 0xffffd397, 0xffffd511, 0xffffd68c, 0xffffd80a, 0xffffd988,
+0xffffdb09, 0xffffdc8a, 0xffffde0d, 0xffffdf92, 0xffffe117, 0xffffe29e, 0xffffe426, 0xffffe5af,
+0xffffe739, 0xffffe8c4, 0xffffea50, 0xffffebdd, 0xffffed6a, 0xffffeef8, 0xfffff087, 0xfffff217,
+0xfffff3a7, 0xfffff537, 0xfffff6c8, 0xfffff859, 0xfffff9eb, 0xfffffb7d, 0xfffffd0f, 0xfffffea1,
+};
+static mpeg3_real_t *mpeg3_xcos1 =
+(mpeg3_real_t*)mpeg3_xcos1_fixedpoints;
+static long mpeg3_xsin1_fixedpoints[] = {
+0xffffffce, 0xfffffe3c, 0xfffffcaa, 0xfffffb18, 0xfffff986, 0xfffff7f5, 0xfffff664, 0xfffff4d3,
+0xfffff343, 0xfffff1b3, 0xfffff023, 0xffffee95, 0xffffed07, 0xffffeb79, 0xffffe9ed, 0xffffe861,
+0xffffe6d6, 0xffffe54d, 0xffffe3c4, 0xffffe23c, 0xffffe0b6, 0xffffdf30, 0xffffddac, 0xffffdc2a,
+0xffffdaa8, 0xffffd928, 0xffffd7aa, 0xffffd62d, 0xffffd4b2, 0xffffd338, 0xffffd1c1, 0xffffd04b,
+0xffffced6, 0xffffcd64, 0xffffcbf4, 0xffffca85, 0xffffc919, 0xffffc7af, 0xffffc647, 0xffffc4e1,
+0xffffc37d, 0xffffc21c, 0xffffc0bd, 0xffffbf61, 0xffffbe07, 0xffffbcb0, 0xffffbb5b, 0xffffba09,
+0xffffb8ba, 0xffffb76d, 0xffffb623, 0xffffb4dc, 0xffffb398, 0xffffb257, 0xffffb119, 0xffffafde,
+0xffffaea6, 0xffffad71, 0xffffac3f, 0xffffab11, 0xffffa9e6, 0xffffa8be, 0xffffa799, 0xffffa678,
+0xffffa55b, 0xffffa440, 0xffffa32a, 0xffffa217, 0xffffa107, 0xffff9ffc, 0xffff9ef3, 0xffff9def,
+0xffff9cef, 0xffff9bf2, 0xffff9af9, 0xffff9a04, 0xffff9913, 0xffff9826, 0xffff973d, 0xffff9658,
+0xffff9577, 0xffff949a, 0xffff93c1, 0xffff92ed, 0xffff921d, 0xffff9151, 0xffff9089, 0xffff8fc5,
+0xffff8f06, 0xffff8e4b, 0xffff8d95, 0xffff8ce3, 0xffff8c35, 0xffff8b8c, 0xffff8ae7, 0xffff8a47,
+0xffff89ac, 0xffff8915, 0xffff8882, 0xffff87f4, 0xffff876b, 0xffff86e7, 0xffff8667, 0xffff85eb,
+0xffff8575, 0xffff8503, 0xffff8496, 0xffff842e, 0xffff83ca, 0xffff836c, 0xffff8312, 0xffff82bd,
+0xffff826c, 0xffff8221, 0xffff81da, 0xffff8199, 0xffff815c, 0xffff8124, 0xffff80f1, 0xffff80c3,
+0xffff8099, 0xffff8075, 0xffff8056, 0xffff803b, 0xffff8026, 0xffff8015, 0xffff8009, 0xffff8002,
+};
+static mpeg3_real_t *mpeg3_xsin1 =
+(mpeg3_real_t*)mpeg3_xsin1_fixedpoints;
+static long mpeg3_xcos2_fixedpoints[] = {
+0xffff8001, 0xffff800d, 0xffff802d, 0xffff8061, 0xffff80a8, 0xffff8103, 0xffff8172, 0xffff81f4,
+0xffff828a, 0xffff8333, 0xffff83ef, 0xffff84be, 0xffff85a1, 0xffff8696, 0xffff879e, 0xffff88b9,
+0xffff89e5, 0xffff8b25, 0xffff8c76, 0xffff8dd9, 0xffff8f4d, 0xffff90d3, 0xffff926a, 0xffff9412,
+0xffff95cb, 0xffff9794, 0xffff996d, 0xffff9b56, 0xffff9d4e, 0xffff9f56, 0xffffa16d, 0xffffa392,
+0xffffa5c5, 0xffffa807, 0xffffaa55, 0xffffacb2, 0xffffaf1b, 0xffffb190, 0xffffb411, 0xffffb69f,
+0xffffb937, 0xffffbbdb, 0xffffbe89, 0xffffc141, 0xffffc403, 0xffffc6ce, 0xffffc9a1, 0xffffcc7e,
+0xffffcf62, 0xffffd24d, 0xffffd540, 0xffffd839, 0xffffdb39, 0xffffde3e, 0xffffe148, 0xffffe457,
+0xffffe76a, 0xffffea81, 0xffffed9c, 0xfffff0b9, 0xfffff3d9, 0xfffff6fa, 0xfffffa1d, 0xfffffd41,
+0xffffff9c, 0xfffffc78, 0xfffff954, 0xfffff632, 0xfffff311, 0xffffeff2, 0xffffecd5, 0xffffe9bb,
+0xffffe6a5, 0xffffe393, 0xffffe085, 0xffffdd7c, 0xffffda78, 0xffffd77a, 0xffffd483, 0xffffd192,
+0xffffcea8, 0xffffcbc6, 0xffffc8ec, 0xffffc61a, 0xffffc351, 0xffffc092, 0xffffbddc, 0xffffbb31,
+0xffffb890, 0xffffb5fa, 0xffffb370, 0xffffb0f1, 0xffffae7f, 0xffffac19, 0xffffa9c0, 0xffffa775,
+0xffffa537, 0xffffa307, 0xffffa0e6, 0xffff9ed3, 0xffff9ccf, 0xffff9ada, 0xffff98f5, 0xffff9720,
+0xffff955b, 0xffff93a7, 0xffff9203, 0xffff9070, 0xffff8eee, 0xffff8d7e, 0xffff8c20, 0xffff8ad3,
+0xffff8998, 0xffff8870, 0xffff875a, 0xffff8657, 0xffff8566, 0xffff8489, 0xffff83be, 0xffff8307,
+0xffff8263, 0xffff81d2, 0xffff8155, 0xffff80eb, 0xffff8095, 0xffff8052, 0xffff8023, 0xffff8008,
+};
+static mpeg3_real_t *mpeg3_xcos2 =
+(mpeg3_real_t*)mpeg3_xcos2_fixedpoints;
+static long mpeg3_xsin2_fixedpoints[] = {
+0xffffff9c, 0xfffffc78, 0xfffff954, 0xfffff632, 0xfffff311, 0xffffeff2, 0xffffecd5, 0xffffe9bb,
+0xffffe6a5, 0xffffe393, 0xffffe085, 0xffffdd7c, 0xffffda78, 0xffffd77a, 0xffffd483, 0xffffd192,
+0xffffcea8, 0xffffcbc6, 0xffffc8ec, 0xffffc61a, 0xffffc351, 0xffffc092, 0xffffbddc, 0xffffbb31,
+0xffffb890, 0xffffb5fa, 0xffffb370, 0xffffb0f1, 0xffffae7f, 0xffffac19, 0xffffa9c0, 0xffffa775,
+0xffffa537, 0xffffa307, 0xffffa0e6, 0xffff9ed3, 0xffff9ccf, 0xffff9ada, 0xffff98f5, 0xffff9720,
+0xffff955b, 0xffff93a7, 0xffff9203, 0xffff9070, 0xffff8eee, 0xffff8d7e, 0xffff8c20, 0xffff8ad3,
+0xffff8998, 0xffff8870, 0xffff875a, 0xffff8657, 0xffff8566, 0xffff8489, 0xffff83be, 0xffff8307,
+0xffff8263, 0xffff81d2, 0xffff8155, 0xffff80eb, 0xffff8095, 0xffff8052, 0xffff8023, 0xffff8008,
+0x00000004, 0x00000007, 0x0000000c, 0x00000010, 0x00000015, 0x0000001c, 0x00000023, 0x0000002a,
+0x00000033, 0x0000003d, 0x00000048, 0x00000053, 0x00000061, 0x0000006f, 0x0000007f, 0x00000091,
+0x000000a4, 0x000000b8, 0x000000cf, 0x000000e7, 0x00000101, 0x0000011d, 0x0000013b, 0x0000015b,
+0x0000017e, 0x000001a3, 0x000001ca, 0x000001f4, 0x00000220, 0x0000024f, 0x00000281, 0x000002b7,
+0x000002ef, 0x0000032a, 0x00000368, 0x000003aa, 0x000003ee, 0x00000437, 0x00000483, 0x000004d3,
+0x00000526, 0x0000057e, 0x000005d9, 0x00000639, 0x0000069c, 0x00000704, 0x0000076f, 0x000007e0,
+0x00000854, 0x000008cd, 0x0000094b, 0x000009cd, 0x00000a54, 0x00000adf, 0x00000b6f, 0x00000c04,
+0x00000c9e, 0x00000d3d, 0x00000de0, 0x00000e89, 0x00000f36, 0x00000fe8, 0x0000109f, 0x0000115c,
+};
+static mpeg3_real_t *mpeg3_xsin2 =
+(mpeg3_real_t*)mpeg3_xsin2_fixedpoints;
+typedef struct { long r, i; } fixed_cmplx;
+fixed_cmplx ac3_w_d1[] = {
+ { 0x00008000, 0x00000000 },};
+fixed_cmplx ac3_w_d2[] = {
+ { 0x00008000, 0x00000000 }, { 0x00000000, 0xffff8000 },};
+fixed_cmplx ac3_w_d4[] = {
+ { 0x00008000, 0x00000000 }, { 0x00005a82, 0xffffa57e }, { 0x00000000, 0xffff8002 }, { 0xffffa580, 0xffffa580 },};
+fixed_cmplx ac3_w_d8[] = {
+ { 0x00008000, 0x00000000 }, { 0x00007641, 0xffffcf05 }, { 0x00005a81, 0xffffa580 }, { 0x000030fb, 0xffff89c4 },
+ { 0x00000002, 0xffff8007 }, { 0xffffcf09, 0xffff89c6 }, { 0xffffa587, 0xffffa583 }, { 0xffff89cb, 0xffffcf05 },};
+fixed_cmplx ac3_w_d16[] = {
+ { 0x00008000, 0x00000000 }, { 0x00007d8a, 0xffffe708 }, { 0x00007642, 0xffffcf06 }, { 0x00006a6e, 0xffffb8e7 },
+ { 0x00005a84, 0xffffa583 }, { 0x00004720, 0xffff9599 }, { 0x00003100, 0xffff89c6 }, { 0x000018ff, 0xffff827e },
+ { 0x00000008, 0xffff8008 }, { 0xffffe711, 0xffff827d }, { 0xffffcf11, 0xffff89c4 }, { 0xffffb8f2, 0xffff9595 },
+ { 0xffffa58e, 0xffffa57d }, { 0xffff95a5, 0xffffb8df }, { 0xffff89d2, 0xffffcefd }, { 0xffff8289, 0xffffe6fc },};
+fixed_cmplx ac3_w_d32[] = {
+ { 0x00008000, 0x00000000 }, { 0x00007f62, 0xfffff375 }, { 0x00007d8a, 0xffffe70a }, { 0x00007a7d, 0xffffdadc },
+ { 0x00007642, 0xffffcf0a }, { 0x000070e4, 0xffffc3b1 }, { 0x00006a70, 0xffffb8ed }, { 0x000062f6, 0xffffaed7 },
+ { 0x00005a88, 0xffffa58a }, { 0x0000513b, 0xffff9d1b }, { 0x00004726, 0xffff95a1 }, { 0x00003c62, 0xffff8f2d },
+ { 0x00003109, 0xffff89cf }, { 0x00002538, 0xffff8593 }, { 0x0000190b, 0xffff8286 }, { 0x00000ca1, 0xffff80ad },
+ { 0x00000017, 0xffff800f }, { 0xfffff38d, 0xffff80ab }, { 0xffffe723, 0xffff8281 }, { 0xffffdaf6, 0xffff858b },
+ { 0xffffcf25, 0xffff89c4 }, { 0xffffc3cc, 0xffff8f1f }, { 0xffffb908, 0xffff9591 }, { 0xffffaef3, 0xffff9d09 },
+ { 0xffffa5a6, 0xffffa575 }, { 0xffff9d37, 0xffffaebf }, { 0xffff95bb, 0xffffb8d2 }, { 0xffff8f46, 0xffffc393 },
+ { 0xffff89e7, 0xffffcee9 }, { 0xffff85aa, 0xffffdab8 }, { 0xffff829b, 0xffffe6e3 }, { 0xffff80c1, 0xfffff34b },};
+fixed_cmplx ac3_w_d64[] = {
+ { 0x00008000, 0x00000000 }, { 0x00007fd8, 0xfffff9b9 }, { 0x00007f62, 0xfffff376 }, { 0x00007e9d, 0xffffed3b },
+ { 0x00007d8a, 0xffffe70c }, { 0x00007c29, 0xffffe0ec }, { 0x00007a7c, 0xffffdae0 }, { 0x00007883, 0xffffd4eb },
+ { 0x00007641, 0xffffcf11 }, { 0x000073b6, 0xffffc955 }, { 0x000070e3, 0xffffc3bb }, { 0x00006dcb, 0xffffbe45 },
+ { 0x00006a6f, 0xffffb8f8 }, { 0x000066d2, 0xffffb3d7 }, { 0x000062f5, 0xffffaee5 }, { 0x00005edc, 0xffffaa25 },
+ { 0x00005a89, 0xffffa59a }, { 0x000055fe, 0xffffa147 }, { 0x0000513e, 0xffff9d2e }, { 0x00004c4c, 0xffff9952 },
+ { 0x0000472b, 0xffff95b6 }, { 0x000041de, 0xffff925b }, { 0x00003c69, 0xffff8f44 }, { 0x000036cf, 0xffff8c72 },
+ { 0x00003113, 0xffff89e7 }, { 0x00002b39, 0xffff87a4 }, { 0x00002544, 0xffff85ac }, { 0x00001f39, 0xffff8400 },
+ { 0x0000191b, 0xffff82a0 }, { 0x000012ed, 0xffff818d }, { 0x00000cb4, 0xffff80c8 }, { 0x00000673, 0xffff8051 },
+ { 0x0000002d, 0xffff8029 }, { 0xfffff9e8, 0xffff804f }, { 0xfffff3a7, 0xffff80c3 }, { 0xffffed6e, 0xffff8186 },
+ { 0xffffe741, 0xffff8297 }, { 0xffffe123, 0xffff83f5 }, { 0xffffdb18, 0xffff859f }, { 0xffffd524, 0xffff8795 },
+ { 0xffffcf4b, 0xffff89d5 }, { 0xffffc990, 0xffff8c5d }, { 0xffffc3f7, 0xffff8f2d }, { 0xffffbe82, 0xffff9242 },
+ { 0xffffb936, 0xffff959b }, { 0xffffb416, 0xffff9935 }, { 0xffffaf24, 0xffff9d0f }, { 0xffffaa64, 0xffffa125 },
+ { 0xffffa5d9, 0xffffa575 }, { 0xffffa186, 0xffffa9fd }, { 0xffff9d6d, 0xffffaeba }, { 0xffff9990, 0xffffb3a9 },
+ { 0xffff95f3, 0xffffb8c7 }, { 0xffff9297, 0xffffbe11 }, { 0xffff8f7f, 0xffffc383 }, { 0xffff8cac, 0xffffc91a },
+ { 0xffff8a20, 0xffffced3 }, { 0xffff87dc, 0xffffd4aa }, { 0xffff85e2, 0xffffda9c }, { 0xffff8434, 0xffffe0a5 },
+ { 0xffff82d2, 0xffffe6c1 }, { 0xffff81be, 0xffffecec }, { 0xffff80f7, 0xfffff323 }, { 0xffff807e, 0xfffff962 },};
+fixed_cmplx *ac3_w_fixedpoints[] = {
+ac3_w_d1, ac3_w_d2, ac3_w_d4, ac3_w_d8, ac3_w_d16, ac3_w_d32, ac3_w_d64, };
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_muls_data[] = {
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xffff5556, 0xffff788b, 0xffff947d, 0xffffaaab, 0xffffbc46, 0xffffca3f, 0xffffd556, 0xffffde23,
+0xffffe520, 0xffffeaab, 0xffffef12, 0xfffff290, 0xfffff556, 0xfffff789, 0xfffff948, 0xfffffaab,
+0xfffffbc5, 0xfffffca4, 0xfffffd56, 0xfffffde3, 0xfffffe52, 0xfffffeab, 0xfffffef2, 0xffffff29,
+0xffffff56, 0xffffff79, 0xffffff95, 0xffffffab, 0xffffffbd, 0xffffffcb, 0xffffffd6, 0xffffffdf,
+0xffffffe6, 0xffffffeb, 0xfffffff0, 0xfffffff3, 0xfffffff6, 0xfffffff8, 0xfffffffa, 0xfffffffb,
+0xfffffffc, 0xfffffffd, 0xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x0000aaaa, 0x00008775, 0x00006b83, 0x00005555, 0x000043ba, 0x000035c1, 0x00002aaa, 0x000021dd,
+0x00001ae0, 0x00001555, 0x000010ee, 0x00000d70, 0x00000aaa, 0x00000877, 0x000006b8, 0x00000555,
+0x0000043b, 0x0000035c, 0x000002aa, 0x0000021d, 0x000001ae, 0x00000155, 0x0000010e, 0x000000d7,
+0x000000aa, 0x00000087, 0x0000006b, 0x00000055, 0x00000043, 0x00000035, 0x0000002a, 0x00000021,
+0x0000001a, 0x00000015, 0x00000010, 0x0000000d, 0x0000000a, 0x00000008, 0x00000006, 0x00000005,
+0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00004924, 0x00003a0d, 0x00002e13, 0x00002492, 0x00001d06, 0x00001709, 0x00001249, 0x00000e83,
+0x00000b84, 0x00000924, 0x00000741, 0x000005c2, 0x00000492, 0x000003a0, 0x000002e1, 0x00000249,
+0x000001d0, 0x00000170, 0x00000124, 0x000000e8, 0x000000b8, 0x00000092, 0x00000074, 0x0000005c,
+0x00000049, 0x0000003a, 0x0000002e, 0x00000024, 0x0000001d, 0x00000017, 0x00000012, 0x0000000e,
+0x0000000b, 0x00000009, 0x00000007, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002,
+0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00002222, 0x00001b17, 0x00001580, 0x00001111, 0x00000d8b, 0x00000ac0, 0x00000888, 0x000006c5,
+0x00000560, 0x00000444, 0x00000362, 0x000002b0, 0x00000222, 0x000001b1, 0x00000158, 0x00000111,
+0x000000d8, 0x000000ac, 0x00000088, 0x0000006c, 0x00000056, 0x00000044, 0x00000036, 0x0000002b,
+0x00000022, 0x0000001b, 0x00000015, 0x00000011, 0x0000000d, 0x0000000a, 0x00000008, 0x00000006,
+0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00001084, 0x00000d1b, 0x00000a67, 0x00000842, 0x0000068d, 0x00000533, 0x00000421, 0x00000346,
+0x00000299, 0x00000210, 0x000001a3, 0x0000014c, 0x00000108, 0x000000d1, 0x000000a6, 0x00000084,
+0x00000068, 0x00000053, 0x00000042, 0x00000034, 0x00000029, 0x00000021, 0x0000001a, 0x00000014,
+0x00000010, 0x0000000d, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003,
+0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000820, 0x00000673, 0x0000051e, 0x00000410, 0x00000339, 0x0000028f, 0x00000208, 0x0000019c,
+0x00000147, 0x00000104, 0x000000ce, 0x000000a3, 0x00000082, 0x00000067, 0x00000051, 0x00000041,
+0x00000033, 0x00000028, 0x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a,
+0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001,
+0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000408, 0x00000333, 0x0000028a, 0x00000204, 0x00000199, 0x00000145, 0x00000102, 0x000000cc,
+0x000000a2, 0x00000081, 0x00000066, 0x00000051, 0x00000040, 0x00000033, 0x00000028, 0x00000020,
+0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005,
+0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000202, 0x00000197, 0x00000143, 0x00000101, 0x000000cb, 0x000000a1, 0x00000080, 0x00000065,
+0x00000050, 0x00000040, 0x00000032, 0x00000028, 0x00000020, 0x00000019, 0x00000014, 0x00000010,
+0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002,
+0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000100, 0x000000cb, 0x000000a1, 0x00000080, 0x00000065, 0x00000050, 0x00000040, 0x00000032,
+0x00000028, 0x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008,
+0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001,
+0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000080, 0x00000065, 0x00000050, 0x00000040, 0x00000032, 0x00000028, 0x00000020, 0x00000019,
+0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004,
+0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000040, 0x00000032, 0x00000028, 0x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c,
+0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002,
+0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006,
+0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003,
+0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001,
+0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xffff3334, 0xffff5d74, 0xffff7efc, 0xffff999a, 0xffffaeba, 0xffffbf7e, 0xffffcccd, 0xffffd75d,
+0xffffdfbf, 0xffffe667, 0xffffebaf, 0xffffefe0, 0xfffff334, 0xfffff5d8, 0xfffff7f0, 0xfffff99a,
+0xfffffaec, 0xfffffbf8, 0xfffffccd, 0xfffffd76, 0xfffffdfc, 0xfffffe67, 0xfffffebb, 0xfffffefe,
+0xffffff34, 0xffffff5e, 0xffffff7f, 0xffffff9a, 0xffffffaf, 0xffffffc0, 0xffffffcd, 0xffffffd8,
+0xffffffe0, 0xffffffe7, 0xffffffec, 0xfffffff0, 0xfffffff4, 0xfffffff6, 0xfffffff8, 0xfffffffa,
+0xfffffffb, 0xfffffffc, 0xfffffffd, 0xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xffff999a, 0xffffaeba, 0xffffbf7e, 0xffffcccd, 0xffffd75d, 0xffffdfbf, 0xffffe667, 0xffffebaf,
+0xffffefe0, 0xfffff334, 0xfffff5d8, 0xfffff7f0, 0xfffff99a, 0xfffffaec, 0xfffffbf8, 0xfffffccd,
+0xfffffd76, 0xfffffdfc, 0xfffffe67, 0xfffffebb, 0xfffffefe, 0xffffff34, 0xffffff5e, 0xffffff7f,
+0xffffff9a, 0xffffffaf, 0xffffffc0, 0xffffffcd, 0xffffffd8, 0xffffffe0, 0xffffffe7, 0xffffffec,
+0xfffffff0, 0xfffffff4, 0xfffffff6, 0xfffffff8, 0xfffffffa, 0xfffffffb, 0xfffffffc, 0xfffffffd,
+0xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00006666, 0x00005146, 0x00004082, 0x00003333, 0x000028a3, 0x00002041, 0x00001999, 0x00001451,
+0x00001020, 0x00000ccc, 0x00000a28, 0x00000810, 0x00000666, 0x00000514, 0x00000408, 0x00000333,
+0x0000028a, 0x00000204, 0x00000199, 0x00000145, 0x00000102, 0x000000cc, 0x000000a2, 0x00000081,
+0x00000066, 0x00000051, 0x00000040, 0x00000033, 0x00000028, 0x00000020, 0x00000019, 0x00000014,
+0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006, 0x00000005, 0x00000004, 0x00000003,
+0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x0000cccc, 0x0000a28c, 0x00008104, 0x00006666, 0x00005146, 0x00004082, 0x00003333, 0x000028a3,
+0x00002041, 0x00001999, 0x00001451, 0x00001020, 0x00000ccc, 0x00000a28, 0x00000810, 0x00000666,
+0x00000514, 0x00000408, 0x00000333, 0x0000028a, 0x00000204, 0x00000199, 0x00000145, 0x00000102,
+0x000000cc, 0x000000a2, 0x00000081, 0x00000066, 0x00000051, 0x00000040, 0x00000033, 0x00000028,
+0x00000020, 0x00000019, 0x00000014, 0x00000010, 0x0000000c, 0x0000000a, 0x00000008, 0x00000006,
+0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xffff1c72, 0xffff4b64, 0xffff70a7, 0xffff8e39, 0xffffa5b2, 0xffffb854, 0xffffc71d, 0xffffd2d9,
+0xffffdc2a, 0xffffe38f, 0xffffe96d, 0xffffee15, 0xfffff1c8, 0xfffff4b7, 0xfffff70b, 0xfffff8e4,
+0xfffffa5c, 0xfffffb86, 0xfffffc72, 0xfffffd2e, 0xfffffdc3, 0xfffffe39, 0xfffffe97, 0xfffffee2,
+0xffffff1d, 0xffffff4c, 0xffffff71, 0xffffff8f, 0xffffffa6, 0xffffffb9, 0xffffffc8, 0xffffffd3,
+0xffffffdd, 0xffffffe4, 0xffffffea, 0xffffffef, 0xfffffff2, 0xfffffff5, 0xfffffff8, 0xfffffff9,
+0xfffffffb, 0xfffffffc, 0xfffffffd, 0xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xffff8e39, 0xffffa5b2, 0xffffb854, 0xffffc71d, 0xffffd2d9, 0xffffdc2a, 0xffffe38f, 0xffffe96d,
+0xffffee15, 0xfffff1c8, 0xfffff4b7, 0xfffff70b, 0xfffff8e4, 0xfffffa5c, 0xfffffb86, 0xfffffc72,
+0xfffffd2e, 0xfffffdc3, 0xfffffe39, 0xfffffe97, 0xfffffee2, 0xffffff1d, 0xffffff4c, 0xffffff71,
+0xffffff8f, 0xffffffa6, 0xffffffb9, 0xffffffc8, 0xffffffd3, 0xffffffdd, 0xffffffe4, 0xffffffea,
+0xffffffef, 0xfffffff2, 0xfffffff5, 0xfffffff8, 0xfffffff9, 0xfffffffb, 0xfffffffc, 0xfffffffd,
+0xfffffffe, 0xfffffffe, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xffffc71d, 0xffffd2d9, 0xffffdc2a, 0xffffe38f, 0xffffe96d, 0xffffee15, 0xfffff1c8, 0xfffff4b7,
+0xfffff70b, 0xfffff8e4, 0xfffffa5c, 0xfffffb86, 0xfffffc72, 0xfffffd2e, 0xfffffdc3, 0xfffffe39,
+0xfffffe97, 0xfffffee2, 0xffffff1d, 0xffffff4c, 0xffffff71, 0xffffff8f, 0xffffffa6, 0xffffffb9,
+0xffffffc8, 0xffffffd3, 0xffffffdd, 0xffffffe4, 0xffffffea, 0xffffffef, 0xfffffff2, 0xfffffff5,
+0xfffffff8, 0xfffffff9, 0xfffffffb, 0xfffffffc, 0xfffffffd, 0xfffffffe, 0xfffffffe, 0xffffffff,
+0xffffffff, 0xffffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x000038e3, 0x00002d27, 0x000023d6, 0x00001c71, 0x00001693, 0x000011eb, 0x00000e38, 0x00000b49,
+0x000008f5, 0x0000071c, 0x000005a4, 0x0000047a, 0x0000038e, 0x000002d2, 0x0000023d, 0x000001c7,
+0x00000169, 0x0000011e, 0x000000e3, 0x000000b4, 0x0000008f, 0x00000071, 0x0000005a, 0x00000047,
+0x00000038, 0x0000002d, 0x00000023, 0x0000001c, 0x00000016, 0x00000011, 0x0000000e, 0x0000000b,
+0x00000008, 0x00000007, 0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001,
+0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x000071c7, 0x00005a4e, 0x000047ac, 0x000038e3, 0x00002d27, 0x000023d6, 0x00001c71, 0x00001693,
+0x000011eb, 0x00000e38, 0x00000b49, 0x000008f5, 0x0000071c, 0x000005a4, 0x0000047a, 0x0000038e,
+0x000002d2, 0x0000023d, 0x000001c7, 0x00000169, 0x0000011e, 0x000000e3, 0x000000b4, 0x0000008f,
+0x00000071, 0x0000005a, 0x00000047, 0x00000038, 0x0000002d, 0x00000023, 0x0000001c, 0x00000016,
+0x00000011, 0x0000000e, 0x0000000b, 0x00000008, 0x00000007, 0x00000005, 0x00000004, 0x00000003,
+0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x0000e38e, 0x0000b49c, 0x00008f59, 0x000071c7, 0x00005a4e, 0x000047ac, 0x000038e3, 0x00002d27,
+0x000023d6, 0x00001c71, 0x00001693, 0x000011eb, 0x00000e38, 0x00000b49, 0x000008f5, 0x0000071c,
+0x000005a4, 0x0000047a, 0x0000038e, 0x000002d2, 0x0000023d, 0x000001c7, 0x00000169, 0x0000011e,
+0x000000e3, 0x000000b4, 0x0000008f, 0x00000071, 0x0000005a, 0x00000047, 0x00000038, 0x0000002d,
+0x00000023, 0x0000001c, 0x00000016, 0x00000011, 0x0000000e, 0x0000000b, 0x00000008, 0x00000007,
+0x00000005, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000001, 0x00000001, 0x00000001,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_gainpow2_data[] = {
+0x05a82799, 0x04c1bf82, 0x04000000, 0x035d13f3, 0x02d413cc, 0x0260dfc1, 0x02000000, 0x01ae89f9,
+0x016a09e6, 0x01306fe0, 0x01000000, 0x00d744fc, 0x00b504f3, 0x009837f0, 0x00800000, 0x006ba27e,
+0x005a8279, 0x004c1bf8, 0x00400000, 0x0035d13f, 0x002d413c, 0x00260dfc, 0x00200000, 0x001ae89f,
+0x0016a09e, 0x001306fe, 0x00100000, 0x000d744f, 0x000b504f, 0x0009837f, 0x00080000, 0x0006ba27,
+0x0005a827, 0x0004c1bf, 0x00040000, 0x00035d13, 0x0002d413, 0x000260df, 0x00020000, 0x0001ae89,
+0x00016a09, 0x0001306f, 0x00010000, 0x0000d744, 0x0000b504, 0x00009837, 0x00008000, 0x00006ba2,
+0x00005a82, 0x00004c1b, 0x00004000, 0x000035d1, 0x00002d41, 0x0000260d, 0x00002000, 0x00001ae8,
+0x000016a0, 0x00001306, 0x00001000, 0x00000d74, 0x00000b50, 0x00000983, 0x00000800, 0x000006ba,
+0x000005a8, 0x000004c1, 0x00000400, 0x0000035d, 0x000002d4, 0x00000260, 0x00000200, 0x000001ae,
+0x0000016a, 0x00000130, 0x00000100, 0x000000d7, 0x000000b5, 0x00000098, 0x00000080, 0x0000006b,
+0x0000005a, 0x0000004c, 0x00000040, 0x00000035, 0x0000002d, 0x00000026, 0x00000020, 0x0000001a,
+0x00000016, 0x00000013, 0x00000010, 0x0000000d, 0x0000000b, 0x00000009, 0x00000008, 0x00000006,
+0x00000005, 0x00000004, 0x00000004, 0x00000003, 0x00000002, 0x00000002, 0x00000002, 0x00000001,
+0x00000001, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_ispow_data[] = {
+0x00000000, 0x00008000, 0x0001428a, 0x000229d2, 0x00032cbf, 0x00044662, 0x0005738c, 0x0006b1fc,
+0x0007ffff, 0x00095c41, 0x000ac5ad, 0x000c3b5d, 0x000dbc8f, 0x000f489e, 0x0010def9, 0x00127f20,
+0x001428a2, 0x0015db1b, 0x00179630, 0x0019598d, 0x001b24e8, 0x001cf7fc, 0x001ed28a, 0x0020b458,
+0x00229d2e, 0x00248cdb, 0x0026832f, 0x00287fff, 0x002a8322, 0x002c8c70, 0x002e9bc5, 0x0030b0ff,
+0x0032cbfd, 0x0034eca0, 0x003712ca, 0x00393e60, 0x003b6f47, 0x003da567, 0x003fe0a5, 0x004220ed,
+0x00446627, 0x0046b03e, 0x0048ff1e, 0x004b52b3, 0x004daaeb, 0x005007b4, 0x005268fc, 0x0054ceb2,
+0x005738c7, 0x0059a72a, 0x005c19cd, 0x005e90a1, 0x00610b98, 0x00638aa4, 0x00660db9, 0x006894c9,
+0x006b1fc8, 0x006daeaa, 0x00704163, 0x0072d7e8, 0x0075722e, 0x0078102b, 0x007ab1d3, 0x007d571e,
+0x007fffff, 0x0082ac70, 0x00855c65, 0x00880fd6, 0x008ac6b9, 0x008d8107, 0x00903eb7, 0x0092ffc0,
+0x0095c41a, 0x00988bbe, 0x009b56a4, 0x009e24c4, 0x00a0f617, 0x00a3ca96, 0x00a6a239, 0x00a97cfa,
+0x00ac5ad2, 0x00af3bbb, 0x00b21fad, 0x00b506a3, 0x00b7f096, 0x00badd81, 0x00bdcd5d, 0x00c0c025,
+0x00c3b5d2, 0x00c6ae60, 0x00c9a9c8, 0x00cca805, 0x00cfa912, 0x00d2acea, 0x00d5b387, 0x00d8bce5,
+0x00dbc8fe, 0x00ded7ce, 0x00e1e950, 0x00e4fd7e, 0x00e81456, 0x00eb2dd1, 0x00ee49ec, 0x00f168a2,
+0x00f489ef, 0x00f7adce, 0x00fad43c, 0x00fdfd34, 0x010128b2, 0x010456b2, 0x01078731, 0x010aba29,
+0x010def99, 0x0111277b, 0x011461cc, 0x01179e89, 0x011addae, 0x011e1f37, 0x01216320, 0x0124a967,
+0x0127f208, 0x012b3d00, 0x012e8a4b, 0x0131d9e6, 0x01352bce, 0x01387fff, 0x013bd678, 0x013f2f33,
+0x01428a2f, 0x0145e768, 0x014946dc, 0x014ca888, 0x01500c68, 0x01537279, 0x0156daba, 0x015a4527,
+0x015db1bd, 0x0161207a, 0x0164915b, 0x0168045d, 0x016b797e, 0x016ef0bb, 0x01726a12, 0x0175e580,
+0x01796302, 0x017ce297, 0x0180643b, 0x0183e7ec, 0x01876da9, 0x018af56e, 0x018e7f38, 0x01920b07,
+0x019598d8, 0x019928a8, 0x019cba74, 0x01a04e3c, 0x01a3e3fd, 0x01a77bb4, 0x01ab155f, 0x01aeb0fd,
+0x01b24e8b, 0x01b5ee07, 0x01b98f70, 0x01bd32c2, 0x01c0d7fc, 0x01c47f1d, 0x01c82821, 0x01cbd308,
+0x01cf7fcf, 0x01d32e74, 0x01d6def6, 0x01da9153, 0x01de4588, 0x01e1fb94, 0x01e5b375, 0x01e96d29,
+0x01ed28af, 0x01f0e604, 0x01f4a528, 0x01f86617, 0x01fc28d2, 0x01ffed55, 0x0203b39f, 0x02077baf,
+0x020b4582, 0x020f1118, 0x0212de6e, 0x0216ad83, 0x021a7e56, 0x021e50e4, 0x0222252d, 0x0225fb2e,
+0x0229d2e6, 0x022dac54, 0x02318776, 0x0235644b, 0x023942d1, 0x023d2306, 0x024104e9, 0x0244e879,
+0x0248cdb5, 0x024cb49a, 0x02509d28, 0x0254875c, 0x02587337, 0x025c60b5, 0x02604fd7, 0x0264409a,
+0x026832fd, 0x026c26ff, 0x02701c9f, 0x027413db, 0x02780cb1, 0x027c0722, 0x0280032a, 0x028400ca,
+0x0287ffff, 0x028c00ca, 0x02900327, 0x02940716, 0x02980c97, 0x029c13a7, 0x02a01c45, 0x02a42670,
+0x02a83228, 0x02ac3f6a, 0x02b04e36, 0x02b45e8b, 0x02b87067, 0x02bc83c9, 0x02c098b1, 0x02c4af1c,
+0x02c8c70a, 0x02cce07a, 0x02d0fb6a, 0x02d517da, 0x02d935c9, 0x02dd5534, 0x02e1761c, 0x02e59880,
+0x02e9bc5d, 0x02ede1b3, 0x02f20882, 0x02f630c8, 0x02fa5a83, 0x02fe85b4, 0x0302b258, 0x0306e070,
+0x030b0ff9, 0x030f40f3, 0x0313735e, 0x0317a737, 0x031bdc7e, 0x03201333, 0x03244b53, 0x032884de,
+0x032cbfd4, 0x0330fc33, 0x033539fa, 0x03397929, 0x033db9be, 0x0341fbb8, 0x03463f17, 0x034a83da,
+0x034eca00, 0x03531187, 0x03575a6f, 0x035ba4b8, 0x035ff060, 0x03643d66, 0x03688bc9, 0x036cdb8a,
+0x03712ca6, 0x03757f1d, 0x0379d2ee, 0x037e2818, 0x03827e9a, 0x0386d674, 0x038b2fa5, 0x038f8a2c,
+0x0393e608, 0x03984338, 0x039ca1bc, 0x03a10192, 0x03a562ba, 0x03a9c533, 0x03ae28fd, 0x03b28e16,
+0x03b6f47e, 0x03bb5c33, 0x03bfc536, 0x03c42f85, 0x03c89b20, 0x03cd0806, 0x03d17636, 0x03d5e5af,
+0x03da5671, 0x03dec87b, 0x03e33bcc, 0x03e7b063, 0x03ec2640, 0x03f09d62, 0x03f515c9, 0x03f98f73,
+0x03fe0a5f, 0x0402868e, 0x040703fe, 0x040b82af, 0x041002a0, 0x041483d1, 0x04190640, 0x041d89ec,
+0x04220ed7, 0x042694fd, 0x042b1c60, 0x042fa4fe, 0x04342ed6, 0x0438b9e9, 0x043d4635, 0x0441d3b9,
+0x04466275, 0x044af269, 0x044f8393, 0x045415f3, 0x0458a988, 0x045d3e53, 0x0461d451, 0x04666b83,
+0x046b03e7, 0x046f9d7e, 0x04743846, 0x0478d440, 0x047d716a, 0x04820fc3, 0x0486af4c, 0x048b5003,
+0x048ff1e8, 0x049494fa, 0x04993939, 0x049ddea5, 0x04a2853c, 0x04a72cfd, 0x04abd5ea, 0x04b07fff,
+0x04b52b3f, 0x04b9d7a6, 0x04be8536, 0x04c333ee, 0x04c7e3cc, 0x04cc94d1, 0x04d146fb, 0x04d5fa4b,
+0x04daaebf, 0x04df6458, 0x04e41b14, 0x04e8d2f3, 0x04ed8bf5, 0x04f24618, 0x04f7015d, 0x04fbbdc3,
+0x05007b49, 0x050539ef, 0x0509f9b4, 0x050eba98, 0x05137c9a, 0x05183fba, 0x051d03f6, 0x0521c950,
+0x05268fc6, 0x052b5757, 0x05302003, 0x0534e9ca, 0x0539b4ab, 0x053e80a5, 0x05434db9, 0x05481be5,
+0x054ceb29, 0x0551bb85, 0x05568cf8, 0x055b5f81, 0x05603321, 0x056507d6, 0x0569dda0, 0x056eb47f,
+0x05738c72, 0x05786578, 0x057d3f92, 0x05821abe, 0x0586f6fd, 0x058bd44e, 0x0590b2af, 0x05959222,
+0x059a72a5, 0x059f5438, 0x05a436da, 0x05a91a8c, 0x05adff4b, 0x05b2e519, 0x05b7cbf5, 0x05bcb3dd,
+0x05c19cd3, 0x05c686d4, 0x05cb71e2, 0x05d05dfb, 0x05d54b1f, 0x05da394d, 0x05df2885, 0x05e418c7,
+0x05e90a12, 0x05edfc66, 0x05f2efc2, 0x05f7e426, 0x05fcd992, 0x0601d004, 0x0606c77d, 0x060bbffd,
+0x0610b982, 0x0615b40c, 0x061aaf9b, 0x061fac2f, 0x0624a9c7, 0x0629a863, 0x062ea802, 0x0633a8a3,
+0x0638aa47, 0x063dacee, 0x0642b095, 0x0647b53f, 0x064cbae8, 0x0651c193, 0x0656c93d, 0x065bd1e7,
+0x0660db90, 0x0665e639, 0x066af1df, 0x066ffe84, 0x06750c26, 0x067a1ac6, 0x067f2a62, 0x06843afb,
+0x06894c90, 0x068e5f21, 0x069372ad, 0x06988735, 0x069d9cb6, 0x06a2b332, 0x06a7caa8, 0x06ace318,
+0x06b1fc80, 0x06b716e2, 0x06bc323b, 0x06c14e8d, 0x06c66bd6, 0x06cb8a17, 0x06d0a94e, 0x06d5c97c,
+0x06daeaa0, 0x06e00cba, 0x06e52fca, 0x06ea53ce, 0x06ef78c8, 0x06f49eb5, 0x06f9c597, 0x06feed6d,
+0x07041635, 0x07093ff1, 0x070e6aa0, 0x07139640, 0x0718c2d3, 0x071df057, 0x07231ecd, 0x07284e33,
+0x072d7e8a, 0x0732afd2, 0x0737e209, 0x073d1530, 0x07424946, 0x07477e4a, 0x074cb43e, 0x0751eb20,
+0x075722ef, 0x075c5bac, 0x07619556, 0x0766cfee, 0x076c0b71, 0x077147e1, 0x0776853d, 0x077bc385,
+0x078102b8, 0x078642d6, 0x078b83de, 0x0790c5d1, 0x079608ae, 0x079b4c74, 0x07a09124, 0x07a5d6bd,
+0x07ab1d3e, 0x07b064a8, 0x07b5acfa, 0x07baf634, 0x07c04056, 0x07c58b5e, 0x07cad74e, 0x07d02424,
+0x07d571e0, 0x07dac082, 0x07e0100a, 0x07e56077, 0x07eab1ca, 0x07f00401, 0x07f5571c, 0x07faab1c,
+0x07ffffff, 0x080555c7, 0x080aac71, 0x081003fe, 0x08155c6e, 0x081ab5c0, 0x08200ff5, 0x08256b0b,
+0x082ac703, 0x083023dc, 0x08358196, 0x083ae030, 0x08403fab, 0x0845a006, 0x084b0141, 0x0850635b,
+0x0855c654, 0x085b2a2d, 0x08608ee4, 0x0865f479, 0x086b5aed, 0x0870c23e, 0x08762a6d, 0x087b9379,
+0x0880fd62, 0x08866828, 0x088bd3ca, 0x08914048, 0x0896ada3, 0x089c1bd8, 0x08a18aea, 0x08a6fad6,
+0x08ac6b9d, 0x08b1dd3f, 0x08b74fbb, 0x08bcc311, 0x08c23741, 0x08c7ac4a, 0x08cd222c, 0x08d298e8,
+0x08d8107c, 0x08dd88e8, 0x08e3022d, 0x08e87c49, 0x08edf73d, 0x08f37309, 0x08f8efac, 0x08fe6d25,
+0x0903eb75, 0x09096a9c, 0x090eea99, 0x09146b6b, 0x0919ed13, 0x091f6f91, 0x0924f2e3, 0x092a770b,
+0x092ffc06, 0x093581d7, 0x093b087b, 0x09408ff3, 0x0946183f, 0x094ba15e, 0x09512b51, 0x0956b616,
+0x095c41ae, 0x0961ce18, 0x09675b54, 0x096ce962, 0x09727842, 0x097807f3, 0x097d9876, 0x098329c9,
+0x0988bbed, 0x098e4ee1, 0x0993e2a6, 0x0999773a, 0x099f0c9f, 0x09a4a2d3, 0x09aa39d6, 0x09afd1a8,
+0x09b56a49, 0x09bb03b8, 0x09c09df6, 0x09c63902, 0x09cbd4dc, 0x09d17183, 0x09d70ef8, 0x09dcad3a,
+0x09e24c49, 0x09e7ec25, 0x09ed8ccd, 0x09f32e41, 0x09f8d082, 0x09fe738e, 0x0a041766, 0x0a09bc09,
+0x0a0f6178, 0x0a1507b1, 0x0a1aaeb5, 0x0a205684, 0x0a25ff1c, 0x0a2ba87f, 0x0a3152ac, 0x0a36fda2,
+0x0a3ca962, 0x0a4255ea, 0x0a48033c, 0x0a4db157, 0x0a536039, 0x0a590fe5, 0x0a5ec058, 0x0a647193,
+0x0a6a2396, 0x0a6fd660, 0x0a7589f2, 0x0a7b3e4b, 0x0a80f36a, 0x0a86a950, 0x0a8c5ffc, 0x0a92176f,
+0x0a97cfa7, 0x0a9d88a5, 0x0aa34269, 0x0aa8fcf2, 0x0aaeb840, 0x0ab47453, 0x0aba312b, 0x0abfeec8,
+0x0ac5ad28, 0x0acb6c4d, 0x0ad12c36, 0x0ad6ece2, 0x0adcae52, 0x0ae27085, 0x0ae8337b, 0x0aedf734,
+0x0af3bbb0, 0x0af980ee, 0x0aff46ef, 0x0b050db2, 0x0b0ad536, 0x0b109d7c, 0x0b166684, 0x0b1c304d,
+0x0b21fad7, 0x0b27c622, 0x0b2d922e, 0x0b335efa, 0x0b392c87, 0x0b3efad3, 0x0b44c9e0, 0x0b4a99ac,
+0x0b506a38, 0x0b563b83, 0x0b5c0d8e, 0x0b61e057, 0x0b67b3df, 0x0b6d8826, 0x0b735d2b, 0x0b7932ee,
+0x0b7f096f, 0x0b84e0ae, 0x0b8ab8ab, 0x0b909165, 0x0b966add, 0x0b9c4511, 0x0ba22003, 0x0ba7fbb1,
+0x0badd81b, 0x0bb3b542, 0x0bb99326, 0x0bbf71c5, 0x0bc55120, 0x0bcb3136, 0x0bd11208, 0x0bd6f395,
+0x0bdcd5dd, 0x0be2b8e0, 0x0be89c9e, 0x0bee8116, 0x0bf46649, 0x0bfa4c36, 0x0c0032dc, 0x0c061a3d,
+0x0c0c0257, 0x0c11eb2a, 0x0c17d4b7, 0x0c1dbefd, 0x0c23a9fc, 0x0c2995b3, 0x0c2f8223, 0x0c356f4c,
+0x0c3b5d2c, 0x0c414bc5, 0x0c473b16, 0x0c4d2b1e, 0x0c531bde, 0x0c590d55, 0x0c5eff83, 0x0c64f268,
+0x0c6ae604, 0x0c70da57, 0x0c76cf60, 0x0c7cc51f, 0x0c82bb95, 0x0c88b2c1, 0x0c8eaaa2, 0x0c94a339,
+0x0c9a9c85, 0x0ca09687, 0x0ca6913e, 0x0cac8caa, 0x0cb288ca, 0x0cb885a0, 0x0cbe8329, 0x0cc48167,
+0x0cca8059, 0x0cd07fff, 0x0cd68059, 0x0cdc8167, 0x0ce28328, 0x0ce8859c, 0x0cee88c4, 0x0cf48c9e,
+0x0cfa912b, 0x0d00966b, 0x0d069c5d, 0x0d0ca302, 0x0d12aa59, 0x0d18b262, 0x0d1ebb1d, 0x0d24c489,
+0x0d2acea7, 0x0d30d976, 0x0d36e4f7, 0x0d3cf128, 0x0d42fe0b, 0x0d490b9e, 0x0d4f19e2, 0x0d5528d6,
+0x0d5b387b, 0x0d6148cf, 0x0d6759d4, 0x0d6d6b88, 0x0d737dec, 0x0d799100, 0x0d7fa4c3, 0x0d85b935,
+0x0d8bce56, 0x0d91e426, 0x0d97faa4, 0x0d9e11d1, 0x0da429ad, 0x0daa4237, 0x0db05b6f, 0x0db67555,
+0x0dbc8fe9, 0x0dc2ab2a, 0x0dc8c719, 0x0dcee3b5, 0x0dd500ff, 0x0ddb1ef5, 0x0de13d99, 0x0de75ce9,
+0x0ded7ce6, 0x0df39d8f, 0x0df9bee5, 0x0dffe0e7, 0x0e060394, 0x0e0c26ee, 0x0e124af4, 0x0e186fa5,
+0x0e1e9501, 0x0e24bb09, 0x0e2ae1bb, 0x0e310919, 0x0e373122, 0x0e3d59d5, 0x0e438333, 0x0e49ad3c,
+0x0e4fd7ee, 0x0e56034b, 0x0e5c2f52, 0x0e625c02, 0x0e68895d, 0x0e6eb761, 0x0e74e60e, 0x0e7b1564,
+0x0e814564, 0x0e87760d, 0x0e8da75e, 0x0e93d959, 0x0e9a0bfb, 0x0ea03f47, 0x0ea6733a, 0x0eaca7d6,
+0x0eb2dd1a, 0x0eb91305, 0x0ebf4999, 0x0ec580d4, 0x0ecbb8b6, 0x0ed1f140, 0x0ed82a71, 0x0ede6449,
+0x0ee49ec8, 0x0eead9ed, 0x0ef115ba, 0x0ef7522d, 0x0efd8f46, 0x0f03cd05, 0x0f0a0b6b, 0x0f104a76,
+0x0f168a28, 0x0f1cca7f, 0x0f230b7b, 0x0f294d1d, 0x0f2f8f65, 0x0f35d251, 0x0f3c15e3, 0x0f425a19,
+0x0f489ef4, 0x0f4ee474, 0x0f552a98, 0x0f5b7161, 0x0f61b8ce, 0x0f6800df, 0x0f6e4994, 0x0f7492ed,
+0x0f7adce9, 0x0f81278a, 0x0f8772cd, 0x0f8dbeb4, 0x0f940b3e, 0x0f9a586b, 0x0fa0a63c, 0x0fa6f4af,
+0x0fad43c4, 0x0fb3937c, 0x0fb9e3d7, 0x0fc034d4, 0x0fc68673, 0x0fccd8b4, 0x0fd32b97, 0x0fd97f1c,
+0x0fdfd343, 0x0fe6280b, 0x0fec7d74, 0x0ff2d37f, 0x0ff92a2b, 0x0fff8178, 0x1005d966, 0x100c31f5,
+0x10128b24, 0x1018e4f4, 0x101f3f64, 0x10259a75, 0x102bf626, 0x10325277, 0x1038af67, 0x103f0cf8,
+0x10456b28, 0x104bc9f8, 0x10522967, 0x10588976, 0x105eea24, 0x10654b70, 0x106bad5c, 0x10720fe7,
+0x10787310, 0x107ed6d8, 0x10853b3f, 0x108ba043, 0x109205e6, 0x10986c27, 0x109ed307, 0x10a53a83,
+0x10aba29e, 0x10b20b57, 0x10b874ac, 0x10bedea0, 0x10c54930, 0x10cbb45e, 0x10d22029, 0x10d88c90,
+0x10def995, 0x10e56736, 0x10ebd574, 0x10f2444e, 0x10f8b3c5, 0x10ff23d8, 0x11059487, 0x110c05d2,
+0x111277b9, 0x1118ea3b, 0x111f5d59, 0x1125d113, 0x112c4568, 0x1132ba59, 0x11392fe5, 0x113fa60c,
+0x11461ccd, 0x114c942a, 0x11530c22, 0x115984b4, 0x115ffde0, 0x116677a7, 0x116cf209, 0x11736d04,
+0x1179e89a, 0x118064c9, 0x1186e192, 0x118d5ef5, 0x1193dcf2, 0x119a5b88, 0x11a0dab8, 0x11a75a81,
+0x11addae3, 0x11b45bde, 0x11badd72, 0x11c15f9f, 0x11c7e265, 0x11ce65c4, 0x11d4e9bb, 0x11db6e4a,
+0x11e1f372, 0x11e87931, 0x11eeff89, 0x11f58679, 0x11fc0e01, 0x12029621, 0x12091ed8, 0x120fa827,
+0x1216320d, 0x121cbc8a, 0x1223479f, 0x1229d34b, 0x12305f8e, 0x1236ec68, 0x123d79d9, 0x124407e0,
+0x124a967e, 0x125125b2, 0x1257b57d, 0x125e45de, 0x1264d6d6, 0x126b6863, 0x1271fa86, 0x12788d40,
+0x127f208f, 0x1285b473, 0x128c48ed, 0x1292ddfd, 0x129973a2, 0x12a009dc, 0x12a6a0ab, 0x12ad3810,
+0x12b3d009, 0x12ba6897, 0x12c101ba, 0x12c79b71, 0x12ce35bd, 0x12d4d09e, 0x12db6c13, 0x12e2081b,
+0x12e8a4b9, 0x12ef41ea, 0x12f5dfaf, 0x12fc7e07, 0x13031cf4, 0x1309bc74, 0x13105c88, 0x1316fd2f,
+0x131d9e69, 0x13244036, 0x132ae297, 0x1331858b, 0x13382911, 0x133ecd2b, 0x134571d7, 0x134c1716,
+0x1352bce7, 0x1359634a, 0x13600a40, 0x1366b1c9, 0x136d59e3, 0x1374028f, 0x137aabce, 0x1381559e,
+0x1387ffff, 0x138eaaf3, 0x13955678, 0x139c028e, 0x13a2af36, 0x13a95c6f, 0x13b00a39, 0x13b6b895,
+0x13bd6781, 0x13c416fe, 0x13cac70c, 0x13d177aa, 0x13d828d9, 0x13deda99, 0x13e58ce9, 0x13ec3fc9,
+0x13f2f33a, 0x13f9a73a, 0x14005bcb, 0x140710eb, 0x140dc69c, 0x14147cdc, 0x141b33ab, 0x1421eb0a,
+0x1428a2f9, 0x142f5b77, 0x14361484, 0x143cce21, 0x1443884c, 0x144a4307, 0x1450fe50, 0x1457ba28,
+0x145e768f, 0x14653384, 0x146bf108, 0x1472af1b, 0x14796dbb, 0x14802cea, 0x1486eca8, 0x148dacf3,
+0x14946dcc, 0x149b2f33, 0x14a1f128, 0x14a8b3aa, 0x14af76ba, 0x14b63a58, 0x14bcfe83, 0x14c3c33b,
+0x14ca8881, 0x14d14e54, 0x14d814b4, 0x14dedba0, 0x14e5a31a, 0x14ec6b21, 0x14f333b4, 0x14f9fcd4,
+0x1500c680, 0x150790b9, 0x150e5b7e, 0x151526cf, 0x151bf2ad, 0x1522bf17, 0x15298c0c, 0x1530598e,
+0x1537279b, 0x153df634, 0x1544c559, 0x154b950a, 0x15526545, 0x1559360d, 0x1560075f, 0x1566d93d,
+0x156daba6, 0x15747e99, 0x157b5218, 0x15822622, 0x1588fab6, 0x158fcfd6, 0x1596a57f, 0x159d7bb4,
+0x15a45272, 0x15ab29bc, 0x15b2018f, 0x15b8d9ed, 0x15bfb2d4, 0x15c68c46, 0x15cd6641, 0x15d440c7,
+0x15db1bd6, 0x15e1f76f, 0x15e8d391, 0x15efb03d, 0x15f68d73, 0x15fd6b31, 0x16044979, 0x160b284a,
+0x161207a5, 0x1618e788, 0x161fc7f4, 0x1626a8e9, 0x162d8a67, 0x16346c6d, 0x163b4efc, 0x16423213,
+0x164915b3, 0x164ff9dc, 0x1656de8c, 0x165dc3c5, 0x1664a985, 0x166b8fce, 0x1672769f, 0x16795df7,
+0x168045d8, 0x16872e40, 0x168e172f, 0x169500a7, 0x169beaa5, 0x16a2d52b, 0x16a9c038, 0x16b0abcd,
+0x16b797e8, 0x16be848b, 0x16c571b4, 0x16cc5f65, 0x16d34d9c, 0x16da3c5a, 0x16e12b9e, 0x16e81b69,
+0x16ef0bbb, 0x16f5fc93, 0x16fcedf1, 0x1703dfd6, 0x170ad241, 0x1711c531, 0x1718b8a8, 0x171faca5,
+0x1726a127, 0x172d9630, 0x17348bbe, 0x173b81d1, 0x1742786b, 0x17496f89, 0x1750672d, 0x17575f56,
+0x175e5805, 0x17655139, 0x176c4af1, 0x1773452f, 0x177a3ff2, 0x17813b39, 0x17883705, 0x178f3356,
+0x1796302c, 0x179d2d86, 0x17a42b64, 0x17ab29c7, 0x17b228ae, 0x17b92819, 0x17c02809, 0x17c7287c,
+0x17ce2974, 0x17d52aef, 0x17dc2cef, 0x17e32f72, 0x17ea3278, 0x17f13603, 0x17f83a11, 0x17ff3ea2,
+0x180643b7, 0x180d494f, 0x18144f6a, 0x181b5609, 0x18225d2a, 0x182964cf, 0x18306cf6, 0x183775a1,
+0x183e7ece, 0x1845887e, 0x184c92b0, 0x18539d65, 0x185aa89d, 0x1861b457, 0x1868c093, 0x186fcd52,
+0x1876da93, 0x187de856, 0x1884f69b, 0x188c0562, 0x189314aa, 0x189a2475, 0x18a134c2, 0x18a84590,
+0x18af56e0, 0x18b668b1, 0x18bd7b04, 0x18c48dd8, 0x18cba12d, 0x18d2b504, 0x18d9c95c, 0x18e0de35,
+0x18e7f38f, 0x18ef096b, 0x18f61fc7, 0x18fd36a3, 0x19044e01, 0x190b65df, 0x19127e3e, 0x1919971d,
+0x1920b07d, 0x1927ca5d, 0x192ee4be, 0x1935ff9f, 0x193d1b00, 0x194436e1, 0x194b5342, 0x19527023,
+0x19598d84, 0x1960ab65, 0x1967c9c6, 0x196ee8a6, 0x19760806, 0x197d27e6, 0x19844845, 0x198b6923,
+0x19928a81, 0x1999ac5e, 0x19a0ceba, 0x19a7f196, 0x19af14f0, 0x19b638ca, 0x19bd5d22, 0x19c481f9,
+0x19cba74f, 0x19d2cd24, 0x19d9f378, 0x19e11a4a, 0x19e8419a, 0x19ef6969, 0x19f691b6, 0x19fdba82,
+0x1a04e3cc, 0x1a0c0d94, 0x1a1337da, 0x1a1a629f, 0x1a218de1, 0x1a28b9a1, 0x1a2fe5df, 0x1a37129b,
+0x1a3e3fd4, 0x1a456d8b, 0x1a4c9bc0, 0x1a53ca72, 0x1a5af9a2, 0x1a62294f, 0x1a695979, 0x1a708a21,
+0x1a77bb45, 0x1a7eece7, 0x1a861f06, 0x1a8d51a2, 0x1a9484bb, 0x1a9bb850, 0x1aa2ec62, 0x1aaa20f1,
+0x1ab155fd, 0x1ab88b85, 0x1abfc18a, 0x1ac6f80b, 0x1ace2f09, 0x1ad56683, 0x1adc9e79, 0x1ae3d6eb,
+0x1aeb0fda, 0x1af24944, 0x1af9832b, 0x1b00bd8d, 0x1b07f86c, 0x1b0f33c6, 0x1b166f9c, 0x1b1dabed,
+0x1b24e8ba, 0x1b2c2603, 0x1b3363c7, 0x1b3aa206, 0x1b41e0c1, 0x1b491ff7, 0x1b505fa9, 0x1b579fd5,
+0x1b5ee07d, 0x1b66219f, 0x1b6d633d, 0x1b74a555, 0x1b7be7e9, 0x1b832af7, 0x1b8a6e7f, 0x1b91b283,
+0x1b98f701, 0x1ba03bf9, 0x1ba7816c, 0x1baec75a, 0x1bb60dc1, 0x1bbd54a3, 0x1bc49bff, 0x1bcbe3d6,
+0x1bd32c26, 0x1bda74f1, 0x1be1be35, 0x1be907f3, 0x1bf0522b, 0x1bf79cdd, 0x1bfee809, 0x1c0633ae,
+0x1c0d7fcc, 0x1c14cc65, 0x1c1c1976, 0x1c236702, 0x1c2ab506, 0x1c320384, 0x1c39527b, 0x1c40a1eb,
+0x1c47f1d4, 0x1c4f4236, 0x1c569311, 0x1c5de466, 0x1c653632, 0x1c6c8878, 0x1c73db37, 0x1c7b2e6e,
+0x1c82821d, 0x1c89d646, 0x1c912ae6, 0x1c987fff, 0x1c9fd591, 0x1ca72b9b, 0x1cae821d, 0x1cb5d917,
+0x1cbd3089, 0x1cc48874, 0x1ccbe0d6, 0x1cd339b1, 0x1cda9303, 0x1ce1eccd, 0x1ce9470f, 0x1cf0a1c8,
+0x1cf7fcf9, 0x1cff58a2, 0x1d06b4c2, 0x1d0e115a, 0x1d156e69, 0x1d1ccbf0, 0x1d2429ed, 0x1d2b8862,
+0x1d32e74e, 0x1d3a46b2, 0x1d41a68c, 0x1d4906dd, 0x1d5067a6, 0x1d57c8e5, 0x1d5f2a9b, 0x1d668cc7,
+0x1d6def6b, 0x1d755285, 0x1d7cb615, 0x1d841a1c, 0x1d8b7e9a, 0x1d92e38e, 0x1d9a48f9, 0x1da1aed9,
+0x1da91530, 0x1db07bfd, 0x1db7e340, 0x1dbf4afa, 0x1dc6b329, 0x1dce1bce, 0x1dd584e9, 0x1ddcee7a,
+0x1de45881, 0x1debc2fe, 0x1df32df0, 0x1dfa9957, 0x1e020535, 0x1e097187, 0x1e10de50, 0x1e184b8d,
+0x1e1fb940, 0x1e272768, 0x1e2e9606, 0x1e360518, 0x1e3d74a0, 0x1e44e49d, 0x1e4c550e, 0x1e53c5f5,
+0x1e5b3750, 0x1e62a921, 0x1e6a1b66, 0x1e718e20, 0x1e79014e, 0x1e8074f1, 0x1e87e909, 0x1e8f5d95,
+0x1e96d295, 0x1e9e480a, 0x1ea5bdf3, 0x1ead3450, 0x1eb4ab22, 0x1ebc2268, 0x1ec39a22, 0x1ecb1250,
+0x1ed28af1, 0x1eda0407, 0x1ee17d91, 0x1ee8f78f, 0x1ef07200, 0x1ef7ece5, 0x1eff683d, 0x1f06e40a,
+0x1f0e604a, 0x1f15dcfd, 0x1f1d5a24, 0x1f24d7be, 0x1f2c55cb, 0x1f33d44c, 0x1f3b5340, 0x1f42d2a7,
+0x1f4a5281, 0x1f51d2ce, 0x1f59538f, 0x1f60d4c2, 0x1f685668, 0x1f6fd881, 0x1f775b0d, 0x1f7ede0c,
+0x1f86617d, 0x1f8de561, 0x1f9569b7, 0x1f9cee80, 0x1fa473bb, 0x1fabf969, 0x1fb37f8a, 0x1fbb061c,
+0x1fc28d21, 0x1fca1498, 0x1fd19c81, 0x1fd924dc, 0x1fe0ada9, 0x1fe836e9, 0x1fefc09a, 0x1ff74abd,
+0x1ffed552, 0x20066059, 0x200debd1, 0x201577bc, 0x201d0417, 0x202490e5, 0x202c1e24, 0x2033abd4,
+0x203b39f6, 0x2042c889, 0x204a578d, 0x2051e703, 0x205976ea, 0x20610742, 0x2068980b, 0x20702946,
+0x2077baf1, 0x207f4d0d, 0x2086df9a, 0x208e7298, 0x20960607, 0x209d99e7, 0x20a52e37, 0x20acc2f8,
+0x20b45829, 0x20bbedcb, 0x20c383de, 0x20cb1a61, 0x20d2b154, 0x20da48b8, 0x20e1e08c, 0x20e978d0,
+0x20f11185, 0x20f8aaa9, 0x2100443e, 0x2107de43, 0x210f78b7, 0x2117139c, 0x211eaef0, 0x21264ab5,
+0x212de6e9, 0x2135838d, 0x213d20a0, 0x2144be24, 0x214c5c16, 0x2153fa79, 0x215b994b, 0x2163388c,
+0x216ad83d, 0x2172785d, 0x217a18ec, 0x2181b9ea, 0x21895b58, 0x2190fd35, 0x21989f81, 0x21a0423c,
+0x21a7e566, 0x21af88ff, 0x21b72d06, 0x21bed17d, 0x21c67663, 0x21ce1bb7, 0x21d5c17a, 0x21dd67ab,
+0x21e50e4b, 0x21ecb55a, 0x21f45cd7, 0x21fc04c3, 0x2203ad1d, 0x220b55e5, 0x2212ff1c, 0x221aa8c1,
+0x222252d4, 0x2229fd56, 0x2231a845, 0x223953a3, 0x2240ff6e, 0x2248aba8, 0x2250584f, 0x22580565,
+0x225fb2e8, 0x226760d9, 0x226f0f37, 0x2276be04, 0x227e6d3e, 0x22861ce5, 0x228dccfa, 0x22957d7d,
+0x229d2e6d, 0x22a4dfcb, 0x22ac9195, 0x22b443cd, 0x22bbf673, 0x22c3a985, 0x22cb5d05, 0x22d310f2,
+0x22dac54c, 0x22e27a13, 0x22ea2f47, 0x22f1e4e8, 0x22f99af5, 0x23015170, 0x23090857, 0x2310bfab,
+0x2318776c, 0x23202f99, 0x2327e833, 0x232fa13a, 0x23375aad, 0x233f148c, 0x2346ced8, 0x234e8991,
+0x235644b5, 0x235e0046, 0x2365bc43, 0x236d78ac, 0x23753582, 0x237cf2c3, 0x2384b071, 0x238c6e8a,
+0x23942d10, 0x239bec01, 0x23a3ab5e, 0x23ab6b28, 0x23b32b5c, 0x23baebfd, 0x23c2ad09, 0x23ca6e81,
+0x23d23064, 0x23d9f2b3, 0x23e1b56e, 0x23e97894, 0x23f13c25, 0x23f90022, 0x2400c48a, 0x2408895d,
+0x24104e9b, 0x24181445, 0x241fda5a, 0x2427a0da, 0x242f67c5, 0x24372f1a, 0x243ef6db, 0x2446bf07,
+0x244e879e, 0x2456509f, 0x245e1a0b, 0x2465e3e2, 0x246dae24, 0x247578d0, 0x247d43e7, 0x24850f68,
+0x248cdb54, 0x2494a7ab, 0x249c746b, 0x24a44197, 0x24ac0f2c, 0x24b3dd2c, 0x24bbab96, 0x24c37a6a,
+0x24cb49a8, 0x24d31951, 0x24dae963, 0x24e2b9e0, 0x24ea8ac6, 0x24f25c17, 0x24fa2dd1, 0x2501fff5,
+0x2509d283, 0x2511a57b, 0x251978dc, 0x25214ca7, 0x252920dc, 0x2530f57b, 0x2538ca82, 0x25409ff4,
+0x254875cf, 0x25504c13, 0x255822c0, 0x255ff9d7, 0x2567d157, 0x256fa941, 0x25778193, 0x257f5a4f,
+0x25873374, 0x258f0d02, 0x2596e6f9, 0x259ec159, 0x25a69c22, 0x25ae7753, 0x25b652ee, 0x25be2ef1,
+0x25c60b5e, 0x25cde833, 0x25d5c570, 0x25dda316, 0x25e58125, 0x25ed5f9d, 0x25f53e7c, 0x25fd1dc5,
+0x2604fd76, 0x260cdd8f, 0x2614be10, 0x261c9efa, 0x2624804c, 0x262c6206, 0x26344429, 0x263c26b3,
+0x264409a6, 0x264bed01, 0x2653d0c3, 0x265bb4ee, 0x26639980, 0x266b7e7b, 0x267363dd, 0x267b49a7,
+0x26832fd9, 0x268b1673, 0x2692fd74, 0x269ae4dd, 0x26a2ccad, 0x26aab4e5, 0x26b29d85, 0x26ba868c,
+0x26c26ffa, 0x26ca59d0, 0x26d2440d, 0x26da2eb1, 0x26e219bd, 0x26ea0530, 0x26f1f10a, 0x26f9dd4b,
+0x2701c9f4, 0x2709b703, 0x2711a479, 0x27199257, 0x2721809b, 0x27296f46, 0x27315e58, 0x27394dd1,
+0x27413db0, 0x27492df7, 0x27511ea4, 0x27590fb7, 0x27610132, 0x2768f312, 0x2770e55a, 0x2778d808,
+0x2780cb1c, 0x2788be96, 0x2790b277, 0x2798a6bf, 0x27a09b6c, 0x27a89080, 0x27b085fa, 0x27b87bdb,
+0x27c07221, 0x27c868cd, 0x27d05fe0, 0x27d85758, 0x27e04f37, 0x27e8477b, 0x27f04026, 0x27f83936,
+0x280032ac, 0x28082c87, 0x281026c9, 0x28182170, 0x28201c7d, 0x282817ef, 0x283013c7, 0x28381004,
+0x28400ca7, 0x284809b0, 0x2850071d, 0x285804f1, 0x28600329, 0x286801c7, 0x287000ca, 0x28780032,
+0x287fffff, 0x28880032, 0x289000ca, 0x289801c6, 0x28a00328, 0x28a804ef, 0x28b0071b, 0x28b809ab,
+0x28c00ca1, 0x28c80ffb, 0x28d013ba, 0x28d817de, 0x28e01c66, 0x28e82153, 0x28f026a5, 0x28f82c5b,
+0x29003276, 0x290838f6, 0x29103fda, 0x29184722, 0x29204ecf, 0x292856e0, 0x29305f55, 0x2938682f,
+0x2940716d, 0x29487b0f, 0x29508516, 0x29588f80, 0x29609a4f, 0x2968a582, 0x2970b118, 0x2978bd13,
+0x2980c972, 0x2988d634, 0x2990e35a, 0x2998f0e5, 0x29a0fed3, 0x29a90d24, 0x29b11bda, 0x29b92af3,
+0x29c13a70, 0x29c94a50, 0x29d15a94, 0x29d96b3c, 0x29e17c47, 0x29e98db5, 0x29f19f87, 0x29f9b1bc,
+0x2a01c455, 0x2a09d751, 0x2a11eab0, 0x2a19fe72, 0x2a221298, 0x2a2a2721, 0x2a323c0d, 0x2a3a515c,
+0x2a42670e, 0x2a4a7d23, 0x2a52939b, 0x2a5aaa75, 0x2a62c1b3, 0x2a6ad954, 0x2a72f157, 0x2a7b09be,
+0x2a832287, 0x2a8b3bb2, 0x2a935541, 0x2a9b6f32, 0x2aa38986, 0x2aaba43c, 0x2ab3bf55, 0x2abbdad0,
+0x2ac3f6ad, 0x2acc12ee, 0x2ad42f90, 0x2adc4c95, 0x2ae469fc, 0x2aec87c6, 0x2af4a5f1, 0x2afcc47f,
+0x2b04e36f, 0x2b0d02c1, 0x2b152276, 0x2b1d428c, 0x2b256304, 0x2b2d83df, 0x2b35a51b, 0x2b3dc6b9,
+0x2b45e8b9, 0x2b4e0b1b, 0x2b562ddf, 0x2b5e5104, 0x2b66748c, 0x2b6e9875, 0x2b76bcbf, 0x2b7ee16b,
+0x2b870679, 0x2b8f2be9, 0x2b9751b9, 0x2b9f77ec, 0x2ba79e80, 0x2bafc575, 0x2bb7eccb, 0x2bc01483,
+0x2bc83c9d, 0x2bd06517, 0x2bd88df3, 0x2be0b730, 0x2be8e0ce, 0x2bf10acd, 0x2bf9352e, 0x2c015fef,
+0x2c098b11, 0x2c11b695, 0x2c19e279, 0x2c220ebf, 0x2c2a3b65, 0x2c32686c, 0x2c3a95d4, 0x2c42c39c,
+0x2c4af1c6, 0x2c532050, 0x2c5b4f3a, 0x2c637e86, 0x2c6bae32, 0x2c73de3e, 0x2c7c0eab, 0x2c843f79,
+0x2c8c70a7, 0x2c94a236, 0x2c9cd424, 0x2ca50674, 0x2cad3923, 0x2cb56c33, 0x2cbd9fa3, 0x2cc5d374,
+0x2cce07a4, 0x2cd63c35, 0x2cde7126, 0x2ce6a677, 0x2ceedc28, 0x2cf71238, 0x2cff48a9, 0x2d077f7a,
+0x2d0fb6ab, 0x2d17ee3c, 0x2d20262c, 0x2d285e7d, 0x2d30972d, 0x2d38d03d, 0x2d4109ac, 0x2d49437c,
+0x2d517daa, 0x2d59b839, 0x2d61f327, 0x2d6a2e75, 0x2d726a22, 0x2d7aa62e, 0x2d82e29b, 0x2d8b1f66,
+0x2d935c91, 0x2d9b9a1b, 0x2da3d804, 0x2dac164d, 0x2db454f5, 0x2dbc93fc, 0x2dc4d363, 0x2dcd1328,
+0x2dd5534d, 0x2ddd93d0, 0x2de5d4b3, 0x2dee15f5, 0x2df65795, 0x2dfe9995, 0x2e06dbf4, 0x2e0f1eb1,
+0x2e1761cd, 0x2e1fa548, 0x2e27e922, 0x2e302d5a, 0x2e3871f2, 0x2e40b6e8, 0x2e48fc3c, 0x2e5141ef,
+0x2e598801, 0x2e61ce71, 0x2e6a1540, 0x2e725c6d, 0x2e7aa3f9, 0x2e82ebe3, 0x2e8b342b, 0x2e937cd2,
+0x2e9bc5d7, 0x2ea40f3b, 0x2eac58fc, 0x2eb4a31c, 0x2ebced9a, 0x2ec53876, 0x2ecd83b0, 0x2ed5cf49,
+0x2ede1b3f, 0x2ee66794, 0x2eeeb446, 0x2ef70156, 0x2eff4ec5, 0x2f079c91, 0x2f0feabb, 0x2f183942,
+0x2f208828, 0x2f28d76b, 0x2f31270c, 0x2f39770b, 0x2f41c768, 0x2f4a1822, 0x2f526939, 0x2f5abaaf,
+0x2f630c81, 0x2f6b5eb2, 0x2f73b13f, 0x2f7c042a, 0x2f845773, 0x2f8cab19, 0x2f94ff1c, 0x2f9d537d,
+0x2fa5a83a, 0x2fadfd56, 0x2fb652ce, 0x2fbea8a3, 0x2fc6fed6, 0x2fcf5566, 0x2fd7ac52, 0x2fe0039c,
+0x2fe85b43, 0x2ff0b347, 0x2ff90ba8, 0x30016466, 0x3009bd80, 0x301216f8, 0x301a70cc, 0x3022cafd,
+0x302b258b, 0x30338076, 0x303bdbbd, 0x30443761, 0x304c9362, 0x3054efbf, 0x305d4c79, 0x3065a98f,
+0x306e0702, 0x307664d2, 0x307ec2fe, 0x30872186, 0x308f806b, 0x3097dfac, 0x30a03f49, 0x30a89f43,
+0x30b0ff99, 0x30b9604b, 0x30c1c159, 0x30ca22c4, 0x30d2848a, 0x30dae6ad, 0x30e3492c, 0x30ebac07,
+0x30f40f3e, 0x30fc72d1, 0x3104d6c0, 0x310d3b0b, 0x31159fb1, 0x311e04b4, 0x31266a12, 0x312ecfcd,
+0x313735e3, 0x313f9c55, 0x31480322, 0x31506a4b, 0x3158d1d0, 0x316139b0, 0x3169a1ed, 0x31720a84,
+0x317a7377, 0x3182dcc6, 0x318b4670, 0x3193b076, 0x319c1ad6, 0x31a48593, 0x31acf0aa, 0x31b55c1d,
+0x31bdc7ec, 0x31c63415, 0x31cea09a, 0x31d70d7a, 0x31df7ab5, 0x31e7e84b, 0x31f0563d, 0x31f8c489,
+0x32013331, 0x3209a233, 0x32121191, 0x321a8149, 0x3222f15d, 0x322b61cb, 0x3233d294, 0x323c43b8,
+0x3244b537, 0x324d2711, 0x32559945, 0x325e0bd4, 0x32667ebe, 0x326ef202, 0x327765a1, 0x327fd99b,
+0x32884def, 0x3290c29e, 0x329937a7, 0x32a1ad0b, 0x32aa22c9, 0x32b298e2, 0x32bb0f55, 0x32c38622,
+0x32cbfd4a, 0x32d474cc, 0x32dceca8, 0x32e564df, 0x32eddd70, 0x32f6565b, 0x32fecfa0, 0x3307493f,
+0x330fc338, 0x33183d8c, 0x3320b839, 0x33293341, 0x3331aea2, 0x333a2a5e, 0x3342a673, 0x334b22e2,
+0x33539fab, 0x335c1cce, 0x33649a4b, 0x336d1821, 0x33759652, 0x337e14dc, 0x338693bf, 0x338f12fd,
+0x33979294, 0x33a01284, 0x33a892cf, 0x33b11372, 0x33b9946f, 0x33c215c6, 0x33ca9776, 0x33d31980,
+0x33db9be3, 0x33e41ea0, 0x33eca1b5, 0x33f52524, 0x33fda8ed, 0x34062d0e, 0x340eb189, 0x3417365d,
+0x341fbb8b, 0x34284111, 0x3430c6f1, 0x34394d29, 0x3441d3bb, 0x344a5aa6, 0x3452e1e9, 0x345b6986,
+0x3463f17c, 0x346c79ca, 0x34750272, 0x347d8b72, 0x348614cb, 0x348e9e7d, 0x34972888, 0x349fb2eb,
+0x34a83da8, 0x34b0c8bd, 0x34b9542a, 0x34c1dff0, 0x34ca6c0f, 0x34d2f887, 0x34db8557, 0x34e4127f,
+0x34eca000, 0x34f52dda, 0x34fdbc0c, 0x35064a96, 0x350ed979, 0x351768b4, 0x351ff847, 0x35288833,
+0x35311877, 0x3539a913, 0x35423a08, 0x354acb54, 0x35535cf9, 0x355beef6, 0x3564814b, 0x356d13f8,
+0x3575a6fe, 0x357e3a5b, 0x3586ce10, 0x358f621d, 0x3597f682, 0x35a08b40, 0x35a92055, 0x35b1b5c1,
+0x35ba4b86, 0x35c2e1a3, 0x35cb7817, 0x35d40ee3, 0x35dca607, 0x35e53d82, 0x35edd555, 0x35f66d80,
+0x35ff0602, 0x36079edc, 0x3610380e, 0x3618d197, 0x36216b77, 0x362a05af, 0x3632a03f, 0x363b3b26,
+0x3643d664, 0x364c71fa, 0x36550de7, 0x365daa2b, 0x366646c7, 0x366ee3ba, 0x36778104, 0x36801ea5,
+0x3688bc9e, 0x36915aee, 0x3699f994, 0x36a29892, 0x36ab37e7, 0x36b3d793, 0x36bc7796, 0x36c517f1,
+0x36cdb8a2, 0x36d659aa, 0x36defb08, 0x36e79cbe, 0x36f03ecb, 0x36f8e12e, 0x370183e9, 0x370a26fa,
+0x3712ca62, 0x371b6e20, 0x37241235, 0x372cb6a1, 0x37355b64, 0x373e007d, 0x3746a5ed, 0x374f4bb3,
+0x3757f1d0, 0x37609844, 0x37693f0e, 0x3771e62e, 0x377a8da5, 0x37833572, 0x378bdd96, 0x37948610,
+0x379d2ee0, 0x37a5d807, 0x37ae8183, 0x37b72b57, 0x37bfd580, 0x37c87fff, 0x37d12ad5, 0x37d9d601,
+0x37e28183, 0x37eb2d5b, 0x37f3d989, 0x37fc860e, 0x380532e8, 0x380de018, 0x38168d9e, 0x381f3b7b,
+0x3827e9ad, 0x38309835, 0x38394712, 0x3841f646, 0x384aa5d0, 0x385355af, 0x385c05e4, 0x3864b66f,
+0x386d674f, 0x38761885, 0x387eca11, 0x38877bf2, 0x38902e29, 0x3898e0b6, 0x38a19398, 0x38aa46d0,
+0x38b2fa5d, 0x38bbae40, 0x38c46278, 0x38cd1705, 0x38d5cbe8, 0x38de8120, 0x38e736ae, 0x38efec91,
+0x38f8a2c9, 0x39015957, 0x390a103a, 0x3912c772, 0x391b7eff, 0x392436e1, 0x392cef19, 0x3935a7a5,
+0x393e6087, 0x394719be, 0x394fd34a, 0x39588d2b, 0x39614760, 0x396a01eb, 0x3972bccb, 0x397b7800,
+0x39843389, 0x398cef68, 0x3995ab9b, 0x399e6823, 0x39a72500, 0x39afe232, 0x39b89fb8, 0x39c15d93,
+0x39ca1bc3, 0x39d2da47, 0x39db9921, 0x39e4584e, 0x39ed17d1, 0x39f5d7a8, 0x39fe97d3, 0x3a075853,
+0x3a101927, 0x3a18da50, 0x3a219bce, 0x3a2a5d9f, 0x3a331fc5, 0x3a3be240, 0x3a44a50f, 0x3a4d6832,
+0x3a562ba9, 0x3a5eef75, 0x3a67b395, 0x3a707809, 0x3a793cd2, 0x3a8201ee, 0x3a8ac75f, 0x3a938d24,
+0x3a9c533d, 0x3aa519aa, 0x3aade06b, 0x3ab6a780, 0x3abf6ee9, 0x3ac836a6, 0x3ad0feb7, 0x3ad9c71c,
+0x3ae28fd5, 0x3aeb58e1, 0x3af42242, 0x3afcebf6, 0x3b05b5fe, 0x3b0e805a, 0x3b174b0a, 0x3b20160d,
+0x3b28e164, 0x3b31ad0f, 0x3b3a790e, 0x3b434560, 0x3b4c1205, 0x3b54deff, 0x3b5dac4b, 0x3b6679ec,
+0x3b6f47e0, 0x3b781627, 0x3b80e4c2, 0x3b89b3b0, 0x3b9282f2, 0x3b9b5287, 0x3ba4226f, 0x3bacf2ab,
+0x3bb5c33a, 0x3bbe941c, 0x3bc76552, 0x3bd036db, 0x3bd908b7, 0x3be1dae6, 0x3beaad69, 0x3bf3803e,
+0x3bfc5367, 0x3c0526e3, 0x3c0dfab2, 0x3c16ced4, 0x3c1fa349, 0x3c287811, 0x3c314d2c, 0x3c3a229a,
+0x3c42f85b, 0x3c4bce6f, 0x3c54a4d5, 0x3c5d7b8f, 0x3c66529b, 0x3c6f29fa, 0x3c7801ac, 0x3c80d9b1,
+0x3c89b209, 0x3c928ab3, 0x3c9b63b0, 0x3ca43cff, 0x3cad16a2, 0x3cb5f097, 0x3cbecade, 0x3cc7a578,
+0x3cd08065, 0x3cd95ba4, 0x3ce23736, 0x3ceb131a, 0x3cf3ef50, 0x3cfccbd9, 0x3d05a8b5, 0x3d0e85e3,
+0x3d176363, 0x3d204136, 0x3d291f5b, 0x3d31fdd2, 0x3d3adc9b, 0x3d43bbb7, 0x3d4c9b25, 0x3d557ae5,
+0x3d5e5af7, 0x3d673b5c, 0x3d701c13, 0x3d78fd1b, 0x3d81de76, 0x3d8ac023, 0x3d93a222, 0x3d9c8473,
+0x3da56716, 0x3dae4a0b, 0x3db72d52, 0x3dc010eb, 0x3dc8f4d6, 0x3dd1d912, 0x3ddabda1, 0x3de3a281,
+0x3dec87b3, 0x3df56d37, 0x3dfe530d, 0x3e073934, 0x3e101fad, 0x3e190678, 0x3e21ed95, 0x3e2ad503,
+0x3e33bcc3, 0x3e3ca4d4, 0x3e458d37, 0x3e4e75ec, 0x3e575ef2, 0x3e60484a, 0x3e6931f3, 0x3e721bed,
+0x3e7b0639, 0x3e83f0d7, 0x3e8cdbc6, 0x3e95c706, 0x3e9eb298, 0x3ea79e7a, 0x3eb08aaf, 0x3eb97734,
+0x3ec2640b, 0x3ecb5133, 0x3ed43eac, 0x3edd2c77, 0x3ee61a93, 0x3eef08ff, 0x3ef7f7bd, 0x3f00e6cc,
+0x3f09d62c, 0x3f12c5de, 0x3f1bb5e0, 0x3f24a633, 0x3f2d96d7, 0x3f3687cd, 0x3f3f7913, 0x3f486aaa,
+0x3f515c92, 0x3f5a4ecb, 0x3f634155, 0x3f6c342f, 0x3f75275b, 0x3f7e1ad7, 0x3f870ea4, 0x3f9002c2,
+0x3f98f730, 0x3fa1ebef, 0x3faae0ff, 0x3fb3d660, 0x3fbccc11, 0x3fc5c213, 0x3fceb865, 0x3fd7af08,
+0x3fe0a5fc, 0x3fe99d40, 0x3ff294d4, 0x3ffb8cb9, 0x400484ef, 0x400d7d75, 0x4016764b, 0x401f6f72,
+0x402868e9, 0x403162b1, 0x403a5cc8, 0x40435730, 0x404c51e9, 0x40554cf2, 0x405e484b, 0x406743f4,
+0x40703fed, 0x40793c37, 0x408238d0, 0x408b35ba, 0x409432f4, 0x409d307e, 0x40a62e58, 0x40af2c82,
+0x40b82afd, 0x40c129c7, 0x40ca28e1, 0x40d3284b, 0x40dc2805, 0x40e5280f, 0x40ee2869, 0x40f72913,
+0x41002a0c, 0x41092b56, 0x41122cef, 0x411b2ed8, 0x41243111, 0x412d3399, 0x41363672, 0x413f399a,
+0x41483d11, 0x415140d9, 0x415a44f0, 0x41634956, 0x416c4e0c, 0x41755312, 0x417e5867, 0x41875e0c,
+0x41906401, 0x41996a44, 0x41a270d8, 0x41ab77ba, 0x41b47eed, 0x41bd866e, 0x41c68e3f, 0x41cf965f,
+0x41d89ecf, 0x41e1a78e, 0x41eab09c, 0x41f3b9fa, 0x41fcc3a6, 0x4205cda2, 0x420ed7ee, 0x4217e288,
+0x4220ed72, 0x4229f8aa, 0x42330432, 0x423c1009, 0x42451c2f, 0x424e28a4, 0x42573569, 0x4260427c,
+0x42694fde, 0x42725d8f, 0x427b6b8f, 0x428479de, 0x428d887c, 0x42969769, 0x429fa6a5, 0x42a8b62f,
+0x42b1c609, 0x42bad631, 0x42c3e6a8, 0x42ccf76e, 0x42d60882, 0x42df19e5, 0x42e82b97, 0x42f13d98,
+0x42fa4fe7, 0x43036285, 0x430c7572, 0x431588ad, 0x431e9c37, 0x4327b00f, 0x4330c436, 0x4339d8ab,
+0x4342ed6f, 0x434c0282, 0x435517e3, 0x435e2d92, 0x4367438f, 0x437059dc, 0x43797076, 0x4382875f,
+0x438b9e96, 0x4394b61b, 0x439dcdef, 0x43a6e611, 0x43affe81, 0x43b91740, 0x43c2304d, 0x43cb49a8,
+0x43d46351, 0x43dd7d48, 0x43e6978d, 0x43efb221, 0x43f8cd02, 0x4401e832, 0x440b03af, 0x44141f7b,
+0x441d3b95, 0x442657fc, 0x442f74b2, 0x443891b6, 0x4441af07, 0x444acca7, 0x4453ea94, 0x445d08cf,
+0x44662758, 0x446f462f, 0x44786553, 0x448184c6, 0x448aa486, 0x4493c494, 0x449ce4f0, 0x44a60599,
+0x44af2690, 0x44b847d5, 0x44c16967, 0x44ca8b47, 0x44d3ad74, 0x44dccfef, 0x44e5f2b8, 0x44ef15ce,
+0x44f83932, 0x45015ce3, 0x450a80e2, 0x4513a52e, 0x451cc9c8, 0x4525eeaf, 0x452f13e3, 0x45383965,
+0x45415f34, 0x454a8551, 0x4553abbb, 0x455cd272, 0x4565f976, 0x456f20c8, 0x45784867, 0x45817053,
+0x458a988c, 0x4593c113, 0x459ce9e7, 0x45a61307, 0x45af3c75, 0x45b86630, 0x45c19039, 0x45caba8e,
+0x45d3e530, 0x45dd101f, 0x45e63b5c, 0x45ef66e5, 0x45f892bb, 0x4601bede, 0x460aeb4e, 0x4614180b,
+0x461d4515, 0x4626726c, 0x462fa00f, 0x4638ce00, 0x4641fc3d, 0x464b2ac7, 0x4654599e, 0x465d88c1,
+0x4666b832, 0x466fe7ef, 0x467917f8, 0x4682484e, 0x468b78f1, 0x4694a9e1, 0x469ddb1d, 0x46a70ca6,
+0x46b03e7b, 0x46b9709d, 0x46c2a30c, 0x46cbd5c7, 0x46d508ce, 0x46de3c22, 0x46e76fc2, 0x46f0a3af,
+0x46f9d7e9, 0x47030c6e, 0x470c4140, 0x4715765f, 0x471eabc9, 0x4727e180, 0x47311784, 0x473a4dd3,
+0x4743846f, 0x474cbb57, 0x4755f28c, 0x475f2a0c, 0x476861d9, 0x477199f2, 0x477ad257, 0x47840b08,
+0x478d4405, 0x47967d4f, 0x479fb6e4, 0x47a8f0c5, 0x47b22af3, 0x47bb656c, 0x47c4a032, 0x47cddb43,
+0x47d716a1, 0x47e0524a, 0x47e98e40, 0x47f2ca81, 0x47fc070e, 0x480543e7, 0x480e810c, 0x4817be7c,
+0x4820fc39, 0x482a3a41, 0x48337895, 0x483cb735, 0x4845f620, 0x484f3557, 0x485874da, 0x4861b4a8,
+0x486af4c3, 0x48743528, 0x487d75da, 0x4886b6d7, 0x488ff81f, 0x489939b3, 0x48a27b93, 0x48abbdbe,
+0x48b50035, 0x48be42f7, 0x48c78605, 0x48d0c95e, 0x48da0d02, 0x48e350f2, 0x48ec952e, 0x48f5d9b4,
+0x48ff1e86, 0x490863a4, 0x4911a90c, 0x491aeec0, 0x492434bf, 0x492d7b0a, 0x4936c1a0, 0x49400881,
+0x49494fad, 0x49529724, 0x495bdee7, 0x496526f4, 0x496e6f4d, 0x4977b7f1, 0x498100e0, 0x498a4a1a,
+0x4993939f, 0x499cdd6f, 0x49a6278a, 0x49af71f0, 0x49b8bca2, 0x49c2079e, 0x49cb52e5, 0x49d49e77,
+0x49ddea53, 0x49e7367b, 0x49f082ee, 0x49f9cfab, 0x4a031cb4, 0x4a0c6a07, 0x4a15b7a5, 0x4a1f058d,
+0x4a2853c1, 0x4a31a23f, 0x4a3af108, 0x4a44401b, 0x4a4d8f7a, 0x4a56df23, 0x4a602f16, 0x4a697f55,
+0x4a72cfdd, 0x4a7c20b1, 0x4a8571cf, 0x4a8ec337, 0x4a9814eb, 0x4aa166e8, 0x4aaab930, 0x4ab40bc3,
+0x4abd5ea0, 0x4ac6b1c8, 0x4ad0053a, 0x4ad958f6, 0x4ae2acfd, 0x4aec014e, 0x4af555e9, 0x4afeaacf,
+0x4b07ffff, 0x4b11557a, 0x4b1aab3f, 0x4b24014e, 0x4b2d57a7, 0x4b36ae4b, 0x4b400538, 0x4b495c70,
+0x4b52b3f2, 0x4b5c0bbf, 0x4b6563d5, 0x4b6ebc36, 0x4b7814e0, 0x4b816dd5, 0x4b8ac714, 0x4b94209d,
+0x4b9d7a6f, 0x4ba6d48c, 0x4bb02ef3, 0x4bb989a4, 0x4bc2e49f, 0x4bcc3fe4, 0x4bd59b72, 0x4bdef74b,
+0x4be8536e, 0x4bf1afda, 0x4bfb0c90, 0x4c046990, 0x4c0dc6da, 0x4c17246e, 0x4c20824b, 0x4c29e073,
+0x4c333ee4, 0x4c3c9d9e, 0x4c45fca3, 0x4c4f5bf1, 0x4c58bb89, 0x4c621b6a, 0x4c6b7b95, 0x4c74dc0a,
+0x4c7e3cc9, 0x4c879dd0, 0x4c90ff22, 0x4c9a60bd, 0x4ca3c2a2, 0x4cad24d0, 0x4cb68747, 0x4cbfea09,
+0x4cc94d13, 0x4cd2b067, 0x4cdc1405, 0x4ce577ec, 0x4ceedc1c, 0x4cf84096, 0x4d01a559, 0x4d0b0a65,
+0x4d146fbb, 0x4d1dd55a, 0x4d273b42, 0x4d30a174, 0x4d3a07ee, 0x4d436eb2, 0x4d4cd5c0, 0x4d563d16,
+0x4d5fa4b6, 0x4d690c9f, 0x4d7274d1, 0x4d7bdd4c, 0x4d854610, 0x4d8eaf1e, 0x4d981874, 0x4da18214,
+0x4daaebfc, 0x4db4562e, 0x4dbdc0a8, 0x4dc72b6c, 0x4dd09679, 0x4dda01ce, 0x4de36d6d, 0x4decd954,
+0x4df64584, 0x4dffb1fe, 0x4e091ec0, 0x4e128bcb, 0x4e1bf91f, 0x4e2566bb, 0x4e2ed4a1, 0x4e3842cf,
+0x4e41b146, 0x4e4b2006, 0x4e548f0e, 0x4e5dfe5f, 0x4e676df9, 0x4e70dddc, 0x4e7a4e07, 0x4e83be7b,
+0x4e8d2f38, 0x4e96a03d, 0x4ea0118b, 0x4ea98321, 0x4eb2f500, 0x4ebc6728, 0x4ec5d998, 0x4ecf4c50,
+0x4ed8bf51, 0x4ee2329b, 0x4eeba62d, 0x4ef51a07, 0x4efe8e2a, 0x4f080296, 0x4f117749, 0x4f1aec45,
+0x4f24618a, 0x4f2dd717, 0x4f374cec, 0x4f40c309, 0x4f4a396f, 0x4f53b01d, 0x4f5d2713, 0x4f669e52,
+0x4f7015d9, 0x4f798da8, 0x4f8305bf, 0x4f8c7e1e, 0x4f95f6c6, 0x4f9f6fb5, 0x4fa8e8ed, 0x4fb2626d,
+0x4fbbdc35, 0x4fc55645, 0x4fced09d, 0x4fd84b3e, 0x4fe1c626, 0x4feb4156, 0x4ff4bcce, 0x4ffe388f,
+0x5007b497, 0x501130e7, 0x501aad7f, 0x50242a5f, 0x502da787, 0x503724f7, 0x5040a2ae, 0x504a20ae,
+0x50539ef5, 0x505d1d84, 0x50669c5b, 0x50701b7a, 0x50799ae0, 0x50831a8e, 0x508c9a84, 0x50961ac2,
+0x509f9b47, 0x50a91c14, 0x50b29d29, 0x50bc1e85, 0x50c5a029, 0x50cf2215, 0x50d8a448, 0x50e226c2,
+0x50eba985, 0x50f52c8f, 0x50feafe0, 0x51083379, 0x5111b759, 0x511b3b81, 0x5124bff1, 0x512e44a7,
+0x5137c9a6, 0x51414eeb, 0x514ad478, 0x51545a4d, 0x515de069, 0x516766cc, 0x5170ed76, 0x517a7468,
+0x5183fba1, 0x518d8322, 0x51970ae9, 0x51a092f8, 0x51aa1b4e, 0x51b3a3ec, 0x51bd2cd0, 0x51c6b5fc,
+0x51d03f6f, 0x51d9c929, 0x51e3532b, 0x51ecdd73, 0x51f66802, 0x51fff2d9, 0x52097df7, 0x5213095b,
+0x521c9507, 0x522620fa, 0x522fad34, 0x523939b5, 0x5242c67c, 0x524c538b, 0x5255e0e1, 0x525f6e7e,
+0x5268fc61, 0x52728a8c, 0x527c18fd, 0x5285a7b5, 0x528f36b4, 0x5298c5fa, 0x52a25587, 0x52abe55a,
+0x52b57575, 0x52bf05d6, 0x52c8967d, 0x52d2276c, 0x52dbb8a1, 0x52e54a1d, 0x52eedbe0, 0x52f86de9,
+0x53020039, 0x530b92d0, 0x531525ad, 0x531eb8d1, 0x53284c3c, 0x5331dfed, 0x533b73e4, 0x53450823,
+0x534e9ca7, 0x53583173, 0x5361c684, 0x536b5bdc, 0x5374f17b, 0x537e8760, 0x53881d8c, 0x5391b3fe,
+0x539b4ab6, 0x53a4e1b5, 0x53ae78fa, 0x53b81086, 0x53c1a858, 0x53cb4070, 0x53d4d8ce, 0x53de7173,
+0x53e80a5e, 0x53f1a390, 0x53fb3d07, 0x5404d6c5, 0x540e70c9, 0x54180b13, 0x5421a5a4, 0x542b407a,
+0x5434db97, 0x543e76fa, 0x544812a3, 0x5451ae92, 0x545b4ac8, 0x5464e743, 0x546e8404, 0x5478210c,
+0x5481be59, 0x548b5bed, 0x5494f9c6, 0x549e97e5, 0x54a8364b, 0x54b1d4f6, 0x54bb73e8, 0x54c5131f,
+0x54ceb29c, 0x54d8525f, 0x54e1f268, 0x54eb92b6, 0x54f5334b, 0x54fed425, 0x55087546, 0x551216ac,
+0x551bb858, 0x55255a49, 0x552efc80, 0x55389efe, 0x554241c0, 0x554be4c9, 0x55558817, 0x555f2bab,
+0x5568cf84, 0x557273a3, 0x557c1808, 0x5585bcb3, 0x558f61a3, 0x559906d8, 0x55a2ac53, 0x55ac5214,
+0x55b5f81a, 0x55bf9e66, 0x55c944f7, 0x55d2ebce, 0x55dc92ea, 0x55e63a4c, 0x55efe1f3, 0x55f989e0,
+0x56033212, 0x560cda89, 0x56168346, 0x56202c48, 0x5629d58f, 0x56337f1c, 0x563d28ee, 0x5646d306,
+0x56507d62, 0x565a2804, 0x5663d2ec, 0x566d7e18, 0x5677298a, 0x5680d541, 0x568a813d, 0x56942d7e,
+0x569dda05, 0x56a786d1, 0x56b133e1, 0x56bae137, 0x56c48ed2, 0x56ce3cb3, 0x56d7ead8, 0x56e19942,
+0x56eb47f1, 0x56f4f6e6, 0x56fea61f, 0x5708559e, 0x57120561, 0x571bb569, 0x572565b7, 0x572f1649,
+0x5738c720, 0x5742783c, 0x574c299e, 0x5755db43, 0x575f8d2e, 0x57693f5e, 0x5772f1d2, 0x577ca48c,
+0x5786578a, 0x57900acd, 0x5799be54, 0x57a37221, 0x57ad2632, 0x57b6da88, 0x57c08f23, 0x57ca4402,
+0x57d3f926, 0x57ddae8f, 0x57e7643c, 0x57f11a2f, 0x57fad065, 0x580486e1, 0x580e3da1, 0x5817f4a5,
+0x5821abee, 0x582b637c, 0x58351b4e, 0x583ed365, 0x58488bc0, 0x58524460, 0x585bfd44, 0x5865b66d,
+0x586f6fda, 0x5879298b, 0x5882e381, 0x588c9dbc, 0x5896583b, 0x58a012fe, 0x58a9ce05, 0x58b38951,
+0x58bd44e2, 0x58c700b6, 0x58d0bccf, 0x58da792c, 0x58e435ce, 0x58edf2b4, 0x58f7afde, 0x59016d4c,
+0x590b2afe, 0x5914e8f5, 0x591ea730, 0x592865af, 0x59322472, 0x593be379, 0x5945a2c5, 0x594f6255,
+0x59592228, 0x5962e240, 0x596ca29c, 0x5976633c, 0x59802420, 0x5989e548, 0x5993a6b4, 0x599d6864,
+0x59a72a58, 0x59b0ec90, 0x59baaf0c, 0x59c471cc, 0x59ce34d0, 0x59d7f818, 0x59e1bba3, 0x59eb7f73,
+0x59f54386, 0x59ff07dd, 0x5a08cc79, 0x5a129158, 0x5a1c567a, 0x5a261be1, 0x5a2fe18b, 0x5a39a779,
+0x5a436dab, 0x5a4d3421, 0x5a56fada, 0x5a60c1d8, 0x5a6a8918, 0x5a74509d, 0x5a7e1865, 0x5a87e071,
+0x5a91a8c0, 0x5a9b7153, 0x5aa53a2a, 0x5aaf0344, 0x5ab8cca2, 0x5ac29644, 0x5acc6029, 0x5ad62a51,
+0x5adff4bd, 0x5ae9bf6d, 0x5af38a60, 0x5afd5597, 0x5b072111, 0x5b10ecce, 0x5b1ab8cf, 0x5b248514,
+0x5b2e519c, 0x5b381e67, 0x5b41eb76, 0x5b4bb8c8, 0x5b55865d, 0x5b5f5436, 0x5b692252, 0x5b72f0b1,
+0x5b7cbf54, 0x5b868e3a, 0x5b905d63, 0x5b9a2cd0, 0x5ba3fc7f, 0x5badcc72, 0x5bb79ca9, 0x5bc16d22,
+0x5bcb3ddf, 0x5bd50ede, 0x5bdee021, 0x5be8b1a7, 0x5bf28371, 0x5bfc557d, 0x5c0627cc, 0x5c0ffa5f,
+0x5c19cd35, 0x5c23a04d, 0x5c2d73a9, 0x5c374748, 0x5c411b2a, 0x5c4aef4e, 0x5c54c3b6, 0x5c5e9861,
+0x5c686d4f, 0x5c724280, 0x5c7c17f3, 0x5c85edaa, 0x5c8fc3a3, 0x5c9999e0, 0x5ca3705f, 0x5cad4721,
+0x5cb71e26, 0x5cc0f56e, 0x5ccaccf9, 0x5cd4a4c6, 0x5cde7cd7, 0x5ce8552a, 0x5cf22dbf, 0x5cfc0698,
+0x5d05dfb3, 0x5d0fb912, 0x5d1992b2, 0x5d236c96, 0x5d2d46bc, 0x5d372125, 0x5d40fbd1, 0x5d4ad6bf,
+0x5d54b1f0, 0x5d5e8d63, 0x5d686919, 0x5d724512, 0x5d7c214d, 0x5d85fdcb, 0x5d8fda8b, 0x5d99b78e,
+0x5da394d4, 0x5dad725c, 0x5db75026, 0x5dc12e33, 0x5dcb0c82, 0x5dd4eb14, 0x5ddec9e9, 0x5de8a8ff,
+0x5df28858, 0x5dfc67f4, 0x5e0647d2, 0x5e1027f2, 0x5e1a0855, 0x5e23e8fa, 0x5e2dc9e1, 0x5e37ab0b,
+0x5e418c77, 0x5e4b6e25, 0x5e555016, 0x5e5f3249, 0x5e6914be, 0x5e72f775, 0x5e7cda6f, 0x5e86bdab,
+0x5e90a129, 0x5e9a84e9, 0x5ea468eb, 0x5eae4d30, 0x5eb831b6, 0x5ec2167f, 0x5ecbfb8a, 0x5ed5e0d7,
+0x5edfc666, 0x5ee9ac37, 0x5ef3924a, 0x5efd78a0, 0x5f075f37, 0x5f114610, 0x5f1b2d2c, 0x5f251489,
+0x5f2efc28, 0x5f38e40a, 0x5f42cc2d, 0x5f4cb492, 0x5f569d39, 0x5f608622, 0x5f6a6f4d, 0x5f7458ba,
+0x5f7e4269, 0x5f882c5a, 0x5f92168c, 0x5f9c0100, 0x5fa5ebb6, 0x5fafd6ae, 0x5fb9c1e8, 0x5fc3ad64,
+0x5fcd9921, 0x5fd78520, 0x5fe17161, 0x5feb5de3, 0x5ff54aa7, 0x5fff37ad, 0x600924f5, 0x6013127e,
+0x601d0049, 0x6026ee56, 0x6030dca4, 0x603acb34, 0x6044ba05, 0x604ea918, 0x6058986d, 0x60628803,
+0x606c77db, 0x607667f4, 0x6080584f, 0x608a48ec, 0x609439ca, 0x609e2ae9, 0x60a81c4a, 0x60b20dec,
+0x60bbffd0, 0x60c5f1f5, 0x60cfe45c, 0x60d9d704, 0x60e3c9ed, 0x60edbd18, 0x60f7b084, 0x6101a432,
+0x610b9821, 0x61158c51, 0x611f80c3, 0x61297576, 0x61336a6a, 0x613d5f9f, 0x61475516, 0x61514ace,
+0x615b40c7, 0x61653702, 0x616f2d7e, 0x6179243a, 0x61831b38, 0x618d1278, 0x619709f8, 0x61a101ba,
+0x61aaf9bd, 0x61b4f200, 0x61beea85, 0x61c8e34b, 0x61d2dc53, 0x61dcd59b, 0x61e6cf24, 0x61f0c8ee,
+0x61fac2fa, 0x6204bd46, 0x620eb7d4, 0x6218b2a2, 0x6222adb1, 0x622ca902, 0x6236a493, 0x6240a065,
+0x624a9c78, 0x625498cd, 0x625e9562, 0x62689238, 0x62728f4e, 0x627c8ca6, 0x62868a3e, 0x62908818,
+0x629a8632, 0x62a4848d, 0x62ae8329, 0x62b88205, 0x62c28123, 0x62cc8081, 0x62d68020, 0x62e07fff,
+0x62ea8020, 0x62f48081, 0x62fe8123, 0x63088205, 0x63128328, 0x631c848c, 0x63268631, 0x63308816,
+0x633a8a3b, 0x63448ca2, 0x634e8f49, 0x63589230, 0x63629558, 0x636c98c1, 0x63769c6a, 0x6380a054,
+0x638aa47e, 0x6394a8e9, 0x639ead94, 0x63a8b280, 0x63b2b7ac, 0x63bcbd19, 0x63c6c2c6, 0x63d0c8b3,
+0x63dacee1, 0x63e4d550, 0x63eedbff, 0x63f8e2ee, 0x6402ea1d, 0x640cf18d, 0x6416f93e, 0x6421012e,
+0x642b095f, 0x643511d0, 0x643f1a82, 0x64492374, 0x64532ca6, 0x645d3618, 0x64673fcb, 0x647149bd,
+0x647b53f0, 0x64855e64, 0x648f6917, 0x6499740b, 0x64a37f3e, 0x64ad8ab2, 0x64b79666, 0x64c1a25b,
+0x64cbae8f, 0x64d5bb03, 0x64dfc7b8, 0x64e9d4ad, 0x64f3e1e1, 0x64fdef56, 0x6507fd0b, 0x65120b00,
+0x651c1934, 0x652627a9, 0x6530365e, 0x653a4553, 0x65445488, 0x654e63fd, 0x655873b1, 0x656283a6,
+0x656c93db, 0x6576a44f, 0x6580b503, 0x658ac5f8, 0x6594d72c, 0x659ee8a0, 0x65a8fa54, 0x65b30c47,
+0x65bd1e7b, 0x65c730ee, 0x65d143a1, 0x65db5694, 0x65e569c7, 0x65ef7d39, 0x65f990eb, 0x6603a4dd,
+0x660db90f, 0x6617cd80, 0x6621e231, 0x662bf722, 0x66360c52, 0x664021c2, 0x664a3772, 0x66544d62,
+0x665e6390, 0x666879ff, 0x667290ad, 0x667ca79b, 0x6686bec8, 0x6690d635, 0x669aede2, 0x66a505ce,
+0x66af1df9, 0x66b93664, 0x66c34f0f, 0x66cd67f9, 0x66d78123, 0x66e19a8c, 0x66ebb434, 0x66f5ce1c,
+0x66ffe843, 0x670a02aa, 0x67141d50, 0x671e3836, 0x6728535b, 0x67326ebf, 0x673c8a63, 0x6746a646,
+0x6750c268, 0x675adeca, 0x6764fb6b, 0x676f184b, 0x6779356a, 0x678352c9, 0x678d7067, 0x67978e45,
+0x67a1ac61, 0x67abcabd, 0x67b5e958, 0x67c00832, 0x67ca274c, 0x67d446a4, 0x67de663c, 0x67e88613,
+0x67f2a629, 0x67fcc67e, 0x6806e712, 0x681107e6, 0x681b28f8, 0x68254a4a, 0x682f6bda, 0x68398daa,
+0x6843afb9, 0x684dd206, 0x6857f493, 0x6862175f, 0x686c3a6a, 0x68765db3, 0x6880813c, 0x688aa504,
+0x6894c90a, 0x689eed50, 0x68a911d5, 0x68b33698, 0x68bd5b9a, 0x68c780dc, 0x68d1a65c, 0x68dbcc1b,
+0x68e5f218, 0x68f01855, 0x68fa3ed0, 0x6904658b, 0x690e8c84, 0x6918b3bc, 0x6922db32, 0x692d02e8,
+0x69372adc, 0x6941530f, 0x694b7b81, 0x6955a431, 0x695fcd20, 0x6969f64e, 0x69741fbb, 0x697e4966,
+0x69887350, 0x69929d78, 0x699cc7df, 0x69a6f285, 0x69b11d69, 0x69bb488c, 0x69c573ee, 0x69cf9f8e,
+0x69d9cb6d, 0x69e3f78a, 0x69ee23e6, 0x69f85080, 0x6a027d59, 0x6a0caa71, 0x6a16d7c7, 0x6a21055b,
+0x6a2b332e, 0x6a35613f, 0x6a3f8f8f, 0x6a49be1d, 0x6a53ecea, 0x6a5e1bf5, 0x6a684b3f, 0x6a727ac7,
+0x6a7caa8d, 0x6a86da91, 0x6a910ad4, 0x6a9b3b56, 0x6aa56c15, 0x6aaf9d13, 0x6ab9ce50, 0x6ac3ffca,
+0x6ace3183, 0x6ad8637b, 0x6ae295b0, 0x6aecc824, 0x6af6fad6, 0x6b012dc6, 0x6b0b60f4, 0x6b159461,
+0x6b1fc80c, 0x6b29fbf5, 0x6b34301c, 0x6b3e6481, 0x6b489925, 0x6b52ce06, 0x6b5d0326, 0x6b673884,
+0x6b716e20, 0x6b7ba3fa, 0x6b85da12, 0x6b901068, 0x6b9a46fd, 0x6ba47dcf, 0x6baeb4df, 0x6bb8ec2e,
+0x6bc323ba, 0x6bcd5b85, 0x6bd7938d, 0x6be1cbd3, 0x6bec0458, 0x6bf63d1a, 0x6c00761a, 0x6c0aaf58,
+0x6c14e8d4, 0x6c1f228e, 0x6c295c86, 0x6c3396bc, 0x6c3dd130, 0x6c480be1, 0x6c5246d1, 0x6c5c81fe,
+0x6c66bd69, 0x6c70f912, 0x6c7b34f8, 0x6c85711d, 0x6c8fad7f, 0x6c99ea1f, 0x6ca426fd, 0x6cae6418,
+0x6cb8a172, 0x6cc2df09, 0x6ccd1cdd, 0x6cd75af0, 0x6ce19940, 0x6cebd7ce, 0x6cf61699, 0x6d0055a2,
+0x6d0a94e9, 0x6d14d46d, 0x6d1f142f, 0x6d29542f, 0x6d33946c, 0x6d3dd4e7, 0x6d4815a0, 0x6d525695,
+0x6d5c97c9, 0x6d66d93a, 0x6d711ae9, 0x6d7b5cd5, 0x6d859eff, 0x6d8fe166, 0x6d9a240a, 0x6da466ec,
+0x6daeaa0c, 0x6db8ed69, 0x6dc33104, 0x6dcd74db, 0x6dd7b8f1, 0x6de1fd44, 0x6dec41d4, 0x6df686a1,
+0x6e00cbac, 0x6e0b10f5, 0x6e15567a, 0x6e1f9c3d, 0x6e29e23d, 0x6e34287b, 0x6e3e6ef6, 0x6e48b5ae,
+0x6e52fca4, 0x6e5d43d7, 0x6e678b47, 0x6e71d2f4, 0x6e7c1adf, 0x6e866307, 0x6e90ab6c, 0x6e9af40e,
+0x6ea53ced, 0x6eaf860a, 0x6eb9cf64, 0x6ec418fb, 0x6ece62cf, 0x6ed8ace0, 0x6ee2f72e, 0x6eed41ba,
+0x6ef78c83, 0x6f01d788, 0x6f0c22cb, 0x6f166e4b, 0x6f20ba08, 0x6f2b0602, 0x6f355239, 0x6f3f9ead,
+0x6f49eb5e, 0x6f54384d, 0x6f5e8578, 0x6f68d2e0, 0x6f732085, 0x6f7d6e67, 0x6f87bc86, 0x6f920ae2,
+0x6f9c597b, 0x6fa6a851, 0x6fb0f763, 0x6fbb46b3, 0x6fc59640, 0x6fcfe609, 0x6fda360f, 0x6fe48652,
+0x6feed6d2, 0x6ff9278f, 0x70037889, 0x700dc9bf, 0x70181b32, 0x70226ce3, 0x702cbecf, 0x703710f9,
+0x7041635f, 0x704bb602, 0x705608e2, 0x70605bff, 0x706aaf58, 0x707502ee, 0x707f56c1, 0x7089aad0,
+0x7093ff1c, 0x709e53a5, 0x70a8a86a, 0x70b2fd6c, 0x70bd52ab, 0x70c7a826, 0x70d1fdde, 0x70dc53d2,
+0x70e6aa03, 0x70f10071, 0x70fb571b, 0x7105ae02, 0x71100525, 0x711a5c85, 0x7124b421, 0x712f0bfa,
+0x7139640f, 0x7143bc61, 0x714e14ef, 0x71586dba, 0x7162c6c1, 0x716d2004, 0x71777984, 0x7181d341,
+0x718c2d3a, 0x7196876f, 0x71a0e1e1, 0x71ab3c8f, 0x71b59779, 0x71bff2a0, 0x71ca4e03, 0x71d4a9a3,
+0x71df057e, 0x71e96197, 0x71f3bdeb, 0x71fe1a7c, 0x72087749, 0x7212d452, 0x721d3197, 0x72278f19,
+0x7231ecd7, 0x723c4ad1, 0x7246a908, 0x7251077b, 0x725b6629, 0x7265c514, 0x7270243c, 0x727a839f,
+0x7284e33f, 0x728f431a, 0x7299a332, 0x72a40386, 0x72ae6416, 0x72b8c4e2, 0x72c325eb, 0x72cd872f,
+0x72d7e8af, 0x72e24a6c, 0x72ecac64, 0x72f70e99, 0x73017109, 0x730bd3b6, 0x7316369f, 0x732099c3,
+0x732afd24, 0x733560c0, 0x733fc499, 0x734a28ad, 0x73548cfe, 0x735ef18a, 0x73695652, 0x7373bb57,
+0x737e2097, 0x73888613, 0x7392ebca, 0x739d51be, 0x73a7b7ee, 0x73b21e59, 0x73bc8500, 0x73c6ebe4,
+0x73d15302, 0x73dbba5d, 0x73e621f4, 0x73f089c6, 0x73faf1d4, 0x74055a1e, 0x740fc2a3, 0x741a2b65,
+0x74249462, 0x742efd9b, 0x7439670f, 0x7443d0bf, 0x744e3aab, 0x7458a4d3, 0x74630f36, 0x746d79d5,
+0x7477e4af, 0x74824fc6, 0x748cbb17, 0x749726a5, 0x74a1926e, 0x74abfe73, 0x74b66ab3, 0x74c0d72f,
+0x74cb43e6, 0x74d5b0d9, 0x74e01e07, 0x74ea8b71, 0x74f4f917, 0x74ff66f8, 0x7509d514, 0x7514436c,
+0x751eb200, 0x752920cf, 0x75338fd9, 0x753dff1f, 0x75486ea1, 0x7552de5d, 0x755d4e56, 0x7567be89,
+0x75722ef8, 0x757c9fa3, 0x75871089, 0x759181aa, 0x759bf306, 0x75a6649e, 0x75b0d671, 0x75bb4880,
+0x75c5baca, 0x75d02d4f, 0x75daa00f, 0x75e5130b, 0x75ef8642, 0x75f9f9b4, 0x76046d62, 0x760ee14b,
+0x7619556f, 0x7623c9ce, 0x762e3e68, 0x7638b33e, 0x7643284f, 0x764d9d9b, 0x76581322, 0x766288e4,
+0x766cfee2, 0x7677751b, 0x7681eb8e, 0x768c623d, 0x7696d927, 0x76a1504d, 0x76abc7ad, 0x76b63f48,
+0x76c0b71f, 0x76cb2f30, 0x76d5a77d, 0x76e02004, 0x76ea98c7, 0x76f511c4, 0x76ff8afd, 0x770a0471,
+0x77147e1f, 0x771ef809, 0x7729722d, 0x7733ec8d, 0x773e6727, 0x7748e1fd, 0x77535d0d, 0x775dd858,
+0x776853df, 0x7772cfa0, 0x777d4b9c, 0x7787c7d2, 0x77924444, 0x779cc0f1, 0x77a73dd8, 0x77b1bafa,
+0x77bc3858, 0x77c6b5ef, 0x77d133c2, 0x77dbb1d0, 0x77e63018, 0x77f0ae9b, 0x77fb2d59, 0x7805ac52,
+0x78102b85, 0x781aaaf3, 0x78252a9c, 0x782faa80, 0x783a2a9e, 0x7844aaf7, 0x784f2b8a, 0x7859ac59,
+0x78642d62, 0x786eaea5, 0x78793024, 0x7883b1dd, 0x788e33d0, 0x7898b5fe, 0x78a33867, 0x78adbb0b,
+0x78b83de9, 0x78c2c101, 0x78cd4454, 0x78d7c7e2, 0x78e24baa, 0x78eccfad, 0x78f753ea, 0x7901d862,
+0x790c5d15, 0x7916e202, 0x79216729, 0x792bec8b, 0x79367227, 0x7940f7fe, 0x794b7e0f, 0x7956045b,
+0x79608ae1, 0x796b11a1, 0x7975989c, 0x79801fd1, 0x798aa741, 0x79952eeb, 0x799fb6d0, 0x79aa3eee,
+0x79b4c748, 0x79bf4fdb, 0x79c9d8a9, 0x79d461b1, 0x79deeaf4, 0x79e97470, 0x79f3fe27, 0x79fe8819,
+0x7a091244, 0x7a139caa, 0x7a1e274a, 0x7a28b225, 0x7a333d39, 0x7a3dc888, 0x7a485411, 0x7a52dfd4,
+0x7a5d6bd2, 0x7a67f809, 0x7a72847b, 0x7a7d1127, 0x7a879e0d, 0x7a922b2e, 0x7a9cb888, 0x7aa7461d,
+0x7ab1d3eb, 0x7abc61f4, 0x7ac6f037, 0x7ad17eb4, 0x7adc0d6b, 0x7ae69c5c, 0x7af12b87, 0x7afbbaec,
+0x7b064a8b, 0x7b10da64, 0x7b1b6a78, 0x7b25fac5, 0x7b308b4c, 0x7b3b1c0e, 0x7b45ad09, 0x7b503e3e,
+0x7b5acfad, 0x7b656156, 0x7b6ff339, 0x7b7a8556, 0x7b8517ad, 0x7b8faa3e, 0x7b9a3d09, 0x7ba4d00d,
+0x7baf634c, 0x7bb9f6c4, 0x7bc48a76, 0x7bcf1e62, 0x7bd9b288, 0x7be446e8, 0x7beedb82, 0x7bf97055,
+0x7c040562, 0x7c0e9aa9, 0x7c19302a, 0x7c23c5e5, 0x7c2e5bd9, 0x7c38f207, 0x7c43886f, 0x7c4e1f10,
+0x7c58b5ec, 0x7c634d01, 0x7c6de450, 0x7c787bd8, 0x7c83139a, 0x7c8dab96, 0x7c9843cb, 0x7ca2dc3a,
+0x7cad74e3, 0x7cb80dc6, 0x7cc2a6e2, 0x7ccd4037, 0x7cd7d9c7, 0x7ce27390, 0x7ced0d92, 0x7cf7a7ce,
+0x7d024244, 0x7d0cdcf3, 0x7d1777dc, 0x7d2212fe, 0x7d2cae5a, 0x7d3749ef, 0x7d41e5be, 0x7d4c81c7,
+0x7d571e08, 0x7d61ba84, 0x7d6c5739, 0x7d76f427, 0x7d81914f, 0x7d8c2eb0, 0x7d96cc4b, 0x7da16a1f,
+0x7dac082d, 0x7db6a673, 0x7dc144f4, 0x7dcbe3ae, 0x7dd682a1, 0x7de121cd, 0x7debc133, 0x7df660d2,
+0x7e0100ab, 0x7e0ba0bd, 0x7e164108, 0x7e20e18d, 0x7e2b824b, 0x7e362342, 0x7e40c472, 0x7e4b65dc,
+0x7e56077f, 0x7e60a95b, 0x7e6b4b71, 0x7e75edc0, 0x7e809048, 0x7e8b3309, 0x7e95d603, 0x7ea07937,
+0x7eab1ca4, 0x7eb5c04a, 0x7ec06429, 0x7ecb0842, 0x7ed5ac93, 0x7ee0511e, 0x7eeaf5e2, 0x7ef59adf,
+0x7f004015, 0x7f0ae584, 0x7f158b2c, 0x7f20310e, 0x7f2ad728, 0x7f357d7c, 0x7f402409, 0x7f4acace,
+0x7f5571cd, 0x7f601905, 0x7f6ac076, 0x7f75681f, 0x7f801002, 0x7f8ab81e, 0x7f956073, 0x7fa00901,
+0x7faab1c7, 0x7fb55ac7, 0x7fc00400, 0x7fcaad71, 0x7fd5571c, 0x7fe00100, 0x7feaab1c, 0x7ff55571,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,
+0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_aa_cs_data[] = {
+0x00006dc2, 0x000070dc, 0x0000798d, 0x00007ddd, 0x00007f6d, 0x00007fe4, 0x00007ffc, 0x00007fff,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_aa_ca_data[] = {
+0xffffbe26, 0xffffc39f, 0xffffd7e4, 0xffffe8b8, 0xfffff3e5, 0xfffffac2, 0xfffffe2f, 0xffffff87,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_win_data[] = {
+0x00000421, 0x00000db8, 0x000019c7, 0x000029ad, 0x00003fff, 0x00006246, 0x00009ee0, 0x00012a7d,
+0x0003df40, 0xfffbc63e, 0xfffe7b01, 0xffff069e, 0xffff4338, 0xffff657e, 0xffff7bd0, 0xffff8bb6,
+0xffff97c5, 0xffffa15c, 0xffffa947, 0xffffb006, 0xffffb5eb, 0xffffbb30, 0xffffc000, 0xffffc47a,
+0xffffc8b7, 0xffffccca, 0xffffd0c5, 0xffffd4b9, 0xffffd8b4, 0xffffdcc8, 0xffffe104, 0xffffe57e,
+0xffffea4e, 0xffffef94, 0xfffff579, 0xfffffc37, 0x00000421, 0x00000db8, 0x000019c7, 0x000029ad,
+0x00003fff, 0x00006246, 0x00009ee0, 0x00012a7d, 0x0003df40, 0xfffbc63e, 0xfffe7b01, 0xffff069e,
+0xffff4338, 0xffff657e, 0xffff7bd0, 0xffff8bb6, 0xffff97c5, 0xffffa15c, 0xffffa932, 0xffffaf55,
+0xffffb41e, 0xffffb7d9, 0xffffbabb, 0xffffbce5, 0xffffbf02, 0xffffc45d, 0xffffcd2e, 0xffffd901,
+0xffffe74d, 0xfffff772, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000db8, 0x00003fff, 0x00012a7d, 0xfffe7b01, 0xffff657e, 0xffff97c5, 0xffffb006, 0xffffc000,
+0xffffccca, 0xffffd8b4, 0xffffe57e, 0xfffff579, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00002698, 0x0000bba3, 0x00037d32, 0xfffb73f7, 0xfffe3b01, 0xfffedad6,
+0xffff2b2b, 0xffff58c3, 0xffff7566, 0xffff88e3, 0xffff96df, 0xffffa145, 0xffffa947, 0xffffb006,
+0xffffb5eb, 0xffffbb30, 0xffffc000, 0xffffc47a, 0xffffc8b7, 0xffffccca, 0xffffd0c5, 0xffffd4b9,
+0xffffd8b4, 0xffffdcc8, 0xffffe104, 0xffffe57e, 0xffffea4e, 0xffffef94, 0xfffff579, 0xfffffc37,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_COS9_data[] = {
+0x00008000, 0x00007e0e, 0x00007847, 0x00006ed9, 0x0000620d, 0x00005246, 0x00004000, 0x00002bc7,
+0x0000163a,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_tfcos36_data[] = {
+0x0000403e, 0x00004241, 0x0000469d, 0x00004e21, 0x00005a82, 0x00006f94, 0x0000976f, 0x0000f746,
+0x0002de51,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_tfcos12_data[] = {
+0x00004241, 0x00005a82, 0x0000f746,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_cos9_data[] = {
+0x00007847, 0xffffe9c6, 0xffff9df3,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_cos18_data[] = {
+0x00007e0e, 0xffffd439, 0xffffadba,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_COS1_data[] = {
+0x00004deb, 0xffff89bf, 0xffffef4b, 0x00007ee7, 0xffffcf05, 0xffff9a74, 0x000030fb, 0xffff89bf,
+0x00007641, 0xffffcf05, 0xffffcf05, 0x00007641, 0x000010b5, 0xffffcf05, 0x00004deb, 0xffff9a74,
+0x00007641, 0xffff8119, 0xffffef4b, 0x000030fb, 0xffffb215, 0x0000658c, 0xffff89bf, 0x00007ee7,
+0xffffcf05, 0x00007641, 0xffff89bf, 0x000030fb, 0x000030fb, 0xffff89bf, 0xffffb215, 0x00007641,
+0x000010b5, 0xffff8119, 0x000030fb, 0x0000658c, 0xffff9a74, 0x000030fb, 0x00007ee7, 0x000010b5,
+0xffff89bf, 0xffffb215, 0xffff89bf, 0xffffcf05, 0x000030fb, 0x00007641, 0x00007641, 0x000030fb,
+0xffff8119, 0xffff89bf, 0xffff9a74, 0xffffb215, 0xffffcf05, 0xffffef4b, 0xffff8119, 0xffff89bf,
+0xffff9a74, 0xffffb215, 0xffffcf05, 0xffffef4b, 0xffff89bf, 0xffffcf05, 0x000030fb, 0x00007641,
+0x00007641, 0x000030fb, 0xffff9a74, 0x000030fb, 0x00007ee7, 0x000010b5, 0xffff89bf, 0xffffb215,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_win1_data[] = {
+0x00000421, 0xfffff248, 0x000019c7, 0xffffd653, 0x00003fff, 0xffff9dba, 0x00009ee0, 0xfffed583,
+0x0003df40, 0x000439c2, 0xfffe7b01, 0x0000f962, 0xffff4338, 0x00009a82, 0xffff7bd0, 0x0000744a,
+0xffff97c5, 0x00005ea4, 0xffffa947, 0x00004ffa, 0xffffb5eb, 0x000044d0, 0xffffc000, 0x00003b86,
+0xffffc8b7, 0x00003336, 0xffffd0c5, 0x00002b47, 0xffffd8b4, 0x00002338, 0xffffe104, 0x00001a82,
+0xffffea4e, 0x0000106c, 0xfffff579, 0x000003c9, 0x00000421, 0xfffff248, 0x000019c7, 0xffffd653,
+0x00003fff, 0xffff9dba, 0x00009ee0, 0xfffed583, 0x0003df40, 0x000439c2, 0xfffe7b01, 0x0000f962,
+0xffff4338, 0x00009a82, 0xffff7bd0, 0x0000744a, 0xffff97c5, 0x00005ea4, 0xffffa932, 0x000050ab,
+0xffffb41e, 0x00004827, 0xffffbabb, 0x0000431b, 0xffffbf02, 0x00003ba3, 0xffffcd2e, 0x000026ff,
+0xffffe74d, 0x0000088e, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000db8, 0xffffc001, 0x00012a7d, 0x000184ff, 0xffff657e, 0x0000683b, 0xffffb006, 0x00004000,
+0xffffccca, 0x0000274c, 0xffffe57e, 0x00000a87, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00002698, 0xffff445d, 0x00037d32, 0x00048c09, 0xfffe3b01, 0x0001252a,
+0xffff2b2b, 0x0000a73d, 0xffff7566, 0x0000771d, 0xffff96df, 0x00005ebb, 0xffffa947, 0x00004ffa,
+0xffffb5eb, 0x000044d0, 0xffffc000, 0x00003b86, 0xffffc8b7, 0x00003336, 0xffffd0c5, 0x00002b47,
+0xffffd8b4, 0x00002338, 0xffffe104, 0x00001a82, 0xffffea4e, 0x0000106c, 0xfffff579, 0x000003c9,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_tan1_1_data[] = {
+0x00000000, 0x00001b0c, 0x00002ed9, 0x00003fff, 0x00005126, 0x000064f3, 0x00007fff, 0x0000aed9,
+0x00012ed9, 0x7fffffff, 0xffff5127, 0xffffd127, 0x00000000, 0x00001b0c, 0x00002ed9, 0x00003fff,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_tan2_1_data[] = {
+0x00008000, 0x000064f3, 0x00005126, 0x00004000, 0x00002ed9, 0x00001b0c, 0x00000000, 0xffffd127,
+0xffff5127, 0x80000000, 0x00012ed9, 0x0000aed9, 0x00008000, 0x000064f3, 0x00005126, 0x00004000,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_tan1_2_data[] = {
+0x00000000, 0x00002640, 0x00004241, 0x00005a82, 0x000072c2, 0x00008ec3, 0x0000b504, 0x0000f746,
+0x0001ac4b, 0x7fffffff, 0xffff08ba, 0xffffbdbf, 0x00000000, 0x00002640, 0x00004241, 0x00005a82,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_tan2_2_data[] = {
+0x0000b504, 0x00008ec3, 0x000072c2, 0x00005a82, 0x00004241, 0x00002640, 0x00000000, 0xffffbdbf,
+0xffff08ba, 0x80000000, 0x0001ac4b, 0x0000f746, 0x0000b504, 0x00008ec3, 0x000072c2, 0x00005a82,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_pow1_1_data[] = {
+0x00008000, 0x00006ba2, 0x00008000, 0x00005a82, 0x00008000, 0x00004c1b, 0x00008000, 0x00004000,
+0x00008000, 0x000035d1, 0x00008000, 0x00002d41, 0x00008000, 0x0000260d, 0x00008000, 0x00002000,
+0x00008000, 0x00005a82, 0x00008000, 0x00003fff, 0x00008000, 0x00002d41, 0x00008000, 0x00001fff,
+0x00008000, 0x000016a0, 0x00008000, 0x00000fff, 0x00008000, 0x00000b50, 0x00008000, 0x000007ff,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_pow2_1_data[] = {
+0x00008000, 0x00008000, 0x00006ba2, 0x00008000, 0x00005a82, 0x00008000, 0x00004c1b, 0x00008000,
+0x00004000, 0x00008000, 0x000035d1, 0x00008000, 0x00002d41, 0x00008000, 0x0000260d, 0x00008000,
+0x00008000, 0x00008000, 0x00005a82, 0x00008000, 0x00003fff, 0x00008000, 0x00002d41, 0x00008000,
+0x00001fff, 0x00008000, 0x000016a0, 0x00008000, 0x00000fff, 0x00008000, 0x00000b50, 0x00008000,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_pow1_2_data[] = {
+0x0000b504, 0x00009837, 0x0000b504, 0x00008000, 0x0000b504, 0x00006ba2, 0x0000b504, 0x00005a82,
+0x0000b504, 0x00004c1b, 0x0000b504, 0x00004000, 0x0000b504, 0x000035d1, 0x0000b504, 0x00002d41,
+0x0000b504, 0x00008000, 0x0000b504, 0x00005a82, 0x0000b504, 0x00003fff, 0x0000b504, 0x00002d41,
+0x0000b504, 0x00001fff, 0x0000b504, 0x000016a0, 0x0000b504, 0x00000fff, 0x0000b504, 0x00000b50,};
+#endif
+#ifdef USE_DATA_TABLES
+static long mpeg3_pow2_2_data[] = {
+0x0000b504, 0x0000b504, 0x00009837, 0x0000b504, 0x00008000, 0x0000b504, 0x00006ba2, 0x0000b504,
+0x00005a82, 0x0000b504, 0x00004c1b, 0x0000b504, 0x00004000, 0x0000b504, 0x000035d1, 0x0000b504,
+0x0000b504, 0x0000b504, 0x00008000, 0x0000b504, 0x00005a82, 0x0000b504, 0x00003fff, 0x0000b504,
+0x00002d41, 0x0000b504, 0x00001fff, 0x0000b504, 0x000016a0, 0x0000b504, 0x00000fff, 0x0000b504,};
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/header.c b/core/multimedia/opieplayer/libmpeg3/audio/header.c
new file mode 100644
index 0000000..02b5e7c
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/header.c
@@ -0,0 +1,163 @@
+#include "mpeg3audio.h"
+#include "tables.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+
+#include <stdio.h>
+
+/* Return 1 if the head check doesn't find a header. */
+int mpeg3audio_head_check(unsigned long head)
+{
+ if((head & 0xffe00000) != 0xffe00000) return 1;
+ if(!((head >> 17) & 3)) return 1;
+ if(((head >> 12) & 0xf) == 0xf) return 1;
+ if(!((head >> 12) & 0xf)) return 1;
+ if(((head >> 10) & 0x3) == 0x3 ) return 1;
+ if(((head >> 19) & 1) == 1 && ((head >> 17) & 3) == 3 && ((head >> 16) & 1) == 1)
+ return 1;
+ if((head & 0xffff0000) == 0xfffe0000) return 1;
+
+ return 0;
+}
+
+int mpeg3audio_decode_header(mpeg3audio_t *audio)
+{
+ if(audio->newhead & (1 << 20))
+ {
+ audio->lsf = (audio->newhead & (1 << 19)) ? 0x0 : 0x1;
+ audio->mpeg35 = 0;
+ }
+ else
+ {
+ audio->lsf = 1;
+ audio->mpeg35 = 1;
+ }
+
+ audio->layer = 4 - ((audio->newhead >> 17) & 3);
+ if(audio->mpeg35)
+ audio->sampling_frequency_code = 6 + ((audio->newhead >> 10) & 0x3);
+ else
+ audio->sampling_frequency_code = ((audio->newhead >> 10) & 0x3) + (audio->lsf * 3);
+
+ audio->error_protection = ((audio->newhead >> 16) & 0x1) ^ 0x1;
+
+ audio->bitrate_index = ((audio->newhead >> 12) & 0xf);
+ audio->padding = ((audio->newhead >> 9) & 0x1);
+ audio->extension = ((audio->newhead >> 8) & 0x1);
+ audio->mode = ((audio->newhead >> 6) & 0x3);
+ audio->mode_ext = ((audio->newhead >> 4) & 0x3);
+ audio->copyright = ((audio->newhead >> 3) & 0x1);
+ audio->original = ((audio->newhead >> 2) & 0x1);
+ audio->emphasis = audio->newhead & 0x3;
+ audio->channels = (audio->mode == MPG_MD_MONO) ? 1 : 2;
+ if(audio->channels > 1)
+ audio->single = -1;
+ else
+ audio->single = 3;
+
+ audio->prev_framesize = audio->framesize;
+
+ if(!audio->bitrate_index) return 1;
+ audio->bitrate = 1000 * mpeg3_tabsel_123[audio->lsf][audio->layer - 1][audio->bitrate_index];
+
+ switch(audio->layer)
+ {
+ case 1:
+ audio->framesize = (long)mpeg3_tabsel_123[audio->lsf][0][audio->bitrate_index] * 12000;
+ audio->framesize /= mpeg3_freqs[audio->sampling_frequency_code];
+ audio->framesize = ((audio->framesize + audio->padding) << 2) - 4;
+ break;
+ case 2:
+ audio->framesize = (long)mpeg3_tabsel_123[audio->lsf][1][audio->bitrate_index] * 144000;
+ audio->framesize /= mpeg3_freqs[audio->sampling_frequency_code];
+ audio->framesize += audio->padding - 4;
+ break;
+ case 3:
+ if(audio->lsf)
+ audio->ssize = (audio->channels == 1) ? 9 : 17;
+ else
+ audio->ssize = (audio->channels == 1) ? 17 : 32;
+ if(audio->error_protection)
+ audio->ssize += 2;
+ audio->framesize = (long)mpeg3_tabsel_123[audio->lsf][2][audio->bitrate_index] * 144000;
+ audio->framesize /= mpeg3_freqs[audio->sampling_frequency_code] << (audio->lsf);
+ audio->framesize = audio->framesize + audio->padding - 4;
+ break;
+ default:
+ return 1;
+ }
+
+ if(audio->framesize > MAXFRAMESIZE) return 1;
+
+ return 0;
+}
+
+int mpeg3audio_read_frame_body(mpeg3audio_t *audio)
+{
+ int i;
+ for(i = 0; i < audio->framesize; i++)
+ {
+ audio->bsbuf[i] = mpeg3bits_getbits(audio->astream, 8);
+ }
+ return 0;
+}
+
+/* Seek to the start of the previous header */
+int mpeg3audio_prev_header(mpeg3audio_t *audio)
+{
+ int result = 0, i, len = (int)audio->avg_framesize;
+
+ for(i = 0; i < len && !result; i++)
+ {
+ mpeg3bits_getbits_reverse(audio->astream, 8);
+ }
+/* Get reading in the forward direction again. */
+ result |= mpeg3bits_refill(audio->astream);
+ return result;
+}
+
+/* Read the next header */
+int mpeg3audio_read_header(mpeg3audio_t *audio)
+{
+ unsigned int code;
+ int i;
+ int attempt = 0;
+ int result = 0;
+
+ switch(audio->format)
+ {
+ case AUDIO_AC3:
+ result = mpeg3audio_read_ac3_header(audio);
+ break;
+
+ case AUDIO_MPEG:
+/* Layer 1 not supported */
+ if(audio->layer == 1)
+ {
+ fprintf(stderr, "mpeg3audio_new: layer 1 not supported\n");
+ result = 1;
+ }
+ audio->newhead = mpeg3bits_showbits(audio->astream, 32);
+ if(!mpeg3bits_eof(audio->astream) &&
+ (mpeg3audio_head_check(audio->newhead) || mpeg3audio_decode_header(audio)))
+ {
+ do
+ {
+ attempt++;
+ mpeg3bits_getbyte_noptr(audio->astream);
+ audio->newhead = mpeg3bits_showbits(audio->astream, 32);
+ }while(!mpeg3bits_eof(audio->astream) &&
+ attempt < 65536 &&
+ (mpeg3audio_head_check(audio->newhead) || mpeg3audio_decode_header(audio)));
+ }
+
+/* Skip the 4 bytes containing the header */
+ mpeg3bits_getbits(audio->astream, 32);
+ break;
+
+ case AUDIO_PCM:
+ mpeg3audio_read_pcm_header(audio);
+ break;
+ }
+ return mpeg3bits_eof(audio->astream);
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/huffman.h b/core/multimedia/opieplayer/libmpeg3/audio/huffman.h
new file mode 100644
index 0000000..a9c8fff
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/huffman.h
@@ -0,0 +1,355 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef HUFFMAN_H
+#define HUFFMAN_H
+
+/*
+ * 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 mpeg3_tab0[] =
+{
+ 0
+};
+
+static short mpeg3_tab1[] =
+{
+ -5, -3, -1, 17, 1, 16, 0
+};
+
+static short mpeg3_tab2[] =
+{
+ -15, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 17, -1, 1,
+ 16, 0
+};
+
+static short mpeg3_tab3[] =
+{
+ -13, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 16, 17, -1,
+ 1, 0
+};
+
+static short mpeg3_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 mpeg3_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 mpeg3_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 mpeg3_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 mpeg3_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 mpeg3_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 mpeg3_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 mpeg3_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 mpeg3_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 mpeg3_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 mpeg3_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 mpeg3_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 mpeg3_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 mpeg3_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 mpeg3_ht[] =
+{
+ { /* 0 */ 0 , mpeg3_tab0 } ,
+ { /* 2 */ 0 , mpeg3_tab1 } ,
+ { /* 3 */ 0 , mpeg3_tab2 } ,
+ { /* 3 */ 0 , mpeg3_tab3 } ,
+ { /* 0 */ 0 , mpeg3_tab0 } ,
+ { /* 4 */ 0 , mpeg3_tab5 } ,
+ { /* 4 */ 0 , mpeg3_tab6 } ,
+ { /* 6 */ 0 , mpeg3_tab7 } ,
+ { /* 6 */ 0 , mpeg3_tab8 } ,
+ { /* 6 */ 0 , mpeg3_tab9 } ,
+ { /* 8 */ 0 , mpeg3_tab10 } ,
+ { /* 8 */ 0 , mpeg3_tab11 } ,
+ { /* 8 */ 0 , mpeg3_tab12 } ,
+ { /* 16 */ 0 , mpeg3_tab13 } ,
+ { /* 0 */ 0 , mpeg3_tab0 } ,
+ { /* 16 */ 0 , mpeg3_tab15 } ,
+
+ { /* 16 */ 1 , mpeg3_tab16 } ,
+ { /* 16 */ 2 , mpeg3_tab16 } ,
+ { /* 16 */ 3 , mpeg3_tab16 } ,
+ { /* 16 */ 4 , mpeg3_tab16 } ,
+ { /* 16 */ 6 , mpeg3_tab16 } ,
+ { /* 16 */ 8 , mpeg3_tab16 } ,
+ { /* 16 */ 10, mpeg3_tab16 } ,
+ { /* 16 */ 13, mpeg3_tab16 } ,
+ { /* 16 */ 4 , mpeg3_tab24 } ,
+ { /* 16 */ 5 , mpeg3_tab24 } ,
+ { /* 16 */ 6 , mpeg3_tab24 } ,
+ { /* 16 */ 7 , mpeg3_tab24 } ,
+ { /* 16 */ 8 , mpeg3_tab24 } ,
+ { /* 16 */ 9 , mpeg3_tab24 } ,
+ { /* 16 */ 11, mpeg3_tab24 } ,
+ { /* 16 */ 13, mpeg3_tab24 }
+};
+
+static struct newhuff mpeg3_htc[] =
+{
+ { /* 1 , 1 , */ 0 , mpeg3_tab_c0 } ,
+ { /* 1 , 1 , */ 0 , mpeg3_tab_c1 }
+};
+
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/layer1.c b/core/multimedia/opieplayer/libmpeg3/audio/layer1.c
new file mode 100644
index 0000000..0c355f3
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/layer1.c
@@ -0,0 +1,6 @@
+#include "mpeg3audio.h"
+
+int mpeg3audio_dolayer1(mpeg3audio_t *audio)
+{
+ ;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/layer2.c b/core/multimedia/opieplayer/libmpeg3/audio/layer2.c
new file mode 100644
index 0000000..01582fe
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/layer2.c
@@ -0,0 +1,418 @@
+/*
+ * most other tables are calculated on program start (which is (of course)
+ * not ISO-conform) ..
+ * Layer-3 huffman table is in huffman.h
+ */
+
+#include "mpeg3audio.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "tables.h"
+
+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} };
+
+
+int mpeg3audio_II_select_table(mpeg3audio_t *audio)
+{
+ static int translate[3][2][16] =
+ {{{ 0,2,2,2,2,2,2,0,0,0,1,1,1,1,1,0},
+ { 0,2,2,0,0,0,1,1,1,1,1,1,1,1,1,0}},
+ {{ 0,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0},
+ { 0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0}},
+ {{ 0,3,3,3,3,3,3,0,0,0,1,1,1,1,1,0},
+ { 0,3,3,0,0,0,1,1,1,1,1,1,1,1,1,0}}};
+ int table, sblim;
+ static struct al_table *tables[5] =
+ {alloc_0, alloc_1, alloc_2, alloc_3, alloc_4};
+ static int sblims[5] = {27, 30, 8, 12, 30};
+
+ if(audio->lsf)
+ table = 4;
+ else
+ table = translate[audio->sampling_frequency_code][2 - audio->channels][audio->bitrate_index];
+ sblim = sblims[table];
+
+ audio->alloc = tables[table];
+ audio->II_sblimit = sblim;
+ return 0;
+}
+
+int mpeg3audio_II_step_one(mpeg3audio_t *audio, unsigned int *bit_alloc, int *scale)
+{
+ int stereo = audio->channels - 1;
+ int sblimit = audio->II_sblimit;
+ int jsbound = audio->jsbound;
+ int sblimit2 = audio->II_sblimit << stereo;
+ struct al_table *alloc1 = audio->alloc;
+ int i, result = 0;
+ unsigned int *scfsi_buf = audio->layer2_scfsi_buf;
+ unsigned int *scfsi, *bita;
+ int sc, step;
+
+ bita = bit_alloc;
+ if(stereo)
+ {
+/* Stereo */
+ for(i = jsbound;i ; i--, alloc1 += (1 << step))
+ {
+ *bita++ = (char)mpeg3bits_getbits(audio->astream, step = alloc1->bits);
+ *bita++ = (char)mpeg3bits_getbits(audio->astream, step);
+ }
+ for(i = sblimit-jsbound; i; i--, alloc1 += (1 << step))
+ {
+ bita[0] = (char)mpeg3bits_getbits(audio->astream, step = alloc1->bits);
+ bita[1] = bita[0];
+ bita += 2;
+ }
+ bita = bit_alloc;
+ scfsi = scfsi_buf;
+ for(i = sblimit2; i; i--)
+ if(*bita++) *scfsi++ = (char)mpeg3bits_getbits(audio->astream, 2);
+ }
+ else
+ {
+/* mono */
+ for(i = sblimit; i; i--, alloc1 += (1 << step))
+ *bita++ = (char)mpeg3bits_getbits(audio->astream, step = alloc1->bits);
+ bita = bit_alloc;
+ scfsi = scfsi_buf;
+ for(i = sblimit; i; i--) if (*bita++) *scfsi++ = (char)mpeg3bits_getbits(audio->astream, 2);
+ }
+
+ bita = bit_alloc;
+ scfsi = scfsi_buf;
+ for(i = sblimit2; i; i--)
+ {
+ if(*bita++)
+ switch(*scfsi++)
+ {
+ case 0:
+ *scale++ = mpeg3bits_getbits(audio->astream, 6);
+ *scale++ = mpeg3bits_getbits(audio->astream, 6);
+ *scale++ = mpeg3bits_getbits(audio->astream, 6);
+ break;
+ case 1 :
+ *scale++ = sc = mpeg3bits_getbits(audio->astream, 6);
+ *scale++ = sc;
+ *scale++ = mpeg3bits_getbits(audio->astream, 6);
+ break;
+ case 2:
+ *scale++ = sc = mpeg3bits_getbits(audio->astream, 6);
+ *scale++ = sc;
+ *scale++ = sc;
+ break;
+ default: /* case 3 */
+ *scale++ = mpeg3bits_getbits(audio->astream, 6);
+ *scale++ = sc = mpeg3bits_getbits(audio->astream, 6);
+ *scale++ = sc;
+ break;
+ }
+ }
+ return result | mpeg3bits_error(audio->astream);
+}
+
+int mpeg3audio_II_step_two(mpeg3audio_t *audio, unsigned int *bit_alloc, mpeg3_real_t fraction[2][4][SBLIMIT], int *scale, int x1)
+{
+ int i, j, k, ba, result = 0;
+ int channels = audio->channels;
+ int sblimit = audio->II_sblimit;
+ int jsbound = audio->jsbound;
+ struct al_table *alloc2, *alloc1 = audio->alloc;
+ unsigned int *bita = bit_alloc;
+ int d1, step, test;
+
+ for(i = 0; i < jsbound; i++, alloc1 += (1 << step))
+ {
+ step = alloc1->bits;
+ for(j = 0; j < channels; j++)
+ {
+ if(ba = *bita++)
+ {
+ k = (alloc2 = alloc1 + ba)->bits;
+ if((d1 = alloc2->d) < 0)
+ {
+ mpeg3_real_t cm = mpeg3_muls[k][scale[x1]];
+
+ fraction[j][0][i] = ((mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm;
+ fraction[j][1][i] = ((mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm;
+ fraction[j][2][i] = ((mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm;
+ }
+ else
+ {
+ static int *table[] =
+ {0, 0, 0, mpeg3_grp_3tab, 0, mpeg3_grp_5tab, 0, 0, 0, mpeg3_grp_9tab};
+ unsigned int idx, *tab, m = scale[x1];
+
+ idx = (unsigned int)mpeg3bits_getbits(audio->astream, k);
+ tab = (unsigned int*)(table[d1] + idx + idx + idx);
+ fraction[j][0][i] = mpeg3_muls[*tab++][m];
+ fraction[j][1][i] = mpeg3_muls[*tab++][m];
+ fraction[j][2][i] = mpeg3_muls[*tab][m];
+ }
+ scale += 3;
+ }
+ else
+ fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0;
+ }
+ }
+
+ for(i = jsbound; i < sblimit; i++, alloc1 += (1 << step))
+ {
+ step = alloc1->bits;
+/* channel 1 and channel 2 bitalloc are the same */
+ bita++;
+ if((ba = *bita++))
+ {
+ k=(alloc2 = alloc1+ba)->bits;
+ if((d1 = alloc2->d) < 0)
+ {
+ mpeg3_real_t cm;
+
+ cm = mpeg3_muls[k][scale[x1 + 3]];
+ fraction[1][0][i] = (fraction[0][0][i] = (mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm;
+ fraction[1][1][i] = (fraction[0][1][i] = (mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm;
+ fraction[1][2][i] = (fraction[0][2][i] = (mpeg3_real_t)((int)mpeg3bits_getbits(audio->astream, k) + d1)) * cm;
+ cm = mpeg3_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, mpeg3_grp_3tab, 0, mpeg3_grp_5tab, 0, 0, 0, mpeg3_grp_9tab};
+ unsigned int idx, *tab, m1, m2;
+
+ m1 = scale[x1];
+ m2 = scale[x1+3];
+ idx = (unsigned int)mpeg3bits_getbits(audio->astream, k);
+ tab = (unsigned int*)(table[d1] + idx + idx + idx);
+ fraction[0][0][i] = mpeg3_muls[*tab][m1];
+ fraction[1][0][i] = mpeg3_muls[*tab++][m2];
+ fraction[0][1][i] = mpeg3_muls[*tab][m1];
+ fraction[1][1][i] = mpeg3_muls[*tab++][m2];
+ fraction[0][2][i] = mpeg3_muls[*tab][m1];
+ fraction[1][2][i] = mpeg3_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 !!
+*/
+ }
+
+ if(sblimit > SBLIMIT) sblimit = SBLIMIT;
+
+ for(i = sblimit; i < SBLIMIT; i++)
+ for(j = 0; j < channels; j++)
+ fraction[j][0][i] = fraction[j][1][i] = fraction[j][2][i] = 0.0;
+
+ return result | mpeg3bits_error(audio->astream);
+}
+
+int mpeg3audio_dolayer2(mpeg3audio_t *audio)
+{
+ int i, j, result = 0;
+ int channels = audio->channels;
+ mpeg3_real_t fraction[2][4][SBLIMIT]; /* pick_table clears unused subbands */
+ unsigned int bit_alloc[64];
+ int scale[192];
+ int single = audio->single;
+
+ if(audio->error_protection)
+ mpeg3bits_getbits(audio->astream, 16);
+
+ mpeg3audio_II_select_table(audio);
+
+ audio->jsbound = (audio->mode == MPG_MD_JOINT_STEREO) ?
+ (audio->mode_ext << 2) + 4 : audio->II_sblimit;
+
+ if(channels == 1 || single == 3)
+ single = 0;
+
+ result |= mpeg3audio_II_step_one(audio, bit_alloc, scale);
+
+ for(i = 0; i < SCALE_BLOCK && !result; i++)
+ {
+ result |= mpeg3audio_II_step_two(audio, bit_alloc, fraction, scale, i >> 2);
+
+ for(j = 0; j < 3; j++)
+ {
+ if(single >= 0)
+ {
+/* Monaural */
+ mpeg3audio_synth_mono(audio, fraction[single][j], audio->pcm_sample, &(audio->pcm_point));
+ }
+ else
+ {
+/* Stereo */
+ int p1 = audio->pcm_point;
+ mpeg3audio_synth_stereo(audio, fraction[0][j], 0, audio->pcm_sample, &p1);
+ mpeg3audio_synth_stereo(audio, fraction[1][j], 1, audio->pcm_sample, &(audio->pcm_point));
+ }
+
+ if(audio->pcm_point / audio->channels >= audio->pcm_allocated - MPEG3AUDIO_PADDING * audio->channels)
+ {
+/* Need more room */
+ mpeg3audio_replace_buffer(audio, audio->pcm_allocated + MPEG3AUDIO_PADDING * audio->channels);
+ }
+ }
+ }
+
+
+ return result;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/layer3.c b/core/multimedia/opieplayer/libmpeg3/audio/layer3.c
new file mode 100644
index 0000000..b8a5f06
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/layer3.c
@@ -0,0 +1,1254 @@
+#include "huffman.h"
+#include "mpeg3audio.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "tables.h"
+
+#include <stdio.h>
+#include <string.h>
+
+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;
+ mpeg3_real_t *full_gain[3];
+ mpeg3_real_t *pow2gain;
+};
+
+struct mpeg3_III_sideinfo
+{
+ unsigned main_data_begin;
+ unsigned private_bits;
+ struct
+ {
+ struct gr_info_s gr[2];
+ } ch[2];
+};
+
+int mpeg3audio_III_get_scale_factors_1(mpeg3audio_t *audio,
+ int *scf,
+ struct gr_info_s *gr_info,
+ int ch,
+ int gr)
+{
+ static 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++ = mpeg3bits_getbits(audio->astream, num0);
+ i = 9;
+/* num0 * 17 + num1 * 18 */
+ numbits -= num0;
+ }
+
+ for( ; i; i--)
+ *scf++ = mpeg3bits_getbits(audio->astream, num0);
+ for(i = 18; i; i--)
+ *scf++ = mpeg3bits_getbits(audio->astream, num1);
+/* short[13][0..2] = 0 */
+ *scf++ = 0;
+ *scf++ = 0;
+ *scf++ = 0;
+ }
+ else
+ {
+ int i;
+ int scfsi = gr_info->scfsi;
+
+ if(scfsi < 0)
+ {
+/* scfsi < 0 => granule == 0 */
+ for(i = 11; i; i--)
+ {
+ *scf++ = mpeg3bits_getbits(audio->astream, num0);
+ }
+ for(i = 10; i; i--)
+ *scf++ = mpeg3bits_getbits(audio->astream, num1);
+ numbits = (num0 + num1) * 10 + num0;
+ *scf++ = 0;
+ }
+ else
+ {
+ numbits = 0;
+ if(!(scfsi & 0x8))
+ {
+ for(i = 0; i < 6; i++)
+ {
+ *scf++ = mpeg3bits_getbits(audio->astream, num0);
+ }
+ numbits += num0 * 6;
+ }
+ else
+ {
+ scf += 6;
+ }
+
+ if(!(scfsi & 0x4))
+ {
+ for(i = 0; i < 5; i++)
+ *scf++ = mpeg3bits_getbits(audio->astream, num0);
+ numbits += num0 * 5;
+ }
+ else
+ {
+ scf += 5;
+ }
+
+ if(!(scfsi & 0x2))
+ {
+ for(i = 0; i < 5; i++)
+ *scf++ = mpeg3bits_getbits(audio->astream, num1);
+ numbits += num1 * 5;
+ }
+ else
+ {
+ scf += 5;
+ }
+
+ if(!(scfsi & 0x1))
+ {
+ for(i = 0; i < 5; i++)
+ *scf++ = mpeg3bits_getbits(audio->astream, num1);
+ numbits += num1 * 5;
+ }
+ else
+ {
+ scf += 5;
+ }
+ *scf++ = 0; /* no l[21] in original sources */
+ }
+ }
+ return numbits;
+}
+
+int mpeg3audio_III_get_scale_factors_2(mpeg3audio_t *audio,
+ int *scf,
+ struct gr_info_s *gr_info,
+ int i_stereo)
+{
+ unsigned char *pnt;
+ int i, j, n = 0, numbits = 0;
+ unsigned int slen;
+ 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}}};
+
+/* i_stereo AND second channel -> do_layer3() checks this */
+ if(i_stereo)
+ slen = mpeg3_i_slen2[gr_info->scalefac_compress >> 1];
+ else
+ slen = mpeg3_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++ = mpeg3bits_getbits(audio->astream, num);
+ numbits += pnt[i] * num;
+ }
+ else
+ {
+ for(j = 0; j < (int)(pnt[i]); j++)
+ *scf++ = 0;
+ }
+ }
+
+ n = (n << 1) + 1;
+ for(i = 0; i < n; i++)
+ *scf++ = 0;
+
+ return numbits;
+}
+
+static int pretab1[22] = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0};
+static int pretab2[22] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+/*
+ * Dequantize samples (includes huffman decoding)
+ *
+ * 24 is enough because tab13 has max. a 19 bit huffvector
+ */
+
+#define BITSHIFT ((sizeof(long) - 1) * 8)
+#define REFRESH_MASK \
+ while(num < BITSHIFT) \
+ { \
+ mask |= mpeg3bits_getbits(audio->astream, 8) << (BITSHIFT - num); \
+ num += 8; \
+ part2remain -= 8; \
+ }
+
+int mpeg3audio_III_dequantize_sample(mpeg3audio_t *audio,
+ mpeg3_real_t xr[SBLIMIT][SSLIMIT],
+ int *scf,
+ struct gr_info_s *gr_info,
+ int sfreq,
+ int part2bits)
+{
+ int shift = 1 + gr_info->scalefac_scale;
+ mpeg3_real_t *xrpnt = (mpeg3_real_t*)xr;
+ int l[3],l3;
+ int part2remain = gr_info->part2_3_length - part2bits;
+ int *me;
+ int num = mpeg3bits_getbitoffset(audio->astream);
+ long mask = mpeg3bits_getbits(audio->astream, num);
+//printf("III_dequantize_sample 1 %08x %d\n", mask, num);
+ mask = mask << (BITSHIFT + 8 - num);
+ part2remain -= num;
+
+ {
+ 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 = 3, cb = 0;
+ register mpeg3_real_t v = 0.0;
+ register int *m, mc;
+
+ if(gr_info->mixed_block_flag)
+ {
+ max[3] = -1;
+ max[0] = max[1] = max[2] = 2;
+ m = mpeg3_map[sfreq][0];
+ me = mpeg3_mapend[sfreq][0];
+ }
+ else
+ {
+ max[0] = max[1] = max[2] = max[3] = -1;
+/* max[3] not floatly needed in this case */
+ m = mpeg3_map[sfreq][1];
+ me = mpeg3_mapend[sfreq][1];
+ }
+
+ mc = 0;
+ for(i = 0; i < 2; i++)
+ {
+ int lp = l[i];
+ struct newhuff *h = mpeg3_ht + gr_info->table_select[i];
+ for( ; lp; lp--, mc--)
+ {
+ register int x,y;
+ if(!mc)
+ {
+ mc = *m++;
+ xrpnt = ((mpeg3_real_t*)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;
+ REFRESH_MASK;
+ while((y = *val++) < 0)
+ {
+ if (mask < 0)
+ val -= y;
+ num--;
+ mask <<= 1;
+ }
+ x = y >> 4;
+ y &= 0xf;
+ }
+
+ if(x == 15 && h->linbits)
+ {
+ max[lwin] = cb;
+ REFRESH_MASK;
+ x += ((unsigned long)mask) >> (BITSHIFT + 8 - h->linbits);
+ num -= h->linbits + 1;
+ mask <<= h->linbits;
+ if(mask < 0)
+ *xrpnt = -mpeg3_ispow[x] * v;
+ else
+ *xrpnt = mpeg3_ispow[x] * v;
+ mask <<= 1;
+ }
+ else
+ if(x)
+ {
+ max[lwin] = cb;
+ if(mask < 0)
+ *xrpnt = -mpeg3_ispow[x] * v;
+ else
+ *xrpnt = mpeg3_ispow[x] * v;
+ num--;
+ mask <<= 1;
+ }
+ else
+ *xrpnt = 0.0;
+
+ xrpnt += step;
+ if(y == 15 && h->linbits)
+ {
+ max[lwin] = cb;
+ REFRESH_MASK;
+ y += ((unsigned long) mask) >> (BITSHIFT + 8 - h->linbits);
+ num -= h->linbits + 1;
+ mask <<= h->linbits;
+ if(mask < 0)
+ *xrpnt = -mpeg3_ispow[y] * v;
+ else
+ *xrpnt = mpeg3_ispow[y] * v;
+ mask <<= 1;
+ }
+ else
+ if(y)
+ {
+ max[lwin] = cb;
+ if(mask < 0)
+ *xrpnt = -mpeg3_ispow[y] * v;
+ else
+ *xrpnt = mpeg3_ispow[y] * v;
+ num--;
+ mask <<= 1;
+ }
+ else
+ *xrpnt = 0.0;
+ xrpnt += step;
+ }
+ }
+
+ for( ;l3 && (part2remain + num > 0); l3--)
+ {
+ struct newhuff *h = mpeg3_htc + gr_info->count1table_select;
+ register short *val = h->table, a;
+
+ REFRESH_MASK;
+ while((a = *val++) < 0)
+ {
+ if (mask < 0)
+ val -= a;
+ num--;
+ mask <<= 1;
+ }
+ if(part2remain + num <= 0)
+ {
+ num -= part2remain + num;
+ break;
+ }
+
+ for(i = 0; i < 4; i++)
+ {
+ if(!(i & 1))
+ {
+ if(!mc)
+ {
+ mc = *m++;
+ xrpnt = ((mpeg3_real_t*)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;
+ if(part2remain + num <= 0)
+ {
+ break;
+ }
+ if(mask < 0)
+ *xrpnt = -v;
+ else
+ *xrpnt = v;
+ num--;
+ mask <<= 1;
+ }
+ else
+ *xrpnt = 0.0;
+ xrpnt += step;
+ }
+ }
+
+ if(lwin < 3)
+ {
+/* short band? */
+ while(1)
+ {
+ for( ;mc > 0; mc--)
+ {
+/* short band -> step=3 */
+ *xrpnt = 0.0;
+ xrpnt += 3;
+ *xrpnt = 0.0;
+ xrpnt += 3;
+ }
+ if(m >= me)
+ break;
+ mc = *m++;
+ xrpnt = ((mpeg3_real_t*)xr) + *m++;
+/* optimize: field will be set to zero at the end of the function */
+ if(*m++ == 0)
+ break;
+/* cb */
+ m++;
+ }
+ }
+
+ 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 ? mpeg3_shortLimit[sfreq][rmax] : mpeg3_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;
+ int *m = mpeg3_map[sfreq][2];
+ register mpeg3_real_t v = 0.0;
+ int mc = 0;
+
+/*
+ * long hash table values
+ */
+ for(i = 0; i < 3; i++)
+ {
+ int lp = l[i];
+ struct newhuff *h = mpeg3_ht + gr_info->table_select[i];
+
+ for(; lp; lp--, mc--)
+ {
+ int x, y;
+
+ if(!mc)
+ {
+ mc = *m++;
+ cb = *m++;
+ if(cb == 21)
+ v = 0.0;
+ else
+ v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift];
+ }
+ {
+ register short *val = h->table;
+ REFRESH_MASK;
+ while((y = *val++) < 0)
+ {
+ if(mask < 0)
+ val -= y;
+ num--;
+ mask <<= 1;
+ }
+ x = y >> 4;
+ y &= 0xf;
+ }
+
+ if(x == 15 && h->linbits)
+ {
+ max = cb;
+ REFRESH_MASK;
+ x += ((unsigned long) mask) >> (BITSHIFT + 8 - h->linbits);
+ num -= h->linbits + 1;
+ mask <<= h->linbits;
+ if(mask < 0)
+ *xrpnt++ = -mpeg3_ispow[x] * v;
+ else
+ *xrpnt++ = mpeg3_ispow[x] * v;
+ mask <<= 1;
+ }
+ else
+ if(x)
+ {
+ max = cb;
+ if(mask < 0)
+ *xrpnt++ = -mpeg3_ispow[x] * v;
+ else
+ *xrpnt++ = mpeg3_ispow[x] * v;
+ num--;
+ mask <<= 1;
+ }
+ else
+ *xrpnt++ = 0.0;
+
+ if(y == 15 && h->linbits)
+ {
+ max = cb;
+ REFRESH_MASK;
+ y += ((unsigned long) mask) >> (BITSHIFT + 8 - h->linbits);
+ num -= h->linbits + 1;
+ mask <<= h->linbits;
+ if(mask < 0)
+ *xrpnt++ = -mpeg3_ispow[y] * v;
+ else
+ *xrpnt++ = mpeg3_ispow[y] * v;
+ mask <<= 1;
+ }
+ else
+ if(y)
+ {
+ max = cb;
+ if(mask < 0)
+ *xrpnt++ = -mpeg3_ispow[y] * v;
+ else
+ *xrpnt++ = mpeg3_ispow[y] * v;
+ num--;
+ mask <<= 1;
+ }
+ else
+ *xrpnt++ = 0.0;
+ }
+ }
+
+/*
+ * short (count1table) values
+ */
+ for( ; l3 && (part2remain + num > 0); l3--)
+ {
+ struct newhuff *h = mpeg3_htc + gr_info->count1table_select;
+ register short *val = h->table, a;
+
+ REFRESH_MASK;
+ while((a = *val++) < 0)
+ {
+ if(mask < 0)
+ val -= a;
+ num--;
+ mask <<= 1;
+ }
+ if(part2remain + num <= 0)
+ {
+ num -= part2remain + num;
+ break;
+ }
+
+ for(i = 0; i < 4; i++)
+ {
+ if(!(i & 1))
+ {
+ if(!mc)
+ {
+ mc = *m++;
+ cb = *m++;
+ if(cb == 21)
+ v = 0.0;
+ else
+ v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift];
+ }
+ mc--;
+ }
+ if((a & (0x8 >> i)))
+ {
+ max = cb;
+ if(part2remain + num <= 0)
+ {
+ break;
+ }
+ if(mask < 0)
+ *xrpnt++ = -v;
+ else
+ *xrpnt++ = v;
+ num--;
+ mask <<= 1;
+ }
+ else
+ *xrpnt++ = 0.0;
+ }
+ }
+
+ gr_info->maxbandl = max + 1;
+ gr_info->maxb = mpeg3_longLimit[sfreq][gr_info->maxbandl];
+ }
+
+ part2remain += num;
+
+//printf("III_dequantize_sample 2 %d %04x\n", num, mpeg3bits_showbits(audio->astream, 16));
+ mpeg3bits_start_reverse(audio->astream);
+ mpeg3bits_getbits_reverse(audio->astream, num);
+ mpeg3bits_start_forward(audio->astream);
+//printf("III_dequantize_sample 3 %d %04x\n", audio->astream->bit_number, mpeg3bits_showbits(audio->astream, 16));
+ num = 0;
+
+ while(xrpnt < &xr[SBLIMIT][0])
+ *xrpnt++ = 0.0;
+
+ while(part2remain > 16)
+ {
+ mpeg3bits_getbits(audio->astream, 16); /* Dismiss stuffing Bits */
+ part2remain -= 16;
+ }
+ if(part2remain > 0)
+ {
+ mpeg3bits_getbits(audio->astream, part2remain);
+ }
+ else
+ if(part2remain < 0)
+ {
+ fprintf(stderr,"mpeg3audio_III_dequantize_sample: Can't rewind stream %d bits!\n", -part2remain);
+ return 1; /* -> error */
+ }
+ return 0;
+}
+
+int mpeg3audio_III_get_side_info(mpeg3audio_t *audio,
+ struct mpeg3_III_sideinfo *si,
+ int channels,
+ int ms_stereo,
+ long sfreq,
+ int single,
+ int lsf)
+{
+ int ch, gr;
+ int powdiff = (single == 3) ? 4 : 0;
+ static const int tabs[2][5] = { { 2,9,5,3,4 } , { 1,8,1,2,9 } };
+ const int *tab = tabs[lsf];
+
+ si->main_data_begin = mpeg3bits_getbits(audio->astream, tab[1]);
+ if(channels == 1)
+ si->private_bits = mpeg3bits_getbits(audio->astream, tab[2]);
+ else
+ si->private_bits = mpeg3bits_getbits(audio->astream, tab[3]);
+ if(!lsf)
+ {
+ for(ch = 0; ch < channels; ch++)
+ {
+ si->ch[ch].gr[0].scfsi = -1;
+ si->ch[ch].gr[1].scfsi = mpeg3bits_getbits(audio->astream, 4);
+ }
+ }
+
+ for(gr = 0; gr < tab[0]; gr++)
+ {
+ for(ch = 0; ch < channels; ch++)
+ {
+ register struct gr_info_s *gr_info = &(si->ch[ch].gr[gr]);
+
+ gr_info->part2_3_length = mpeg3bits_getbits(audio->astream, 12);
+ gr_info->big_values = mpeg3bits_getbits(audio->astream, 9);
+ if(gr_info->big_values > 288)
+ {
+ fprintf(stderr,"mpeg3_III_get_side_info: big_values too large!\n");
+ gr_info->big_values = 288;
+ }
+ gr_info->pow2gain = mpeg3_gainpow2 + 256 - mpeg3bits_getbits(audio->astream, 8) + powdiff;
+ if(ms_stereo)
+ gr_info->pow2gain += 2;
+ gr_info->scalefac_compress = mpeg3bits_getbits(audio->astream, tab[4]);
+
+ if(mpeg3bits_getbits(audio->astream, 1))
+ {
+/* window switch flag */
+ int i;
+ gr_info->block_type = mpeg3bits_getbits(audio->astream, 2);
+ gr_info->mixed_block_flag = mpeg3bits_getbits(audio->astream, 1);
+ gr_info->table_select[0] = mpeg3bits_getbits(audio->astream, 5);
+ gr_info->table_select[1] = mpeg3bits_getbits(audio->astream, 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 + (mpeg3bits_getbits(audio->astream, 3) << 3);
+
+ if(gr_info->block_type == 0)
+ {
+ fprintf(stderr,"Blocktype == 0 and window-switching == 1 not allowed.\n");
+ return 1;
+ }
+
+/* region_count/start parameters are implicit in this case. */
+ if(!lsf || gr_info->block_type == 2)
+ gr_info->region1start = 36 >> 1;
+ else
+ {
+/* check this again for 2.5 and sfreq=8 */
+ if(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] = mpeg3bits_getbits(audio->astream, 5);
+
+ r0c = mpeg3bits_getbits(audio->astream, 4);
+ r1c = mpeg3bits_getbits(audio->astream, 3);
+ gr_info->region1start = mpeg3_bandInfo[sfreq].longIdx[r0c + 1] >> 1 ;
+ gr_info->region2start = mpeg3_bandInfo[sfreq].longIdx[r0c + 1 + r1c + 1] >> 1;
+ gr_info->block_type = 0;
+ gr_info->mixed_block_flag = 0;
+ }
+ if(!lsf) gr_info->preflag = mpeg3bits_getbits(audio->astream, 1);
+ gr_info->scalefac_scale = mpeg3bits_getbits(audio->astream, 1);
+ gr_info->count1table_select = mpeg3bits_getbits(audio->astream, 1);
+ }
+ }
+ return 0;
+}
+
+int mpeg3audio_III_hybrid(mpeg3audio_t *audio,
+ mpeg3_real_t fsIn[SBLIMIT][SSLIMIT],
+ mpeg3_real_t tsOut[SSLIMIT][SBLIMIT],
+ int ch,
+ struct gr_info_s *gr_info)
+{
+ mpeg3_real_t *tspnt = (mpeg3_real_t *) tsOut;
+ mpeg3_real_t *rawout1,*rawout2;
+ int bt, sb = 0;
+
+
+ {
+ int b = audio->mp3_blc[ch];
+ rawout1 = audio->mp3_block[b][ch];
+ b = -b + 1;
+ rawout2 = audio->mp3_block[b][ch];
+ audio->mp3_blc[ch] = b;
+ }
+
+ if(gr_info->mixed_block_flag)
+ {
+ sb = 2;
+ mpeg3audio_dct36(fsIn[0], rawout1, rawout2, mpeg3_win[0], tspnt);
+ mpeg3audio_dct36(fsIn[1], rawout1 + 18, rawout2 + 18, mpeg3_win1[0], tspnt + 1);
+ rawout1 += 36;
+ rawout2 += 36;
+ tspnt += 2;
+ }
+
+ bt = gr_info->block_type;
+ if(bt == 2)
+ {
+ for( ; sb < gr_info->maxb; sb += 2, tspnt += 2, rawout1 += 36, rawout2 += 36)
+ {
+ mpeg3audio_dct12(fsIn[sb] ,rawout1 ,rawout2 ,mpeg3_win[2] ,tspnt);
+ mpeg3audio_dct12(fsIn[sb + 1], rawout1 + 18, rawout2 + 18, mpeg3_win1[2], tspnt + 1);
+ }
+ }
+ else
+ {
+ for( ; sb < gr_info->maxb; sb += 2, tspnt += 2, rawout1 += 36, rawout2 += 36)
+ {
+ mpeg3audio_dct36(fsIn[sb], rawout1, rawout2, mpeg3_win[bt], tspnt);
+ mpeg3audio_dct36(fsIn[sb + 1], rawout1 + 18, rawout2 + 18, mpeg3_win1[bt], tspnt + 1);
+ }
+ }
+
+ for( ; sb < SBLIMIT; sb++, tspnt++)
+ {
+ int i;
+ for(i = 0; i < SSLIMIT; i++)
+ {
+ tspnt[i * SBLIMIT] = *rawout1++;
+ *rawout2++ = 0.0;
+ }
+ }
+ return 0;
+}
+
+int mpeg3audio_III_antialias(mpeg3audio_t *audio,
+ mpeg3_real_t xr[SBLIMIT][SSLIMIT],
+ struct gr_info_s *gr_info)
+{
+ int sblim;
+
+ if(gr_info->block_type == 2)
+ {
+ if(!gr_info->mixed_block_flag)
+ return 0;
+ 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;
+ mpeg3_real_t *xr1 = (mpeg3_real_t*)xr[1];
+
+ for(sb = sblim; sb; sb--, xr1 += 10)
+ {
+ int ss;
+ mpeg3_real_t *cs, *ca;
+ mpeg3_real_t *xr2;
+ cs = mpeg3_aa_cs;
+ ca = mpeg3_aa_ca;
+ xr2 = xr1;
+
+ for(ss = 7; ss >= 0; ss--)
+ {
+/* upper and lower butterfly inputs */
+ register mpeg3_real_t bu, bd;
+ bu = *--xr2;
+ bd = *xr1;
+ *xr2 = (bu * (*cs) ) - (bd * (*ca) );
+ *xr1++ = (bd * (*cs++) ) + (bu * (*ca++) );
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ * III_stereo: calculate mpeg3_real_t channel values for Joint-I-Stereo-mode
+ */
+int mpeg3audio_III_i_stereo(mpeg3audio_t *audio,
+ mpeg3_real_t xr_buf[2][SBLIMIT][SSLIMIT],
+ int *scalefac,
+ struct gr_info_s *gr_info,
+ int sfreq,
+ int ms_stereo,
+ int lsf)
+{
+ mpeg3_real_t (*xr)[SBLIMIT*SSLIMIT] = (mpeg3_real_t (*)[SBLIMIT*SSLIMIT] ) xr_buf;
+ struct mpeg3_bandInfoStruct *bi = &mpeg3_bandInfo[sfreq];
+ const mpeg3_real_t *tab1, *tab2;
+
+ int tab;
+/* TODO: optimize as static */
+ static const mpeg3_real_t *tabs[3][2][2] =
+ {
+ { { mpeg3_tan1_1, mpeg3_tan2_1 } , { mpeg3_tan1_2, mpeg3_tan2_2 } },
+ { { mpeg3_pow1_1[0], mpeg3_pow2_1[0] } , { mpeg3_pow1_2[0], mpeg3_pow2_2[0] } } ,
+ { { mpeg3_pow1_1[1], mpeg3_pow2_1[1] } , { mpeg3_pow1_2[1], mpeg3_pow2_2[1] } }
+ };
+
+ tab = lsf + (gr_info->scalefac_compress & lsf);
+ tab1 = tabs[tab][ms_stereo][0];
+ tab2 = tabs[tab][ms_stereo][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 */
+/* sfb is minimal 3 for mixed mode */
+ int is_p, sb, idx, sfb = gr_info->maxband[lwin];
+ if(sfb > 3) do_l = 0;
+
+ for( ; sfb < 12 ; sfb++)
+ {
+/* scale: 0-15 */
+ is_p = scalefac[sfb * 3 + lwin - gr_info->mixed_block_flag];
+ if(is_p != 7)
+ {
+ mpeg3_real_t 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)
+ {
+ mpeg3_real_t 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?) */
+/* scale: 0-15 */
+ is_p = scalefac[11 * 3 + lwin - gr_info->mixed_block_flag];
+ sb = bi->shortDiff[12];
+ idx = bi->shortIdx[12] + lwin;
+ if(is_p != 7)
+ {
+ mpeg3_real_t t1, t2;
+ t1 = tab1[is_p];
+ t2 = tab2[is_p];
+ for( ; sb > 0; sb--, idx += 3)
+ {
+ mpeg3_real_t v = xr[0][idx];
+ xr[0][idx] = v * t1;
+ xr[1][idx] = v * t2;
+ }
+ }
+ } /* end for(lwin; .. ; . ) */
+
+/* also check l-part, if ALL bands in the three windows are 'empty'
+* and mode = mixed_mode
+*/
+ if(do_l)
+ {
+ int sfb = gr_info->maxbandl;
+ int idx = bi->longIdx[sfb];
+
+ for ( ; sfb < 8; sfb++)
+ {
+ int sb = bi->longDiff[sfb];
+/* scale: 0-15 */
+ int is_p = scalefac[sfb];
+ if(is_p != 7)
+ {
+ mpeg3_real_t t1, t2;
+ t1 = tab1[is_p];
+ t2 = tab2[is_p];
+ for( ; sb > 0; sb--, idx++)
+ {
+ mpeg3_real_t 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];
+/* scale: 0-15 */
+ is_p = scalefac[sfb];
+ if(is_p != 7)
+ {
+ mpeg3_real_t t1, t2;
+ t1 = tab1[is_p];
+ t2 = tab2[is_p];
+ for( ; sb > 0; sb--, idx++)
+ {
+ mpeg3_real_t v = xr[0][idx];
+ xr[0][idx] = v * t1;
+ xr[1][idx] = v * t2;
+ }
+ }
+ else
+ idx += sb;
+ }
+
+ is_p = scalefac[20];
+ if(is_p != 7)
+ {
+/* copy l-band 20 to l-band 21 */
+ int sb;
+ mpeg3_real_t t1 = tab1[is_p], t2 = tab2[is_p];
+
+ for(sb = bi->longDiff[21]; sb > 0; sb--, idx++)
+ {
+ mpeg3_real_t v = xr[0][idx];
+ xr[0][idx] = v * t1;
+ xr[1][idx] = v * t2;
+ }
+ }
+ } /* ... */
+}
+
+/* Read just the frame after a seek. */
+int mpeg3audio_read_layer3_frame(mpeg3audio_t *audio)
+{
+ int result = 0;
+
+ result = mpeg3audio_read_header(audio);
+ if(!result)
+ {
+ audio->bsbufold = audio->bsbuf;
+ audio->bsbuf = audio->bsspace[audio->bsnum] + 512;
+ audio->bsnum ^= 1;
+ result = mpeg3bits_read_buffer(audio->astream, audio->bsbuf, audio->framesize);
+ }
+
+ return result;
+}
+
+int mpeg3audio_dolayer3(mpeg3audio_t *audio)
+{
+ int gr, ch, ss;
+ int scalefacs[2][39]; /* max 39 for short[13][3] mode, mixed: 38, long: 22 */
+ struct mpeg3_III_sideinfo sideinfo;
+ int channels = audio->channels;
+ int single = audio->single;
+ int ms_stereo, i_stereo;
+ int sfreq = audio->sampling_frequency_code;
+ int stereo1, granules;
+ int i;
+
+/* flip/init buffer */
+ audio->bsbufold = audio->bsbuf;
+ audio->bsbuf = audio->bsspace[audio->bsnum] + 512;
+ audio->bsnum ^= 1;
+
+/* read main data into memory */
+ if(mpeg3bits_read_buffer(audio->astream, audio->bsbuf, audio->framesize))
+ return 1;
+ mpeg3bits_use_ptr(audio->astream, audio->bsbuf);
+
+/* CRC must be skipped here for proper alignment with the backstep */
+ if(audio->error_protection)
+ mpeg3bits_getbits(audio->astream, 16);
+
+ if(channels == 1)
+ {
+/* stream is mono */
+ stereo1 = 1;
+ single = 0;
+ }
+ else
+ {
+/* Stereo */
+ stereo1 = 2;
+ }
+
+ if(audio->mode == MPG_MD_JOINT_STEREO)
+ {
+ ms_stereo = (audio->mode_ext & 0x2) >> 1;
+ i_stereo = audio->mode_ext & 0x1;
+ }
+ else
+ ms_stereo = i_stereo = 0;
+
+ if(audio->lsf)
+ {
+ granules = 1;
+ }
+ else
+ {
+ granules = 2;
+ }
+
+ if(mpeg3audio_III_get_side_info(audio, &sideinfo, channels, ms_stereo, sfreq, single, audio->lsf))
+ return 1;
+
+/* Step back */
+ if(sideinfo.main_data_begin >= 512)
+ return 1;
+
+ if(sideinfo.main_data_begin)
+ {
+ memcpy(audio->bsbuf + audio->ssize - sideinfo.main_data_begin,
+ audio->bsbufold + audio->prev_framesize - sideinfo.main_data_begin,
+ sideinfo.main_data_begin);
+ mpeg3bits_use_ptr(audio->astream, audio->bsbuf + audio->ssize - sideinfo.main_data_begin);
+ }
+
+ for(gr = 0; gr < granules; gr++)
+ {
+ mpeg3_real_t hybridIn [2][SBLIMIT][SSLIMIT];
+ mpeg3_real_t hybridOut[2][SSLIMIT][SBLIMIT];
+
+ {
+ struct gr_info_s *gr_info = &(sideinfo.ch[0].gr[gr]);
+ long part2bits;
+ if(audio->lsf)
+ part2bits = mpeg3audio_III_get_scale_factors_2(audio, scalefacs[0], gr_info, 0);
+ else
+ part2bits = mpeg3audio_III_get_scale_factors_1(audio, scalefacs[0], gr_info, 0, gr);
+//printf("dolayer3 4 %04x\n", mpeg3bits_showbits(audio->astream, 16));
+
+ if(mpeg3audio_III_dequantize_sample(audio, hybridIn[0], scalefacs[0], gr_info, sfreq, part2bits))
+ {
+ mpeg3bits_use_demuxer(audio->astream);
+ return 1;
+ }
+//printf("dolayer3 5 %04x\n", mpeg3bits_showbits(audio->astream, 16));
+ }
+
+ if(channels == 2)
+ {
+ struct gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]);
+ long part2bits;
+ if(audio->lsf)
+ part2bits = mpeg3audio_III_get_scale_factors_2(audio, scalefacs[1], gr_info, i_stereo);
+ else
+ part2bits = mpeg3audio_III_get_scale_factors_1(audio, scalefacs[1], gr_info, 1, gr);
+
+ if(mpeg3audio_III_dequantize_sample(audio, hybridIn[1], scalefacs[1], gr_info, sfreq, part2bits))
+ {
+ mpeg3bits_use_demuxer(audio->astream);
+ return 1;
+ }
+
+ if(ms_stereo)
+ {
+ int i;
+ int maxb = sideinfo.ch[0].gr[gr].maxb;
+ if(sideinfo.ch[1].gr[gr].maxb > maxb)
+ maxb = sideinfo.ch[1].gr[gr].maxb;
+ for(i = 0; i < SSLIMIT * maxb; i++)
+ {
+ mpeg3_real_t tmp0 = ((mpeg3_real_t*)hybridIn[0])[i];
+ mpeg3_real_t tmp1 = ((mpeg3_real_t*)hybridIn[1])[i];
+ ((mpeg3_real_t*)hybridIn[0])[i] = tmp0 + tmp1;
+ ((mpeg3_real_t*)hybridIn[1])[i] = tmp0 - tmp1;
+ }
+ }
+
+ if(i_stereo)
+ mpeg3audio_III_i_stereo(audio, hybridIn, scalefacs[1], gr_info, sfreq, ms_stereo, audio->lsf);
+
+ if(ms_stereo || i_stereo || (single == 3))
+ {
+ if(gr_info->maxb > sideinfo.ch[0].gr[gr].maxb)
+ sideinfo.ch[0].gr[gr].maxb = gr_info->maxb;
+ else
+ gr_info->maxb = sideinfo.ch[0].gr[gr].maxb;
+ }
+
+ switch(single)
+ {
+ case 3:
+ {
+ register int i;
+ register mpeg3_real_t *in0 = (mpeg3_real_t*)hybridIn[0], *in1 = (mpeg3_real_t*)hybridIn[1];
+/* *0.5 done by pow-scale */
+ for(i = 0; i < SSLIMIT * gr_info->maxb; i++, in0++)
+ *in0 = (*in0 + *in1++);
+ }
+ break;
+ case 1:
+ {
+ register int i;
+ register mpeg3_real_t *in0 = (mpeg3_real_t*)hybridIn[0], *in1 = (mpeg3_real_t*)hybridIn[1];
+ for(i = 0; i < SSLIMIT * gr_info->maxb; i++)
+ *in0++ = *in1++;
+ }
+ break;
+ }
+ }
+
+ for(ch = 0; ch < stereo1; ch++)
+ {
+ struct gr_info_s *gr_info = &(sideinfo.ch[ch].gr[gr]);
+ mpeg3audio_III_antialias(audio, hybridIn[ch], gr_info);
+ mpeg3audio_III_hybrid(audio, hybridIn[ch], hybridOut[ch], ch, gr_info);
+ }
+
+ for(ss = 0; ss < SSLIMIT; ss++)
+ {
+ if(single >= 0)
+ {
+ mpeg3audio_synth_mono(audio, hybridOut[0][ss], audio->pcm_sample, &(audio->pcm_point));
+ }
+ else
+ {
+ int p1 = audio->pcm_point;
+ mpeg3audio_synth_stereo(audio, hybridOut[0][ss], 0, audio->pcm_sample, &p1);
+ mpeg3audio_synth_stereo(audio, hybridOut[1][ss], 1, audio->pcm_sample, &(audio->pcm_point));
+ }
+
+ if(audio->pcm_point / audio->channels >= audio->pcm_allocated - MPEG3AUDIO_PADDING * audio->channels)
+ {
+/* Need more room */
+ mpeg3audio_replace_buffer(audio, audio->pcm_allocated + MPEG3AUDIO_PADDING * audio->channels);
+ }
+ }
+ }
+
+ mpeg3bits_use_demuxer(audio->astream);
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/mantissa.c b/core/multimedia/opieplayer/libmpeg3/audio/mantissa.c
new file mode 100644
index 0000000..05fe251
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/mantissa.c
@@ -0,0 +1,387 @@
+/*
+ *
+ * mantissa.c Copyright (C) Aaron Holtzman - May 1999
+ *
+ *
+ * This file is part of libmpeg3
+ *
+ * libmpeg3 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.
+ *
+ * libmpeg3 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 "mpeg3audio.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+
+
+/* Lookup tables of 0.16 two's complement quantization values */
+static short mpeg3_q_1[3] =
+{
+ (-2 << 15) / 3,
+ 0,
+ (2 << 15) / 3
+};
+
+static short mpeg3_q_2[5] =
+{
+ (-4 << 15) / 5,
+ ((-2 << 15) / 5) << 1,
+ 0,
+ (2 << 15) / 5,
+ ((4 << 15) / 5) << 1
+};
+
+static short mpeg3_q_3[7] =
+{
+ (-6 << 15) / 7,
+ (-4 << 15) / 7,
+ (-2 << 15) / 7,
+ 0,
+ (2 << 15) / 7,
+ (4 << 15) / 7,
+ (6 << 15) / 7
+};
+
+static short mpeg3_q_4[11] =
+{
+ (-10 << 15) / 11,
+ (-8 << 15) / 11,
+ (-6 << 15) / 11,
+ (-4 << 15) / 11,
+ (-2 << 15) / 11,
+ 0,
+ ( 2 << 15) / 11,
+ ( 4 << 15) / 11,
+ ( 6 << 15) / 11,
+ ( 8 << 15) / 11,
+ (10 << 15) / 11
+};
+
+static short mpeg3_q_5[15] =
+{
+ (-14 << 15) / 15,
+ (-12 << 15) / 15,
+ (-10 << 15) / 15,
+ (-8 << 15) / 15,
+ (-6 << 15) / 15,
+ (-4 << 15) / 15,
+ (-2 << 15) / 15,
+ 0,
+ ( 2 << 15) / 15,
+ ( 4 << 15) / 15,
+ ( 6 << 15) / 15,
+ ( 8 << 15) / 15,
+ (10 << 15) / 15,
+ (12 << 15) / 15,
+ (14 << 15) / 15
+};
+
+static short mpeg3_qnttztab[16] = {0, 0, 0, 3, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16};
+
+
+/* */
+/* Scale factors for tofloat */
+/* */
+
+static const unsigned MPEG3_INT32 mpeg3_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 MPEG3_FLOAT32 *mpeg3_scale_factor = (MPEG3_FLOAT32*)mpeg3_scale_factors;
+
+static inline mpeg3_real_t mpeg3audio_ac3_tofloat(unsigned short exponent, int mantissa)
+{
+ mpeg3_real_t x;
+ x = mantissa * mpeg3_scale_factor[exponent];
+ return x;
+}
+
+static inline void mpeg3audio_ac3_mantissa_reset(mpeg3_ac3_mantissa_t *mantissa)
+{
+ mantissa->m_1[2] = mantissa->m_1[1] = mantissa->m_1[0] = 0;
+ mantissa->m_2[2] = mantissa->m_2[1] = mantissa->m_2[0] = 0;
+ mantissa->m_4[1] = mantissa->m_4[0] = 0;
+/* Force new groups to be loaded */
+ mantissa->m_1_pointer = mantissa->m_2_pointer = mantissa->m_4_pointer = 3;
+}
+
+/*
+ * 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]
+ *
+ */
+inline unsigned int mpeg3audio_ac3_dither_gen(mpeg3audio_t *audio)
+{
+ int i;
+ unsigned int state;
+
+/* explicitly bring the state into a local var as gcc > 3.0? */
+/* doesn't know how to optimize out the stores */
+ state = audio->ac3_lfsr_state;
+
+/* Generate eight pseudo random bits */
+ for(i = 0; i < 8; i++)
+ {
+ state <<= 1;
+
+ if(state & 0x10000)
+ state ^= 0xa011;
+ }
+
+ audio->ac3_lfsr_state = state;
+ return (((((int)state << 8) >> 8) * (int)(0.707106f * 256.0f)) >> 16);
+}
+
+
+/* Fetch an unpacked, left justified, and properly biased/dithered mantissa value */
+static inline unsigned short mpeg3audio_ac3_mantissa_get(mpeg3audio_t *audio,
+ unsigned short bap,
+ unsigned short dithflag)
+{
+ unsigned short mantissa;
+ unsigned int group_code;
+ mpeg3_ac3_mantissa_t *mantissa_struct = &(audio->ac3_mantissa);
+
+/* If the bap is 0-5 then we have special cases to take care of */
+ switch(bap)
+ {
+ case 0:
+ if(dithflag)
+ mantissa = mpeg3audio_ac3_dither_gen(audio);
+ else
+ mantissa = 0;
+ break;
+
+ case 1:
+ if(mantissa_struct->m_1_pointer > 2)
+ {
+ group_code = mpeg3bits_getbits(audio->astream, 5);
+
+ if(group_code > 26)
+ {
+/* FIXME do proper block error handling */
+ fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 1 %d\n", group_code);
+ return 0;
+ }
+
+ mantissa_struct->m_1[0] = group_code / 9;
+ mantissa_struct->m_1[1] = (group_code % 9) / 3;
+ mantissa_struct->m_1[2] = (group_code % 9) % 3;
+ mantissa_struct->m_1_pointer = 0;
+ }
+ mantissa = mantissa_struct->m_1[mantissa_struct->m_1_pointer++];
+ mantissa = mpeg3_q_1[mantissa];
+ break;
+
+ case 2:
+ if(mantissa_struct->m_2_pointer > 2)
+ {
+ group_code = mpeg3bits_getbits(audio->astream, 7);
+
+ if(group_code > 124)
+ {
+ fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 2 %d\n", group_code);
+ return 0;
+ }
+
+ mantissa_struct->m_2[0] = group_code / 25;
+ mantissa_struct->m_2[1] = (group_code % 25) / 5;
+ mantissa_struct->m_2[2] = (group_code % 25) % 5;
+ mantissa_struct->m_2_pointer = 0;
+ }
+ mantissa = mantissa_struct->m_2[mantissa_struct->m_2_pointer++];
+ mantissa = mpeg3_q_2[mantissa];
+ break;
+
+ case 3:
+ mantissa = mpeg3bits_getbits(audio->astream, 3);
+
+ if(mantissa > 6)
+ {
+ fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 3 %d\n", mantissa);
+ return 0;
+ }
+
+ mantissa = mpeg3_q_3[mantissa];
+ break;
+
+ case 4:
+ if(mantissa_struct->m_4_pointer > 1)
+ {
+ group_code = mpeg3bits_getbits(audio->astream, 7);
+
+ if(group_code > 120)
+ {
+ fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 4 %d\n", group_code);
+ return 0;
+ }
+
+ mantissa_struct->m_4[0] = group_code / 11;
+ mantissa_struct->m_4[1] = group_code % 11;
+ mantissa_struct->m_4_pointer = 0;
+ }
+ mantissa = mantissa_struct->m_4[mantissa_struct->m_4_pointer++];
+ mantissa = mpeg3_q_4[mantissa];
+ break;
+
+ case 5:
+ mantissa = mpeg3bits_getbits(audio->astream, 4);
+
+ if(mantissa > 14)
+ {
+/* FIXME do proper block error handling */
+ fprintf(stderr, "mpeg3audio_ac3_mantissa_get: Invalid mantissa 5 %d\n", mantissa);
+ return 0;
+ }
+
+ mantissa = mpeg3_q_5[mantissa];
+ break;
+
+ default:
+ mantissa = mpeg3bits_getbits(audio->astream, mpeg3_qnttztab[bap]);
+ mantissa <<= 16 - mpeg3_qnttztab[bap];
+ }
+ return mantissa;
+}
+
+void mpeg3audio_ac3_uncouple_channel(mpeg3audio_t *audio,
+ mpeg3_real_t samples[],
+ mpeg3_ac3bsi_t *bsi,
+ mpeg3_ac3audblk_t *audblk,
+ unsigned int ch)
+{
+ unsigned int bnd = 0;
+ unsigned int sub_bnd = 0;
+ unsigned int i, j;
+ MPEG3_FLOAT32 cpl_coord = 1.0;
+ unsigned int cpl_exp_tmp;
+ unsigned int cpl_mant_tmp;
+ short mantissa;
+
+ for(i = audblk->cplstrtmant; i < audblk->cplendmant; )
+ {
+ if(!audblk->cplbndstrc[sub_bnd++])
+ {
+ cpl_exp_tmp = audblk->cplcoexp[ch][bnd] + 3 * audblk->mstrcplco[ch];
+ if(audblk->cplcoexp[ch][bnd] == 15)
+ cpl_mant_tmp = (audblk->cplcomant[ch][bnd]) << 11;
+ else
+ cpl_mant_tmp = ((0x10) | audblk->cplcomant[ch][bnd]) << 10;
+
+ cpl_coord = mpeg3audio_ac3_tofloat(cpl_exp_tmp, cpl_mant_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] == 0)
+ mantissa = mpeg3audio_ac3_dither_gen(audio);
+ else
+ mantissa = audblk->cplmant[i];
+
+ samples[i] = cpl_coord * mpeg3audio_ac3_tofloat(audblk->cpl_exp[i], mantissa);;
+
+ i++;
+ }
+ }
+ return;
+}
+
+int mpeg3audio_ac3_coeff_unpack(mpeg3audio_t *audio,
+ mpeg3_ac3bsi_t *bsi,
+ mpeg3_ac3audblk_t *audblk,
+ mpeg3ac3_stream_samples_t samples)
+{
+ int i, j;
+ int done_cpl = 0;
+ short mantissa;
+
+ mpeg3audio_ac3_mantissa_reset(&(audio->ac3_mantissa));
+
+ for(i = 0; i < bsi->nfchans && !mpeg3bits_error(audio->astream); i++)
+ {
+ for(j = 0; j < audblk->endmant[i] && !mpeg3bits_error(audio->astream); j++)
+ {
+ mantissa = mpeg3audio_ac3_mantissa_get(audio, audblk->fbw_bap[i][j], audblk->dithflag[i]);
+ samples[i][j] = mpeg3audio_ac3_tofloat(audblk->fbw_exp[i][j], mantissa);
+ }
+
+ if(audblk->cplinu && audblk->chincpl[i] && !(done_cpl) && !mpeg3bits_error(audio->astream))
+ {
+/* 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 && !mpeg3bits_error(audio->astream);
+ j++)
+ {
+ audblk->cplmant[j] = mpeg3audio_ac3_mantissa_get(audio, audblk->cpl_bap[j], 0);
+ }
+ done_cpl = 1;
+ }
+ }
+
+/* Uncouple the channel */
+ if(audblk->cplinu)
+ {
+ if(audblk->chincpl[i])
+ mpeg3audio_ac3_uncouple_channel(audio, samples[i], bsi, audblk, i);
+ }
+
+ if(bsi->lfeon && !mpeg3bits_error(audio->astream))
+ {
+/* There are always 7 mantissas for lfe, no dither for lfe */
+ for(j = 0; j < 7 && !mpeg3bits_error(audio->astream); j++)
+ mantissa = mpeg3audio_ac3_mantissa_get(audio, audblk->lfe_bap[j], 0);
+ samples[5][j] = mpeg3audio_ac3_tofloat(audblk->lfe_exp[j], mantissa);
+ }
+
+ return mpeg3bits_error(audio->astream);
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.c b/core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.c
new file mode 100644
index 0000000..e2d3912
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.c
@@ -0,0 +1,536 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3audio.h"
+#include "tables.h"
+
+#include <math.h>
+#include <stdlib.h>
+
+mpeg3audio_t* mpeg3audio_allocate_struct(mpeg3_t *file, mpeg3_atrack_t *track)
+{
+ mpeg3audio_t *audio = (mpeg3audio_t*)calloc(1, sizeof(mpeg3audio_t));
+ audio->file = file;
+ audio->track = track;
+ audio->astream = mpeg3bits_new_stream(file, track->demuxer);
+ audio->outscale = 1;
+ audio->bsbuf = audio->bsspace[1];
+ audio->init = 1;
+ audio->bo = 1;
+ audio->channels = 1;
+ return audio;
+}
+
+
+int mpeg3audio_delete_struct(mpeg3audio_t *audio)
+{
+ mpeg3bits_delete_stream(audio->astream);
+ if(audio->pcm_sample) free(audio->pcm_sample);
+ free(audio);
+ return 0;
+}
+
+int mpeg3audio_replace_buffer(mpeg3audio_t *audio, long new_allocation)
+{
+ long i;
+
+ audio->pcm_sample = (mpeg3_real_t*)realloc( audio->pcm_sample, sizeof(mpeg3_real_t) * new_allocation * audio->channels );
+ audio->pcm_allocated = new_allocation;
+/*
+ // Isn't this exactly the same as what the ANSI C function call realloc does,
+ // or did I miss C Programming 101 ?
+
+ if(!audio->pcm_sample)
+ {
+ audio->pcm_sample = (mpeg3_real_t*)malloc(sizeof(mpeg3_real_t) * new_allocation * audio->channels);
+ audio->pcm_allocated = new_allocation;
+ }
+ else
+ {
+ mpeg3_real_t *new_samples = (mpeg3_real_t*)malloc(sizeof(mpeg3_real_t) * new_allocation * audio->channels);
+ for(i = 0; i < audio->pcm_allocated * audio->channels; i++)
+ {
+ new_samples[i] = audio->pcm_sample[i];
+ }
+ free(audio->pcm_sample);
+ audio->pcm_sample = new_samples;
+ audio->pcm_allocated = new_allocation;
+ }
+*/
+ return 0;
+}
+
+int mpeg3audio_read_frame(mpeg3audio_t *audio)
+{
+ int result = 0;
+ result = mpeg3audio_read_header(audio);
+
+ if(!result)
+ {
+ switch(audio->format)
+ {
+ case AUDIO_AC3:
+ result = mpeg3audio_do_ac3(audio);
+ break;
+
+ case AUDIO_MPEG:
+ switch(audio->layer)
+ {
+ case 1:
+ break;
+
+ case 2:
+ result = mpeg3audio_dolayer2(audio);
+ break;
+
+ case 3:
+ result = mpeg3audio_dolayer3(audio);
+ break;
+
+ default:
+ result = 1;
+ break;
+ }
+ break;
+
+ case AUDIO_PCM:
+ result = mpeg3audio_do_pcm(audio);
+ break;
+ }
+ }
+
+ if(!result)
+ {
+/* Byte align the stream */
+ mpeg3bits_byte_align(audio->astream);
+ }
+ return result;
+}
+
+/* Get the length but also initialize the frame sizes. */
+int mpeg3audio_get_length(mpeg3audio_t *audio, mpeg3_atrack_t *track)
+{
+ long result = 0;
+ long framesize1 = 0, total1 = 0;
+ long framesize2 = 0, total2 = 0;
+ long total_framesize = 0, total_frames = 0;
+ long byte_limit = 131072; /* Total bytes to gather information from */
+ long total_bytes = 0;
+ long major_framesize; /* Bigger framesize + header */
+ long minor_framesize; /* Smaller framesize + header */
+ long major_total;
+ long minor_total;
+ mpeg3_t *file = audio->file;
+
+/* Get the frame sizes */
+ mpeg3bits_seek_start(audio->astream);
+ audio->pcm_point = 0;
+ result = mpeg3audio_read_frame(audio); /* Stores the framesize */
+ audio->samples_per_frame = audio->pcm_point / audio->channels;
+
+ switch(audio->format)
+ {
+ case AUDIO_AC3:
+ audio->avg_framesize = audio->framesize;
+ break;
+
+ case AUDIO_MPEG:
+ framesize1 = audio->framesize;
+ total_bytes += audio->framesize;
+ total1 = 1;
+
+ while(!result && total_bytes < byte_limit)
+ {
+ audio->pcm_point = 0;
+ result = mpeg3audio_read_frame(audio);
+ total_bytes += audio->framesize;
+ if(audio->framesize != framesize1)
+ {
+ framesize2 = audio->framesize;
+ total2 = 1;
+ break;
+ }
+ else
+ {
+ total1++;
+ }
+ }
+
+ while(!result && total_bytes < byte_limit)
+ {
+ audio->pcm_point = 0;
+ result = mpeg3audio_read_frame(audio);
+ total_bytes += audio->framesize;
+ if(audio->framesize != framesize2)
+ {
+ break;
+ }
+ else
+ {
+ total2++;
+ }
+ }
+
+ audio->pcm_point = 0;
+ result = mpeg3audio_read_frame(audio);
+ if(audio->framesize != framesize1 && audio->framesize != framesize2)
+ {
+/* Variable bit rate. Get the average frame size. */
+ while(!result && total_bytes < byte_limit)
+ {
+ audio->pcm_point = 0;
+ result = mpeg3audio_read_frame(audio);
+ total_bytes += audio->framesize;
+ if(!result)
+ {
+ total_framesize += audio->framesize;
+ total_frames++;
+ }
+ }
+ audio->avg_framesize = 4 + (total_framesize + framesize1 + framesize2) / (total_frames + total1 + total2);
+ }
+ else
+ {
+ major_framesize = framesize2 > framesize1 ? framesize2 : framesize1;
+ major_total = framesize2 > framesize1 ? total2 : total1;
+ minor_framesize = framesize2 > framesize1 ? framesize1 : framesize2;
+ minor_total = framesize2 > framesize1 ? total1 : total2;
+/* Add the headers to the framesizes */
+ audio->avg_framesize = 4 + (major_framesize * major_total + minor_framesize * minor_total) / (major_total + minor_total);
+ }
+ break;
+
+ case AUDIO_PCM:
+ break;
+ }
+
+/* Estimate the total samples */
+ if(file->is_audio_stream)
+ {
+/* From the raw file */
+ result = (long)((float)mpeg3demuxer_total_bytes(audio->astream->demuxer) / audio->avg_framesize * audio->samples_per_frame);
+ }
+ else
+ {
+/* Gross approximation from a multiplexed file. */
+ result = (long)(mpeg3demux_length(audio->astream->demuxer) * track->sample_rate);
+/* result = (long)((mpeg3_real_t)mpeg3_video_frames(file, 0) / mpeg3_frame_rate(file, 0) * track->sample_rate); */
+/* We would scan the multiplexed packets here for the right timecode if only */
+/* they had meaningful timecode. */
+ }
+
+ audio->pcm_point = 0;
+ mpeg3bits_seek_start(audio->astream);
+ mpeg3audio_reset_synths(audio);
+ return result;
+}
+
+int mpeg3audio_seek(mpeg3audio_t *audio, long position)
+{
+ int result = 0;
+ mpeg3_t *file = audio->file;
+ mpeg3_atrack_t *track = audio->track;
+ long frame_number;
+ long byte_position;
+ double time_position;
+
+/* Sample seek wasn't requested */
+ if(audio->sample_seek < 0)
+ {
+ audio->pcm_position = position;
+ audio->pcm_size = 0;
+ return 0;
+ }
+
+/* Can't slide buffer. Seek instead. */
+ if(!file->is_audio_stream)
+ {
+/* Seek in a multiplexed stream using the multiplexer. */
+ time_position = (double)position / track->sample_rate;
+ result |= mpeg3bits_seek_time(audio->astream, time_position);
+ audio->pcm_position = (long)mpeg3bits_packet_time(audio->astream) * track->sample_rate;
+/*printf("wanted %f got %f\n", time_position, mpeg3bits_packet_time(audio->astream)); */
+ }
+ else
+ {
+/* Seek in an elemental stream. This algorithm achieves sample accuracy on fixed bitrates. */
+/* Forget about variable bitrates or program streams. */
+ frame_number = position / audio->samples_per_frame;
+ byte_position = (long)(audio->avg_framesize * frame_number);
+ audio->pcm_position = frame_number * audio->samples_per_frame;
+
+ if(byte_position < audio->avg_framesize * 2)
+ {
+ result |= mpeg3bits_seek_start(audio->astream);
+ audio->pcm_position = 0;
+ }
+ else
+ {
+ result |= mpeg3bits_seek_byte(audio->astream, byte_position);
+ }
+ }
+
+/* Arm the backstep buffer for layer 3 if not at the beginning already. */
+ if(byte_position >= audio->avg_framesize * 2 && audio->layer == 3 && !result)
+ {
+ result |= mpeg3audio_prev_header(audio);
+ result |= mpeg3audio_read_layer3_frame(audio);
+ }
+
+/* Reset the tables. */
+ mpeg3audio_reset_synths(audio);
+ audio->pcm_size = 0;
+ audio->pcm_point = 0;
+ return result;
+}
+
+/* ================================================================ */
+/* ENTRY POINTS */
+/* ================================================================ */
+
+
+
+
+mpeg3audio_t* mpeg3audio_new(mpeg3_t *file, mpeg3_atrack_t *track, int format)
+{
+ mpeg3audio_t *audio = mpeg3audio_allocate_struct(file, track);
+ int result = 0;
+
+/* Init tables */
+ mpeg3audio_new_decode_tables(audio);
+ audio->percentage_seek = -1;
+ audio->sample_seek = -1;
+ audio->format = format;
+
+/* Determine the format of the stream */
+ if(format == AUDIO_UNKNOWN)
+ {
+ if(((mpeg3bits_showbits(audio->astream, 32) & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE)
+ audio->format = AUDIO_AC3;
+ else
+ audio->format = AUDIO_MPEG;
+ }
+
+/* get channel count */
+ result = mpeg3audio_read_header(audio);
+
+/* Set up the sample buffer */
+ mpeg3audio_replace_buffer(audio, 262144);
+
+/* Copy information to the mpeg struct */
+ if(!result)
+ {
+ track->channels = audio->channels;
+
+ switch(audio->format)
+ {
+ case AUDIO_AC3:
+ track->sample_rate = mpeg3_ac3_samplerates[audio->sampling_frequency_code];
+ break;
+
+ case AUDIO_MPEG:
+ track->sample_rate = mpeg3_freqs[audio->sampling_frequency_code];
+ break;
+
+ case AUDIO_PCM:
+ track->sample_rate = 48000;
+ break;
+ }
+
+ track->total_samples = mpeg3audio_get_length(audio, track);
+ result |= mpeg3bits_seek_start(audio->astream);
+ }
+ else
+ {
+ mpeg3audio_delete_struct(audio);
+ audio = 0;
+ }
+
+ return audio;
+}
+
+int mpeg3audio_delete(mpeg3audio_t *audio)
+{
+ mpeg3audio_delete_struct(audio);
+ return 0;
+}
+
+int mpeg3audio_seek_percentage(mpeg3audio_t *audio, double percentage)
+{
+ audio->percentage_seek = percentage;
+ return 0;
+}
+
+int mpeg3audio_seek_sample(mpeg3audio_t *audio, long sample)
+{
+ audio->sample_seek = sample;
+ return 0;
+}
+
+/* Read raw frames for concatenation purposes */
+int mpeg3audio_read_raw(mpeg3audio_t *audio, unsigned char *output, long *size, long max_size)
+{
+ int result = 0;
+ int i;
+ *size = 0;
+
+ switch(audio->format)
+ {
+ case AUDIO_AC3:
+/* Just write the AC3 stream */
+ if(mpeg3bits_read_buffer(audio->astream, output, audio->framesize))
+ return 1;
+ *size = audio->framesize;
+ break;
+
+ case AUDIO_MPEG:
+/* Fix the mpeg stream */
+ result = mpeg3audio_read_header(audio);
+ if(!result)
+ {
+ if(max_size < 4) return 1;
+ *output++ = (audio->newhead & 0xff000000) >> 24;
+ *output++ = (audio->newhead & 0xff0000) >> 16;
+ *output++ = (audio->newhead & 0xff00) >> 8;
+ *output++ = (audio->newhead & 0xff);
+ *size += 4;
+
+ if(max_size < 4 + audio->framesize) return 1;
+ if(mpeg3bits_read_buffer(audio->astream, output, audio->framesize))
+ return 1;
+
+ *size += audio->framesize;
+ }
+ break;
+
+ case AUDIO_PCM:
+ if(mpeg3bits_read_buffer(audio->astream, output, audio->framesize))
+ return 1;
+ *size = audio->framesize;
+ break;
+ }
+ return result;
+}
+
+/* Channel is 0 to channels - 1 */
+int mpeg3audio_decode_audio(mpeg3audio_t *audio,
+ mpeg3_real_t *output_f,
+ short *output_i, int sampleSpacing,
+ int channel,
+ long start_position,
+ long len)
+{
+ long allocation_needed = len + MPEG3AUDIO_PADDING;
+ long i, j, result = 0;
+ mpeg3_t *file = audio->file;
+ mpeg3_atrack_t *atrack = audio->track;
+ long attempts;
+
+/* Create new buffer */
+ if(audio->pcm_allocated < allocation_needed)
+ {
+ mpeg3audio_replace_buffer(audio, allocation_needed);
+ }
+
+/* There was a percentage seek */
+ if(audio->percentage_seek >= 0)
+ {
+ mpeg3bits_seek_percentage(audio->astream, audio->percentage_seek);
+/* Force the pcm buffer to be reread. */
+ audio->pcm_position = start_position;
+ audio->pcm_size = 0;
+ audio->percentage_seek = -1;
+ }
+ else
+ {
+/* Entire output is in buffer so don't do anything. */
+ if(start_position >= audio->pcm_position && start_position < audio->pcm_position + audio->pcm_size &&
+ start_position + len <= audio->pcm_size)
+ {
+ ;
+ }
+ else
+/* Output starts in buffer but ends later so slide it back. */
+ if(start_position <= audio->pcm_position + audio->pcm_size &&
+ start_position >= audio->pcm_position)
+ {
+ for(i = 0, j = (start_position - audio->pcm_position) * audio->channels;
+ j < audio->pcm_size * audio->channels;
+ i++, j++)
+ {
+ audio->pcm_sample[i] = audio->pcm_sample[j];
+ }
+
+ audio->pcm_point = i;
+ audio->pcm_size -= start_position - audio->pcm_position;
+ audio->pcm_position = start_position;
+ }
+ else
+ {
+/* Output is outside buffer completely. */
+ result = mpeg3audio_seek(audio, start_position);
+ audio->sample_seek = -1;
+/* Check sanity */
+ if(start_position < audio->pcm_position) audio->pcm_position = start_position;
+ }
+ audio->sample_seek = -1;
+ }
+
+/* Read packets until the buffer is full. */
+ if(!result)
+ {
+ attempts = 0;
+ result = 1;
+ while(attempts < 6 &&
+ !mpeg3bits_eof(audio->astream) &&
+ audio->pcm_size + audio->pcm_position < start_position + len)
+ {
+ result = mpeg3audio_read_frame(audio);
+ if(result) attempts++;
+ audio->pcm_size = audio->pcm_point / audio->channels;
+ }
+ }
+
+
+
+/* Copy the buffer to the output */
+ if(output_f)
+ {
+ for(i = 0, j = (start_position - audio->pcm_position) * audio->channels + channel;
+ i < len && j < audio->pcm_size * audio->channels;
+ i++, j += audio->channels)
+ {
+ output_f[i] = audio->pcm_sample[j];
+ }
+ for( ; i < len; i++)
+ {
+ output_f[i] = 0;
+ }
+ }
+ else
+ if(output_i)
+ {
+ int sample;
+ for(i = 0, j = (start_position - audio->pcm_position) * audio->channels + channel;
+ i < (len*(sampleSpacing+1)) && j < audio->pcm_size * audio->channels;
+ i++, j += audio->channels)
+ {
+ sample = (int)(audio->pcm_sample[j] * 32767);
+ if(sample > 32767) sample = 32767;
+ else
+ if(sample < -32768) sample = -32768;
+
+ output_i[i] = sample;
+ i += sampleSpacing;
+ }
+ for( ; i < (len*(sampleSpacing+1)); i++)
+ {
+ output_i[i] = 0;
+ i += sampleSpacing;
+ }
+ }
+
+ if(audio->pcm_point > 0)
+ return 0;
+ else
+ return result;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.h b/core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.h
new file mode 100644
index 0000000..2117be7
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/mpeg3audio.h
@@ -0,0 +1,144 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEG3AUDIO_H
+#define MPEG3AUDIO_H
+
+#include "ac3.h"
+#include "../bitstream.h"
+typedef struct mpeg3_atrack_rec mpeg3_atrack_t;
+
+#define MAXFRAMESIZE 1792
+#define HDRCMPMASK 0xfffffd00
+#define SBLIMIT 32
+#define SSLIMIT 18
+#define SCALE_BLOCK 12
+#define MPEG3AUDIO_PADDING 1024
+
+/* Values for mode */
+#define MPG_MD_STEREO 0
+#define MPG_MD_JOINT_STEREO 1
+#define MPG_MD_DUAL_CHANNEL 2
+#define MPG_MD_MONO 3
+
+/* IMDCT variables */
+typedef struct
+{
+ mpeg3_real_t real;
+ mpeg3_real_t imag;
+} mpeg3_complex_t;
+
+#define AC3_N 512
+
+struct al_table
+{
+ short bits;
+ short d;
+};
+
+typedef struct
+{
+ struct mpeg3_rec* file;
+ mpeg3_atrack_t* track;
+ mpeg3_bits_t *astream;
+
+/* In order of importance */
+ int format; /* format of audio */
+ int layer; /* layer if mpeg */
+ int channels;
+ long outscale;
+ long framenum;
+ long prev_framesize;
+ long framesize; /* For mp3 current framesize without header. For AC3 current framesize with header. */
+ int avg_framesize; /* Includes the 4 byte header */
+ mpeg3_real_t *pcm_sample; /* Interlaced output from synthesizer in floats */
+ int pcm_point; /* Float offset in pcm_sample to write to */
+ long pcm_position; /* Sample start of pcm_samples in file */
+ long pcm_size; /* Number of pcm samples in the buffer */
+ long pcm_allocated; /* Allocated number of samples in pcm_samples */
+ int sample_seek;
+ double percentage_seek;
+ unsigned long oldhead;
+ unsigned long newhead;
+ unsigned long firsthead;
+ int bsnum;
+ int lsf;
+ int mpeg35;
+ int sampling_frequency_code;
+ int bitrate_index;
+ int bitrate;
+ int samples_per_frame;
+ int padding;
+ int extension;
+ int mode;
+ int mode_ext;
+ int copyright;
+ int original;
+ int emphasis;
+ int error_protection;
+
+/* Back step buffers for mp3 */
+ unsigned char bsspace[2][MAXFRAMESIZE + 512]; /* MAXFRAMESIZE */
+ unsigned char *bsbuf, *bsbufold;
+ long ssize;
+ int init;
+ int single;
+ struct al_table *alloc;
+ int II_sblimit;
+ int jsbound;
+ int bo; /* Static variable in synthesizer */
+
+/* MP3 Static arrays here */
+ mpeg3_real_t synth_stereo_buffs[2][2][0x110];
+ mpeg3_real_t synth_mono_buff[64];
+ unsigned int layer2_scfsi_buf[64];
+
+ mpeg3_real_t mp3_block[2][2][SBLIMIT * SSLIMIT];
+ int mp3_blc[2];
+
+/* AC3 specific stuff. AC3 also shares objects with MPEG */
+ unsigned int ac3_framesize_code;
+ mpeg3_ac3bsi_t ac3_bsi;
+ mpeg3_ac3audblk_t ac3_audblk;
+ mpeg3_ac3_bitallocation_t ac3_bit_allocation;
+ mpeg3_ac3_mantissa_t ac3_mantissa;
+ mpeg3_complex_t ac3_imdct_buf[AC3_N / 4];
+
+/* Delay buffer for DCT interleaving */
+ mpeg3_real_t ac3_delay[6][AC3_N / 2];
+/* Twiddle factor LUT */
+ mpeg3_complex_t *ac3_w[7];
+#if !defined(USE_FIXED_POINT) || defined(PRINT_FIXED_POINT_TABLES)
+ /* Just for allocated memory */
+ mpeg3_complex_t ac3_w_1[1];
+ mpeg3_complex_t ac3_w_2[2];
+ mpeg3_complex_t ac3_w_4[4];
+ mpeg3_complex_t ac3_w_8[8];
+ mpeg3_complex_t ac3_w_16[16];
+ mpeg3_complex_t ac3_w_32[32];
+ mpeg3_complex_t ac3_w_64[64];
+#endif
+ int ac3_lfsr_state;
+ unsigned char ac3_buffer[MAX_AC3_FRAMESIZE];
+ mpeg3ac3_stream_samples_t ac3_samples;
+} mpeg3audio_t;
+
+
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/mpeg3real.h b/core/multimedia/opieplayer/libmpeg3/audio/mpeg3real.h
new file mode 100644
index 0000000..cdcac3d
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/mpeg3real.h
@@ -0,0 +1,232 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEG3REAL_H
+#define MPEG3REAL_H
+
+#ifdef USE_FIXED_POINT
+
+#include <limits.h>
+#include <stdio.h>
+
+#ifndef LONGLONG
+#define LONGLONG long long
+#endif
+
+//#define SC (1<<16)
+#define SC (1<<15)
+
+class mpeg3_real_t {
+ long v;
+public:
+ mpeg3_real_t() { } // Uninitialized, just like a float
+ mpeg3_real_t(double d) { v=long(d*SC); }
+ mpeg3_real_t(float f) { v=long(f*SC); }
+ mpeg3_real_t(int i) { v=long(i*SC); }
+ long fixedPoint() const { return v; }
+ operator float() const { return ((float)v)/SC; }
+ operator int() const { return (int)(v/SC); }
+ mpeg3_real_t operator+() const;
+ mpeg3_real_t operator-() const;
+ mpeg3_real_t& operator= (const mpeg3_real_t&);
+ mpeg3_real_t& operator+= (const mpeg3_real_t&);
+ mpeg3_real_t& operator-= (const mpeg3_real_t&);
+ mpeg3_real_t& operator*= (const mpeg3_real_t&);
+ mpeg3_real_t& operator/= (const mpeg3_real_t&);
+ friend mpeg3_real_t operator+ (const mpeg3_real_t&, const mpeg3_real_t&);
+ friend mpeg3_real_t operator- (const mpeg3_real_t&, const mpeg3_real_t&);
+ friend mpeg3_real_t operator* (const mpeg3_real_t&, const mpeg3_real_t&);
+ friend mpeg3_real_t operator/ (const mpeg3_real_t&, const mpeg3_real_t&);
+ friend mpeg3_real_t operator+ (const mpeg3_real_t&, const float&);
+ friend mpeg3_real_t operator- (const mpeg3_real_t&, const float&);
+ friend mpeg3_real_t operator* (const mpeg3_real_t&, const float&);
+ friend mpeg3_real_t operator/ (const mpeg3_real_t&, const float&);
+ friend mpeg3_real_t operator+ (const float&, const mpeg3_real_t&);
+ friend mpeg3_real_t operator- (const float&, const mpeg3_real_t&);
+ friend mpeg3_real_t operator* (const float&, const mpeg3_real_t&);
+ friend mpeg3_real_t operator/ (const float&, const mpeg3_real_t&);
+ friend mpeg3_real_t operator+ (const mpeg3_real_t&, const int&);
+ friend mpeg3_real_t operator- (const mpeg3_real_t&, const int&);
+ friend mpeg3_real_t operator* (const mpeg3_real_t&, const int&);
+ friend mpeg3_real_t operator/ (const mpeg3_real_t&, const int&);
+ friend mpeg3_real_t operator+ (const int&, const mpeg3_real_t&);
+ friend mpeg3_real_t operator- (const int&, const mpeg3_real_t&);
+ friend mpeg3_real_t operator* (const int&, const mpeg3_real_t&);
+ friend mpeg3_real_t operator/ (const int&, const mpeg3_real_t&);
+};
+
+inline mpeg3_real_t mpeg3_real_t::operator+() const
+{
+ return *this;
+}
+
+inline mpeg3_real_t mpeg3_real_t::operator-() const
+{
+ mpeg3_real_t r;
+ r.v=-v;
+ return r;
+}
+
+inline mpeg3_real_t& mpeg3_real_t::operator= (const mpeg3_real_t& o)
+{
+ v=o.v;
+ return *this;
+}
+
+inline mpeg3_real_t& mpeg3_real_t::operator+= (const mpeg3_real_t& o)
+{
+ v += o.v;
+ return *this;
+}
+
+inline mpeg3_real_t& mpeg3_real_t::operator-= (const mpeg3_real_t& o)
+{
+ v -= o.v;
+ return *this;
+}
+
+inline mpeg3_real_t& mpeg3_real_t::operator*= (const mpeg3_real_t& o)
+{
+ *this = *this * o;
+ return *this;
+}
+
+inline mpeg3_real_t& mpeg3_real_t::operator/= (const mpeg3_real_t& o)
+{
+ *this = *this / o;
+ return *this;
+}
+
+
+inline mpeg3_real_t operator+ (const mpeg3_real_t&a, const mpeg3_real_t&b)
+{
+ mpeg3_real_t r;
+ r.v=a.v+b.v;
+ return r;
+}
+
+inline mpeg3_real_t operator- (const mpeg3_real_t&a, const mpeg3_real_t&b)
+{
+ mpeg3_real_t r;
+ r.v=a.v-b.v;
+ return r;
+}
+
+inline mpeg3_real_t operator* (const mpeg3_real_t&a, const mpeg3_real_t&b)
+{
+ mpeg3_real_t r;
+ r.v = (LONGLONG)a.v * b.v / SC;
+ return r;
+}
+
+inline mpeg3_real_t operator/ (const mpeg3_real_t&a, const mpeg3_real_t&b)
+{
+ mpeg3_real_t r;
+ r.v = (LONGLONG)a.v * SC / b.v;
+ return r;
+}
+
+inline mpeg3_real_t operator+ (const mpeg3_real_t&a, const float&b)
+{
+ return a+mpeg3_real_t(b);
+}
+
+inline mpeg3_real_t operator- (const mpeg3_real_t&a, const float&b)
+{
+ return a-mpeg3_real_t(b);
+}
+
+inline mpeg3_real_t operator* (const mpeg3_real_t&a, const float&b)
+{
+ return a*mpeg3_real_t(b);
+}
+
+inline mpeg3_real_t operator/ (const mpeg3_real_t&a, const float&b)
+{
+ return a/mpeg3_real_t(b);
+}
+
+
+inline mpeg3_real_t operator+ (const float&a, const mpeg3_real_t&b)
+{
+ return mpeg3_real_t(a)+b;
+}
+
+inline mpeg3_real_t operator- (const float&a, const mpeg3_real_t&b)
+{
+ return mpeg3_real_t(a)-b;
+}
+
+inline mpeg3_real_t operator* (const float&a, const mpeg3_real_t&b)
+{
+ return mpeg3_real_t(a)*b;
+}
+
+inline mpeg3_real_t operator/ (const float&a, const mpeg3_real_t&b)
+{
+ return mpeg3_real_t(a)/b;
+}
+
+
+inline mpeg3_real_t operator+ (const mpeg3_real_t&a, const int&b)
+{
+ return a+mpeg3_real_t(b);
+}
+
+inline mpeg3_real_t operator- (const mpeg3_real_t&a, const int&b)
+{
+ return a-mpeg3_real_t(b);
+}
+
+inline mpeg3_real_t operator* (const mpeg3_real_t&a, const int&b)
+{
+ return a*mpeg3_real_t(b);
+}
+
+inline mpeg3_real_t operator/ (const mpeg3_real_t&a, const int&b)
+{
+ return a/mpeg3_real_t(b);
+}
+
+
+inline mpeg3_real_t operator+ (const int&a, const mpeg3_real_t&b)
+{
+ return mpeg3_real_t(a)+b;
+}
+
+inline mpeg3_real_t operator- (const int&a, const mpeg3_real_t&b)
+{
+ return mpeg3_real_t(a)-b;
+}
+
+inline mpeg3_real_t operator* (const int&a, const mpeg3_real_t&b)
+{
+ return mpeg3_real_t(a)*b;
+}
+
+inline mpeg3_real_t operator/ (const int&a, const mpeg3_real_t&b)
+{
+ return mpeg3_real_t(a)/b;
+}
+
+#else
+typedef float mpeg3_real_t;
+#endif
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/pcm.c b/core/multimedia/opieplayer/libmpeg3/audio/pcm.c
new file mode 100644
index 0000000..8fa0d25
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/pcm.c
@@ -0,0 +1,51 @@
+#include "mpeg3audio.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+
+int mpeg3audio_read_pcm_header(mpeg3audio_t *audio)
+{
+ unsigned int code;
+
+ code = mpeg3bits_getbits(audio->astream, 16);
+ while(!mpeg3bits_eof(audio->astream) && code != MPEG3_PCM_START_CODE)
+ {
+ code <<= 8;
+ code &= 0xffff;
+ code |= mpeg3bits_getbits(audio->astream, 8);
+ }
+
+ audio->avg_framesize = audio->framesize = 0x7db;
+ audio->channels = 2;
+
+ return mpeg3bits_eof(audio->astream);
+}
+
+int mpeg3audio_do_pcm(mpeg3audio_t *audio)
+{
+ int i, j, k;
+ MPEG3_INT16 sample;
+ int frame_samples = (audio->framesize - 3) / audio->channels / 2;
+
+ if(mpeg3bits_read_buffer(audio->astream, audio->ac3_buffer, frame_samples * audio->channels * 2))
+ return 1;
+
+/* Need more room */
+ if(audio->pcm_point / audio->channels >= audio->pcm_allocated - MPEG3AUDIO_PADDING * audio->channels)
+ {
+ mpeg3audio_replace_buffer(audio, audio->pcm_allocated + MPEG3AUDIO_PADDING * audio->channels);
+ }
+
+ k = 0;
+ for(i = 0; i < frame_samples; i++)
+ {
+ for(j = 0; j < audio->channels; j++)
+ {
+ sample = ((MPEG3_INT16)(audio->ac3_buffer[k++])) << 8;
+ sample |= audio->ac3_buffer[k++];
+ audio->pcm_sample[audio->pcm_point + i * audio->channels + j] =
+ (mpeg3_real_t)sample / 32767;
+ }
+ }
+ audio->pcm_point += frame_samples * audio->channels;
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/synthesizers.c b/core/multimedia/opieplayer/libmpeg3/audio/synthesizers.c
new file mode 100644
index 0000000..71a74b3
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/synthesizers.c
@@ -0,0 +1,174 @@
+#include "mpeg3audio.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "tables.h"
+
+#define WRITE_SAMPLE(samples, sum) \
+{ \
+ (*samples) = (sum); \
+}
+
+int mpeg3audio_synth_stereo(mpeg3audio_t *audio, mpeg3_real_t *bandPtr, int channel, mpeg3_real_t *out, int *pnt)
+{
+ const int step = 2;
+ mpeg3_real_t *samples = out + *pnt;
+ register mpeg3_real_t sum;
+ mpeg3_real_t *b0, (*buf)[0x110];
+ int bo1;
+
+ if(!channel)
+ {
+ audio->bo--;
+ audio->bo &= 0xf;
+ buf = audio->synth_stereo_buffs[0];
+ }
+ else
+ {
+ samples++;
+ buf = audio->synth_stereo_buffs[1];
+ }
+
+ if(audio->bo & 0x1)
+ {
+ b0 = buf[0];
+ bo1 = audio->bo;
+ mpeg3audio_dct64(buf[1] + ((audio->bo + 1) & 0xf), buf[0] + audio->bo, bandPtr);
+ }
+ else
+ {
+ b0 = buf[1];
+ bo1 = audio->bo + 1;
+ mpeg3audio_dct64(buf[0] + audio->bo, buf[1] + audio->bo + 1, bandPtr);
+ }
+
+/*printf("%f %f %f\n", buf[0][0], buf[1][0], bandPtr[0]); */
+
+ {
+ register int j;
+ mpeg3_real_t *window = mpeg3_decwin + 16 - bo1;
+
+ for(j = 16; j; j--, b0 += 0x10, window += 0x20, samples += step)
+ {
+ 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);
+ }
+
+ 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);
+ b0 -= 0x10;
+ window -= 0x20;
+ samples += step;
+ window += bo1 << 1;
+
+ for(j = 15; j; j--, b0 -= 0x10, window -= 0x20, samples += step)
+ {
+ 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);
+ }
+ }
+ *pnt += 64;
+
+ return 0;
+}
+
+int mpeg3audio_synth_mono(mpeg3audio_t *audio, mpeg3_real_t *bandPtr, mpeg3_real_t *samples, int *pnt)
+{
+ mpeg3_real_t *samples_tmp = audio->synth_mono_buff;
+ mpeg3_real_t *tmp1 = samples_tmp;
+ int i, ret;
+ int pnt1 = 0;
+
+ ret = mpeg3audio_synth_stereo(audio, bandPtr, 0, samples_tmp, &pnt1);
+ samples += *pnt;
+
+ for(i = 0; i < 32; i++)
+ {
+ *samples = *tmp1;
+ samples++;
+ tmp1 += 2;
+ }
+ *pnt += 32;
+
+ return ret;
+}
+
+
+/* Call this after every seek to reset the buffers */
+int mpeg3audio_reset_synths(mpeg3audio_t *audio)
+{
+ int i, j, k;
+ for(i = 0; i < 2; i++)
+ {
+ for(j = 0; j < 2; j++)
+ {
+ for(k = 0; k < 0x110; k++)
+ {
+ audio->synth_stereo_buffs[i][j][k] = 0;
+ }
+ }
+ }
+ for(i = 0; i < 64; i++)
+ {
+ audio->synth_mono_buff[i] = 0;
+ audio->layer2_scfsi_buf[i] = 0;
+ }
+ for(i = 0; i < 2; i++)
+ {
+ for(j = 0; j < 2; j++)
+ {
+ for(k = 0; k < SBLIMIT * SSLIMIT; k++)
+ {
+ audio->mp3_block[i][j][k] = 0;
+ }
+ }
+ }
+ audio->mp3_blc[0] = 0;
+ audio->mp3_blc[1] = 0;
+ for(i = 0; i < audio->channels; i++)
+ {
+ for(j = 0; j < AC3_N / 2; j++)
+ {
+ audio->ac3_delay[i][j] = 0;
+ }
+ }
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/tables.c b/core/multimedia/opieplayer/libmpeg3/audio/tables.c
new file mode 100644
index 0000000..aeab335
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/tables.c
@@ -0,0 +1,554 @@
+#include "mpeg3audio.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "tables.h"
+
+#include <math.h>
+
+/* Bitrate indexes */
+int mpeg3_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 mpeg3_freqs[9] = { 44100, 48000, 32000, 22050, 24000, 16000 , 11025 , 12000 , 8000 };
+
+#ifdef USE_3DNOW
+mpeg3_real_t mpeg3_decwin[2 * (512 + 32)];
+mpeg3_real_t mpeg3_cos64[32], mpeg3_cos32[16], mpeg3_cos16[8], mpeg3_cos8[4], mpeg3_cos4[2];
+#else
+mpeg3_real_t mpeg3_decwin[512 + 32];
+mpeg3_real_t mpeg3_cos64[16], mpeg3_cos32[8], mpeg3_cos16[4], mpeg3_cos8[2], mpeg3_cos4[1];
+#endif
+
+mpeg3_real_t *mpeg3_pnts[] = { mpeg3_cos64, mpeg3_cos32, mpeg3_cos16, mpeg3_cos8, mpeg3_cos4 };
+
+int mpeg3_grp_3tab[32 * 3] = { 0, }; /* used: 27 */
+int mpeg3_grp_5tab[128 * 3] = { 0, }; /* used: 125 */
+int mpeg3_grp_9tab[1024 * 3] = { 0, }; /* used: 729 */
+
+REAL_MATRIX(mpeg3_muls, [27], [64]); /* also used by layer 1 */
+REAL_MATRIX(mpeg3_gainpow2, [256 + 118 + 4], );
+REAL_MATRIX(mpeg3_ispow, [8207], );
+REAL_MATRIX(mpeg3_aa_ca, [8], );
+REAL_MATRIX(mpeg3_aa_cs, [8], );
+REAL_MATRIX(mpeg3_win, [4], [36]);
+REAL_MATRIX(mpeg3_win1, [4], [36]);
+REAL_MATRIX(mpeg3_COS1, [12], [6]);
+REAL_MATRIX(mpeg3_COS9, [9], );
+REAL_MATRIX(mpeg3_tfcos36, [9], );
+REAL_MATRIX(mpeg3_tfcos12, [3], );
+REAL_MATRIX(mpeg3_cos9, [3], );
+REAL_MATRIX(mpeg3_cos18, [3], );
+REAL_MATRIX(mpeg3_tan1_1, [16], );
+REAL_MATRIX(mpeg3_tan2_1, [16], );
+REAL_MATRIX(mpeg3_tan1_2, [16], );
+REAL_MATRIX(mpeg3_tan2_2, [16], );
+REAL_MATRIX(mpeg3_pow1_1, [2], [16]);
+REAL_MATRIX(mpeg3_pow2_1, [2], [16]);
+REAL_MATRIX(mpeg3_pow1_2, [2], [16]);
+REAL_MATRIX(mpeg3_pow2_2, [2], [16]);
+
+mpeg3_real_t mpeg3_COS6_1, mpeg3_COS6_2;
+
+#ifdef PRINT_FIXED_POINT_TABLES
+static void print_table(const char* var, mpeg3_real_t* data, int count)
+{
+ int i;
+ printf("#ifdef USE_DATA_TABLES\n");
+ printf("static long %s_data[] = {",var);
+ for(i = 0; i < count; i++) {
+ printf("%c0x%08x,", i%8?' ':'\n', data[i].fixedPoint());
+ }
+ printf("};\n");
+ printf("#endif\n");
+}
+#endif
+
+#ifdef PRINT_FIXED_POINT_TABLES
+# define DO_TABLE(T) print_table(#T, T, sizeof(T)/sizeof(mpeg3_real_t))
+# define DO_TABLE2(T,DIM) print_table(#T, (mpeg3_real_t*)T, sizeof(T)/sizeof(mpeg3_real_t))
+#elif USE_FIXED_POINT
+# define DO_TABLE(T) T = (mpeg3_real_t*)T##_data
+ // multidimensional
+# define DO_TABLE2(T,DIM) T = (mpeg3_real_t(*)DIM)T##_data
+#else
+# define DO_TABLE(T)
+# define DO_TABLE2(T,DIM)
+#endif
+
+#if defined(USE_FIXED_POINT) && !defined(PRINT_FIXED_POINT_TABLES)
+#define USE_DATA_TABLES
+#include "fptables.h"
+#endif
+
+long mpeg3_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 };
+
+int mpeg3_longLimit[9][23];
+int mpeg3_shortLimit[9][14];
+
+struct mpeg3_bandInfoStruct mpeg3_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} } ,
+};
+
+int mpeg3_mapbuf0[9][152];
+int mpeg3_mapbuf1[9][156];
+int mpeg3_mapbuf2[9][44];
+int *mpeg3_map[9][3];
+int *mpeg3_mapend[9][3];
+
+unsigned int mpeg3_n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */
+unsigned int mpeg3_i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */
+
+int mpeg3audio_init_layer3(mpeg3audio_t *audio);
+
+int mpeg3audio_init_layer2(mpeg3audio_t *audio)
+{
+ 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 }
+ };
+ static int tablen[3] = { 3, 5, 9 };
+ static int *itable, *tables[3] = {mpeg3_grp_3tab, mpeg3_grp_5tab, mpeg3_grp_9tab};
+ int i, j, k, l, len;
+ mpeg3_real_t *table;
+
+ 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];
+ }
+ }
+
+#if !defined(USE_FIXED_POINT) || defined(PRINT_FIXED_POINT_TABLES)
+#if defined(PRINT_FIXED_POINT_TABLES)
+ //mpeg3audio_init_layer3(audio); // we depend on mpeg3_muls table
+#endif
+ for(k = 0; k < 27; k++)
+ {
+ double m = mulmul[k];
+ table = mpeg3_muls[k];
+ for(j = 3, i = 0; i < 63; i++, j--)
+ *table++ = m * pow(2.0, (double)j / 3.0);
+ *table++ = 0.0;
+ }
+#endif
+ DO_TABLE2(mpeg3_muls,[64]);
+ return 0;
+}
+
+int mpeg3audio_init_layer3(mpeg3audio_t *audio)
+{
+ int i, j, k, l;
+ int down_sample_sblimit = 32;
+
+ audio->mp3_block[0][0][0] = 0;
+ audio->mp3_blc[0] = 0;
+ audio->mp3_blc[1] = 0;
+
+#if !defined(USE_FIXED_POINT) || defined(PRINT_FIXED_POINT_TABLES)
+ for(i = -256; i < 118 + 4; i++)
+ mpeg3_gainpow2[i + 256] = pow((double)2.0, -0.25 * (double)(i + 210));
+
+ for(i = 0; i < 8207; i++)
+ mpeg3_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]);
+ mpeg3_aa_cs[i] = 1.0/sq;
+ mpeg3_aa_ca[i] = Ci[i]/sq;
+ }
+
+ for(i = 0; i < 18; i++)
+ {
+ mpeg3_win[0][i] = mpeg3_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);
+ mpeg3_win[0][i+18] = mpeg3_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++)
+ {
+ mpeg3_win[1][i + 18] = 0.5 / cos ( M_PI * (double) (2*(i+18)+19) / 72.0 );
+ mpeg3_win[3][i + 12] = 0.5 / cos ( M_PI * (double) (2*(i+12)+19) / 72.0 );
+ mpeg3_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 );
+ mpeg3_win[1][i + 30] = mpeg3_win[3][i] = 0.0;
+ mpeg3_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++)
+ mpeg3_COS9[i] = cos(M_PI / 18.0 * (double)i);
+
+ for(i = 0; i < 9; i++)
+ mpeg3_tfcos36[i] = 0.5 / cos (M_PI * (double) (i*2+1) / 36.0);
+ for(i = 0; i < 3; i++)
+ mpeg3_tfcos12[i] = 0.5 / cos (M_PI * (double) (i*2+1) / 12.0);
+
+ mpeg3_cos9[0] = cos(1.0 * M_PI / 9.0);
+ mpeg3_cos9[1] = cos(5.0 * M_PI / 9.0);
+ mpeg3_cos9[2] = cos(7.0 * M_PI / 9.0);
+ mpeg3_cos18[0] = cos(1.0 * M_PI / 18.0);
+ mpeg3_cos18[1] = cos(11.0 * M_PI / 18.0);
+ mpeg3_cos18[2] = cos(13.0 * M_PI / 18.0);
+
+ for(i = 0; i < 12; i++)
+ {
+ mpeg3_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++)
+ mpeg3_COS1[i][j] = cos(M_PI / 24.0 * (double) ((2 * i + 7) * (2 * j + 1)));
+ }
+
+ for(j = 0; j < 4; j++)
+ {
+ static int len[4] = {36, 36, 12, 36};
+ for(i = 0; i < len[j]; i += 2)
+ mpeg3_win1[j][i] = + mpeg3_win[j][i];
+ for(i = 1; i < len[j]; i += 2)
+ mpeg3_win1[j][i] = - mpeg3_win[j][i];
+ }
+
+ for(i = 0; i < 16; i++)
+ {
+ double t = tan( (double) i * M_PI / 12.0 );
+ mpeg3_tan1_1[i] = t / (1.0 + t);
+ mpeg3_tan2_1[i] = 1.0 / (1.0 + t);
+ mpeg3_tan1_2[i] = M_SQRT2 * t / (1.0 + t);
+ mpeg3_tan2_2[i] = M_SQRT2 / (1.0 + t);
+
+ for(j = 0; j < 2; j++)
+ {
+ double base = pow(2.0, -0.25 * (j + 1.0));
+ double p1 = 1.0,p2 = 1.0;
+ if(i > 0)
+ {
+ if( i & 1 )
+ p1 = pow(base, (i + 1.0) * 0.5);
+ else
+ p2 = pow(base, i * 0.5);
+ }
+ mpeg3_pow1_1[j][i] = p1;
+ mpeg3_pow2_1[j][i] = p2;
+ mpeg3_pow1_2[j][i] = M_SQRT2 * p1;
+ mpeg3_pow2_2[j][i] = M_SQRT2 * p2;
+ }
+ }
+
+#endif
+
+ DO_TABLE(mpeg3_gainpow2);
+ DO_TABLE(mpeg3_ispow);
+ DO_TABLE(mpeg3_aa_cs);
+ DO_TABLE(mpeg3_aa_ca);
+ DO_TABLE2(mpeg3_win,[36]);
+ DO_TABLE(mpeg3_COS9);
+ DO_TABLE(mpeg3_tfcos36);
+ DO_TABLE(mpeg3_tfcos12);
+ DO_TABLE(mpeg3_cos9);
+ DO_TABLE(mpeg3_cos18);
+ DO_TABLE2(mpeg3_COS1,[6]);
+ DO_TABLE2(mpeg3_win1,[36]);
+ DO_TABLE(mpeg3_tan1_1);
+ DO_TABLE(mpeg3_tan2_1);
+ DO_TABLE(mpeg3_tan1_2);
+ DO_TABLE(mpeg3_tan2_2);
+ DO_TABLE2(mpeg3_pow1_1,[16]);
+ DO_TABLE2(mpeg3_pow2_1,[16]);
+ DO_TABLE2(mpeg3_pow1_2,[16]);
+ DO_TABLE2(mpeg3_pow2_2,[16]);
+
+ mpeg3_COS6_1 = cos( M_PI / 6.0 * (double) 1);
+ mpeg3_COS6_2 = cos( M_PI / 6.0 * (double) 2);
+
+ for(j = 0; j < 9; j++)
+ {
+ struct mpeg3_bandInfoStruct *bi = &mpeg3_bandInfo[j];
+ int *mp;
+ int cb,lwin;
+ int *bdf;
+
+ mp = mpeg3_map[j][0] = mpeg3_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;
+ }
+ mpeg3_mapend[j][0] = mp;
+
+ mp = mpeg3_map[j][1] = mpeg3_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;
+ }
+ mpeg3_mapend[j][1] = mp;
+
+ mp = mpeg3_map[j][2] = mpeg3_mapbuf2[j];
+ bdf = bi->longDiff;
+ for(cb = 0; cb < 22 ; cb++)
+ {
+ *mp++ = (*bdf++) >> 1;
+ *mp++ = cb;
+ }
+ mpeg3_mapend[j][2] = mp;
+ }
+
+ for(j = 0; j < 9; j++)
+ {
+ for(i = 0; i < 23; i++)
+ {
+ mpeg3_longLimit[j][i] = (mpeg3_bandInfo[j].longIdx[i] - 1 + 8) / 18 + 1;
+ if(mpeg3_longLimit[j][i] > (down_sample_sblimit))
+ mpeg3_longLimit[j][i] = down_sample_sblimit;
+ }
+ for(i = 0; i < 14; i++)
+ {
+ mpeg3_shortLimit[j][i] = (mpeg3_bandInfo[j].shortIdx[i] - 1) / 18 + 1;
+ if(mpeg3_shortLimit[j][i] > (down_sample_sblimit) )
+ mpeg3_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;
+ mpeg3_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;
+ mpeg3_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;
+ mpeg3_i_slen2[n + 244] = i | (j << 3) | (5 << 12);
+ mpeg3_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;
+ mpeg3_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;
+ mpeg3_n_slen2[n + 400] = i | (j << 3) | (k << 6) | (1 << 12);
+ }
+ }
+ }
+
+ return 0;
+}
+
+int mpeg3audio_new_decode_tables(mpeg3audio_t *audio)
+{
+ int i, j, k, kr, divv;
+ mpeg3_real_t *costab;
+ int idx;
+ long scaleval = audio->outscale;
+
+
+ for(i = 0; i < 5; i++)
+ {
+ kr = 0x10 >> i;
+ divv = 0x40 >> i;
+ costab = mpeg3_pnts[i];
+ for(k = 0; k < kr; k++)
+ costab[k] = 1.0 / (2.0 * cos(M_PI * ((double)k * 2.0 + 1.0) / (double)divv));
+
+#ifdef USE_3DNOW
+ for(k = 0; k < kr; k++)
+ costab[k + kr] = -costab[k];
+#endif
+
+ }
+
+ idx = 0;
+ scaleval = -scaleval;
+ for(i = 0, j = 0; i < 256; i++, j++,idx += 32)
+ {
+ if(idx < 512 + 16)
+ mpeg3_decwin[idx+16] = mpeg3_decwin[idx] = (double)mpeg3_intwinbase[j] / 65536.0 * (double)scaleval;
+
+ if(i % 32 == 31)
+ idx -= 1023;
+ if(i % 64 == 63)
+ scaleval = -scaleval;
+ }
+
+ for( ; i < 512; i++, j--, idx += 32)
+ {
+ if(idx < 512 + 16)
+ mpeg3_decwin[idx + 16] = mpeg3_decwin[idx] = (double)mpeg3_intwinbase[j] / 65536.0 * (double)scaleval;
+
+ if(i % 32 == 31)
+ idx -= 1023;
+ if(i % 64 == 63)
+ scaleval = -scaleval;
+ }
+
+#ifdef USE_3DNOW
+ if(!param.down_sample)
+ {
+ for(i = 0; i < 512 + 32; i++)
+ {
+ mpeg3_decwin[512 + 31 - i] *= 65536.0; /* allows faster clipping in 3dnow code */
+ mpeg3_decwin[512 + 32 + i] = mpeg3_decwin[512 + 31 - i];
+ }
+ }
+#endif
+
+/* Initialize AC3 */
+ audio->ac3_lfsr_state = 1;
+ mpeg3audio_imdct_init(audio);
+/* Initialize MPEG */
+ mpeg3audio_init_layer2(audio); /* inits also shared tables with layer1 */
+ mpeg3audio_init_layer3(audio);
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/tables.h b/core/multimedia/opieplayer/libmpeg3/audio/tables.h
new file mode 100644
index 0000000..7b14de1
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/tables.h
@@ -0,0 +1,88 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef TABLES_H
+#define TABLES_H
+
+extern int mpeg3_tabsel_123[2][3][16];
+
+extern long mpeg3_freqs[9];
+
+struct mpeg3_bandInfoStruct
+{
+ int longIdx[23];
+ int longDiff[22];
+ int shortIdx[14];
+ int shortDiff[13];
+};
+
+
+extern mpeg3_real_t mpeg3_decwin[512 + 32];
+extern mpeg3_real_t mpeg3_cos64[16], mpeg3_cos32[8], mpeg3_cos16[4], mpeg3_cos8[2], mpeg3_cos4[1];
+
+extern mpeg3_real_t *mpeg3_pnts[5];
+
+extern int mpeg3_grp_3tab[32 * 3]; /* used: 27 */
+extern int mpeg3_grp_5tab[128 * 3]; /* used: 125 */
+extern int mpeg3_grp_9tab[1024 * 3]; /* used: 729 */
+extern long mpeg3_intwinbase[257];
+extern mpeg3_real_t mpeg3_COS6_1, mpeg3_COS6_2;
+
+#if defined(USE_FIXED_POINT) && !defined(PRINT_FIXED_POINT_TABLES)
+# define REAL_MATRIX(var,dim1,dimn) mpeg3_real_t (*var)dimn
+#else
+# define REAL_MATRIX(var,dim1,dimn) mpeg3_real_t var dim1 dimn
+#endif
+extern REAL_MATRIX(mpeg3_muls, [27], [64]); /* also used by layer 1 */
+extern REAL_MATRIX(mpeg3_gainpow2, [256 + 118 + 4], );
+extern REAL_MATRIX(mpeg3_ispow, [8207], );
+extern REAL_MATRIX(mpeg3_aa_ca, [8], );
+extern REAL_MATRIX(mpeg3_aa_cs, [8], );
+extern REAL_MATRIX(mpeg3_win, [4], [36]);
+extern REAL_MATRIX(mpeg3_win1, [4], [36]);
+extern REAL_MATRIX(mpeg3_COS1, [12], [6]);
+extern REAL_MATRIX(mpeg3_COS9, [9], );
+extern REAL_MATRIX(mpeg3_tfcos36, [9], );
+extern REAL_MATRIX(mpeg3_tfcos12, [3], );
+extern REAL_MATRIX(mpeg3_cos9, [3], );
+extern REAL_MATRIX(mpeg3_cos18, [3], );
+extern REAL_MATRIX(mpeg3_tan1_1, [16], );
+extern REAL_MATRIX(mpeg3_tan2_1, [16], );
+extern REAL_MATRIX(mpeg3_tan1_2, [16], );
+extern REAL_MATRIX(mpeg3_tan2_2, [16], );
+extern REAL_MATRIX(mpeg3_pow1_1, [2], [16]);
+extern REAL_MATRIX(mpeg3_pow2_1, [2], [16]);
+extern REAL_MATRIX(mpeg3_pow1_2, [2], [16]);
+extern REAL_MATRIX(mpeg3_pow2_2, [2], [16]);
+
+extern int mpeg3_longLimit[9][23];
+extern int mpeg3_shortLimit[9][14];
+
+extern struct mpeg3_bandInfoStruct mpeg3_bandInfo[9];
+
+extern int mpeg3_mapbuf0[9][152];
+extern int mpeg3_mapbuf1[9][156];
+extern int mpeg3_mapbuf2[9][44];
+extern int *mpeg3_map[9][3];
+extern int *mpeg3_mapend[9][3];
+
+extern unsigned int mpeg3_n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */
+extern unsigned int mpeg3_i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/audio/uncouple.c b/core/multimedia/opieplayer/libmpeg3/audio/uncouple.c
new file mode 100644
index 0000000..d87a078
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/audio/uncouple.c
@@ -0,0 +1,135 @@
+/*
+ *
+ * uncouple.c Copyright (C) Aaron Holtzman - May 1999
+ *
+ * This file is part of libmpeg3
+ *
+ * libmpeg3 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.
+ *
+ * libmpeg3 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 "../bitstream.h"
+#include "mpeg3audio.h"
+
+static unsigned char mpeg3_first_bit_lut[256] =
+{
+ 0, 8, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 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,
+ 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,
+ 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
+};
+
+/* Converts an unsigned exponent in the range of 0-24 and a 16 bit mantissa
+ * to an IEEE single precision floating point value */
+static inline void mpeg3audio_ac3_convert_to_float(unsigned short exp,
+ unsigned short mantissa,
+ unsigned MPEG3_INT32 *dest)
+{
+ int num;
+ short exponent;
+ int i;
+
+/* If the mantissa is zero we can simply return zero */
+ if(mantissa == 0)
+ {
+ *dest = 0;
+ return;
+ }
+
+/* Exponent is offset by 127 in IEEE format minus the shift to
+ * align the mantissa to 1.f (subtracted in the final result) */
+ exponent = 127 - exp;
+
+/* Take care of the one asymmetric negative number */
+ if(mantissa == 0x8000)
+ mantissa++;
+
+/* Extract the sign bit, invert the mantissa if it's negative, and
+ shift out the sign bit */
+ if(mantissa & 0x8000)
+ {
+ mantissa *= -1;
+ num = 0x80000000 + (exponent << 23);
+ }
+ else
+ {
+ mantissa *= 1;
+ num = exponent << 23;
+ }
+
+/* Find the index of the most significant one bit */
+ i = mpeg3_first_bit_lut[mantissa >> 8];
+
+ if(i == 0)
+ i = mpeg3_first_bit_lut[mantissa & 0xff] + 8;
+
+ *dest = num - (i << 23) + (mantissa << (7 + i));
+ return;
+}
+
+
+int mpeg3audio_ac3_uncouple(mpeg3audio_t *audio,
+ mpeg3_ac3bsi_t *bsi,
+ mpeg3_ac3audblk_t *audblk,
+ mpeg3_stream_coeffs_t *coeffs)
+{
+ int i, j;
+
+ for(i = 0; i < bsi->nfchans; i++)
+ {
+ for(j = 0; j < audblk->endmant[i]; j++)
+ mpeg3audio_ac3_convert_to_float(audblk->fbw_exp[i][j],
+ audblk->chmant[i][j],
+ (unsigned MPEG3_INT32*)&coeffs->fbw[i][j]);
+ }
+
+ if(audblk->cplinu)
+ {
+ for(i = 0; i < bsi->nfchans; i++)
+ {
+ if(audblk->chincpl[i])
+ {
+ mpeg3audio_ac3_uncouple_channel(audio,
+ coeffs,
+ audblk,
+ i);
+ }
+ }
+
+ }
+
+ if(bsi->lfeon)
+ {
+/* There are always 7 mantissas for lfe */
+ for(j = 0; j < 7 ; j++)
+ mpeg3audio_ac3_convert_to_float(audblk->lfe_exp[j],
+ audblk->lfemant[j],
+ (unsigned MPEG3_INT32*)&coeffs->lfe[j]);
+
+ }
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/bitstream.c b/core/multimedia/opieplayer/libmpeg3/bitstream.c
new file mode 100644
index 0000000..b4f46e3
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/bitstream.c
@@ -0,0 +1,167 @@
+#include "mpeg3private.h"
+#include "mpeg3protos.h"
+
+#include <stdlib.h>
+
+mpeg3_bits_t* mpeg3bits_new_stream(mpeg3_t *file, mpeg3_demuxer_t *demuxer)
+{
+ mpeg3_bits_t *stream = (mpeg3_bits_t*)malloc(sizeof(mpeg3_bits_t));
+ stream->bfr = 0;
+ stream->bfr_size = 0;
+ stream->bit_number = 0;
+ stream->file = file;
+ stream->demuxer = demuxer;
+ stream->input_ptr = 0;
+ return stream;
+}
+
+int mpeg3bits_delete_stream(mpeg3_bits_t* stream)
+{
+ free(stream);
+ return 0;
+}
+
+
+/* Fill a buffer. Only works if bit_number is on an 8 bit boundary */
+int mpeg3bits_read_buffer(mpeg3_bits_t* stream, unsigned char *buffer, int bytes)
+{
+ int result, i = 0;
+ while(stream->bit_number > 0)
+ {
+ stream->bit_number -= 8;
+ mpeg3demux_read_prev_char(stream->demuxer);
+ }
+
+ stream->bit_number = 0;
+ stream->bfr_size = 0;
+ stream->bfr = 0;
+ result = mpeg3demux_read_data(stream->demuxer, buffer, bytes);
+ return result;
+}
+
+/* For mp3 decompression use a pointer in a buffer for getbits. */
+int mpeg3bits_use_ptr(mpeg3_bits_t* stream, unsigned char *buffer)
+{
+ stream->bfr_size = stream->bit_number = 0;
+ stream->bfr = 0;
+ stream->input_ptr = buffer;
+ return 0;
+}
+
+/* Go back to using the demuxer for getbits in mp3. */
+int mpeg3bits_use_demuxer(mpeg3_bits_t* stream)
+{
+ if(stream->input_ptr)
+ {
+ stream->bfr_size = stream->bit_number = 0;
+ stream->input_ptr = 0;
+ stream->bfr = 0;
+ }
+
+ return 0;
+}
+
+/* Reconfigure for reverse operation */
+/* Default is forward operation */
+void mpeg3bits_start_reverse(mpeg3_bits_t* stream)
+{
+ int i;
+ for(i = 0; i < stream->bfr_size; i += 8)
+ if(stream->input_ptr)
+ stream->input_ptr--;
+ else
+ mpeg3demux_read_prev_char(stream->demuxer);
+}
+
+/* Reconfigure for forward operation */
+void mpeg3bits_start_forward(mpeg3_bits_t* stream)
+{
+ int i;
+ for(i = 0; i < stream->bfr_size; i += 8)
+ if(stream->input_ptr)
+ stream->input_ptr++;
+ else
+ mpeg3demux_read_char(stream->demuxer);
+}
+
+/* Erase the buffer with the next 4 bytes in the file. */
+int mpeg3bits_refill(mpeg3_bits_t* stream)
+{
+ stream->bit_number = 32;
+ stream->bfr_size = 32;
+
+ if(stream->input_ptr)
+ {
+ stream->bfr = (unsigned int)(*stream->input_ptr++) << 24;
+ stream->bfr |= (unsigned int)(*stream->input_ptr++) << 16;
+ stream->bfr |= (unsigned int)(*stream->input_ptr++) << 8;
+ stream->bfr |= *stream->input_ptr++;
+ }
+ else
+ {
+ stream->bfr = mpeg3demux_read_char(stream->demuxer) << 24;
+ stream->bfr |= mpeg3demux_read_char(stream->demuxer) << 16;
+ stream->bfr |= mpeg3demux_read_char(stream->demuxer) << 8;
+ stream->bfr |= mpeg3demux_read_char(stream->demuxer);
+ }
+ return mpeg3demux_eof(stream->demuxer);
+}
+
+/* Erase the buffer with the previous 4 bytes in the file. */
+int mpeg3bits_refill_backwards(mpeg3_bits_t* stream)
+{
+ stream->bit_number = 0;
+ stream->bfr_size = 32;
+ stream->bfr = mpeg3demux_read_prev_char(stream->demuxer);
+ stream->bfr |= (unsigned int)mpeg3demux_read_prev_char(stream->demuxer) << 8;
+ stream->bfr |= (unsigned int)mpeg3demux_read_prev_char(stream->demuxer) << 16;
+ stream->bfr |= (unsigned int)mpeg3demux_read_prev_char(stream->demuxer) << 24;
+ return mpeg3demux_eof(stream->demuxer);
+}
+
+int mpeg3bits_byte_align(mpeg3_bits_t *stream)
+{
+ stream->bit_number = (stream->bit_number + 7) & 0xf8;
+ return 0;
+}
+
+int mpeg3bits_seek_end(mpeg3_bits_t* stream)
+{
+ stream->bfr_size = stream->bit_number = 0;
+ return mpeg3demux_seek_byte(stream->demuxer, mpeg3demuxer_total_bytes(stream->demuxer));
+}
+
+int mpeg3bits_seek_start(mpeg3_bits_t* stream)
+{
+ stream->bfr_size = stream->bit_number = 0;
+ return mpeg3demux_seek_byte(stream->demuxer, 0);
+}
+
+int mpeg3bits_seek_time(mpeg3_bits_t* stream, double time_position)
+{
+ stream->bfr_size = stream->bit_number = 0;
+ return mpeg3demux_seek_time(stream->demuxer, time_position);
+}
+
+int mpeg3bits_seek_byte(mpeg3_bits_t* stream, long position)
+{
+ stream->bfr_size = stream->bit_number = 0;
+ return mpeg3demux_seek_byte(stream->demuxer, position);
+}
+
+int mpeg3bits_seek_percentage(mpeg3_bits_t* stream, double percentage)
+{
+ stream->bfr_size = stream->bit_number = 0;
+ return mpeg3demux_seek_percentage(stream->demuxer, percentage);
+}
+
+int mpeg3bits_tell(mpeg3_bits_t* stream)
+{
+ return mpeg3demux_tell(stream->demuxer);
+}
+
+int mpeg3bits_getbitoffset(mpeg3_bits_t *stream)
+{
+ return stream->bit_number & 7;
+}
+
diff --git a/core/multimedia/opieplayer/libmpeg3/bitstream.h b/core/multimedia/opieplayer/libmpeg3/bitstream.h
new file mode 100644
index 0000000..2f6dcf9
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/bitstream.h
@@ -0,0 +1,207 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef BITSTREAM_H
+#define BITSTREAM_H
+
+#include "mpeg3demux.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+// next bit in forward direction
+// next bit in reverse direction |
+// v v
+// | | | | | | | | | | | | | | | | | | | | | | | | | | |1|1|1|1|1|1| */
+// ^ ^
+// | bit_number = 1
+// bfr_size = 6
+
+typedef struct
+{
+ unsigned MPEG3_INT32 bfr; /* bfr = buffer for bits */
+ int bit_number; /* position of pointer in bfr */
+ int bfr_size; /* number of bits in bfr. Should always be a multiple of 8 */
+ struct mpeg3_rec *file; /* Mpeg2 file */
+ mpeg3_demuxer_t *demuxer; /* Mpeg2 demuxer */
+/* If the input ptr is true, data is read from it instead of the demuxer. */
+ unsigned char *input_ptr;
+} mpeg3_bits_t;
+
+LIBMPEG_EXPORT unsigned int mpeg3demux_read_char_packet(mpeg3_demuxer_t *demuxer);
+LIBMPEG_EXPORT unsigned int mpeg3demux_read_prev_char_packet(mpeg3_demuxer_t *demuxer);
+
+/* ======================================================================== */
+/* Entry Points */
+/* ======================================================================== */
+
+#define mpeg3bits_tell_percentage(stream) mpeg3demux_tell_percentage((stream)->demuxer)
+
+#define mpeg3bits_packet_time(stream) mpeg3demux_current_time((stream)->demuxer)
+
+#define mpeg3bits_time_offset(stream) mepg2demux_time_offset((stream)->demuxer)
+
+#define mpeg3bits_error(stream) mpeg3demux_error((stream)->demuxer)
+
+#define mpeg3bits_eof(stream) mpeg3demux_eof((stream)->demuxer)
+
+#define mpeg3bits_bof(stream) mpeg3demux_bof((stream)->demuxer)
+
+/* Read bytes backward from the file until the reverse_bits is full. */
+static inline void mpeg3bits_fill_reverse_bits(mpeg3_bits_t* stream, int bits)
+{
+// Right justify
+ while(stream->bit_number > 7)
+ {
+ stream->bfr >>= 8;
+ stream->bfr_size -= 8;
+ stream->bit_number -= 8;
+ }
+
+// Insert bytes before bfr_size
+ while(stream->bfr_size - stream->bit_number < bits)
+ {
+ if(stream->input_ptr)
+ stream->bfr |= (unsigned int)(*--stream->input_ptr) << stream->bfr_size;
+ else
+ stream->bfr |= (unsigned int)mpeg3demux_read_prev_char(stream->demuxer) << stream->bfr_size;
+ stream->bfr_size += 8;
+ }
+}
+
+/* Read bytes forward from the file until the forward_bits is full. */
+extern inline void mpeg3bits_fill_bits(mpeg3_bits_t* stream, int bits)
+{
+ while(stream->bit_number < bits)
+ {
+ stream->bfr <<= 8;
+ if(stream->input_ptr)
+ {
+ stream->bfr |= *stream->input_ptr++;
+ }
+ else
+ {
+ stream->bfr |= mpeg3demux_read_char(stream->demuxer);
+ }
+ stream->bit_number += 8;
+ stream->bfr_size += 8;
+ if(stream->bfr_size > 32) stream->bfr_size = 32;
+ }
+}
+
+/* Return 8 bits, advancing the file position. */
+extern inline unsigned int mpeg3bits_getbyte_noptr(mpeg3_bits_t* stream)
+{
+ if(stream->bit_number < 8)
+ {
+ stream->bfr <<= 8;
+ if(stream->input_ptr)
+ stream->bfr |= *stream->input_ptr++;
+ else
+ stream->bfr |= mpeg3demux_read_char(stream->demuxer);
+
+ stream->bfr_size += 8;
+ if(stream->bfr_size > 32) stream->bfr_size = 32;
+
+ return (stream->bfr >> stream->bit_number) & 0xff;
+ }
+ return (stream->bfr >> (stream->bit_number -= 8)) & 0xff;
+}
+
+extern inline unsigned int mpeg3bits_getbit_noptr(mpeg3_bits_t* stream)
+{
+ if(!stream->bit_number)
+ {
+ stream->bfr <<= 8;
+ stream->bfr |= mpeg3demux_read_char(stream->demuxer);
+
+ stream->bfr_size += 8;
+ if(stream->bfr_size > 32) stream->bfr_size = 32;
+
+ stream->bit_number = 7;
+
+ return (stream->bfr >> 7) & 0x1;
+ }
+ return (stream->bfr >> (--stream->bit_number)) & (0x1);
+}
+
+/* Return n number of bits, advancing the file position. */
+/* Use in place of flushbits */
+extern inline unsigned int mpeg3bits_getbits(mpeg3_bits_t* stream, int bits)
+{
+ if(bits <= 0) return 0;
+ mpeg3bits_fill_bits(stream, bits);
+ return (stream->bfr >> (stream->bit_number -= bits)) & (0xffffffff >> (32 - bits));
+}
+
+extern inline unsigned int mpeg3bits_showbits24_noptr(mpeg3_bits_t* stream)
+{
+ while(stream->bit_number < 24)
+ {
+ stream->bfr <<= 8;
+ stream->bfr |= mpeg3demux_read_char(stream->demuxer);
+ stream->bit_number += 8;
+ stream->bfr_size += 8;
+ if(stream->bfr_size > 32) stream->bfr_size = 32;
+ }
+ return (stream->bfr >> (stream->bit_number - 24)) & 0xffffff;
+}
+
+extern inline unsigned int mpeg3bits_showbits32_noptr(mpeg3_bits_t* stream)
+{
+ while(stream->bit_number < 32)
+ {
+ stream->bfr <<= 8;
+ stream->bfr |= mpeg3demux_read_char(stream->demuxer);
+ stream->bit_number += 8;
+ stream->bfr_size += 8;
+ if(stream->bfr_size > 32) stream->bfr_size = 32;
+ }
+ return stream->bfr;
+}
+
+extern inline unsigned int mpeg3bits_showbits(mpeg3_bits_t* stream, int bits)
+{
+ mpeg3bits_fill_bits(stream, bits);
+ return (stream->bfr >> (stream->bit_number - bits)) & (0xffffffff >> (32 - bits));
+}
+
+extern inline unsigned int mpeg3bits_getbits_reverse(mpeg3_bits_t* stream, int bits)
+{
+ unsigned int result;
+ mpeg3bits_fill_reverse_bits(stream, bits);
+ result = (stream->bfr >> stream->bit_number) & (0xffffffff >> (32 - bits));
+ stream->bit_number += bits;
+ return result;
+}
+
+extern inline unsigned int mpeg3bits_showbits_reverse(mpeg3_bits_t* stream, int bits)
+{
+ unsigned int result;
+ mpeg3bits_fill_reverse_bits(stream, bits);
+ result = (stream->bfr >> stream->bit_number) & (0xffffffff >> (32 - bits));
+ return result;
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/c_flags b/core/multimedia/opieplayer/libmpeg3/c_flags
new file mode 100755
index 0000000..0c8a75d
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/c_flags
@@ -0,0 +1,4 @@
+case "$1" in
+ *.c) echo $CFLAGS_lessopt
+;; *) echo $CFLAGS
+esac
diff --git a/core/multimedia/opieplayer/libmpeg3/configure b/core/multimedia/opieplayer/libmpeg3/configure
new file mode 100755
index 0000000..e75af76
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/configure
@@ -0,0 +1,102 @@
+#!/bin/sh
+
+USE_MMX=1
+USE_CSS=1
+LESS_OPT=
+PLATFORM_CFLAGS="-malign-loops=2 -malign-jumps=2 -malign-functions=2 -march=i486"
+DEBUG=
+OPTIMIZE=-O2
+OPTIMIZE_less=-O
+DEFINES=
+CC=gcc
+
+for ac_option
+do
+case "$ac_option" in
+ --fixed-point)
+ CC=g++
+ DEFINES="$DEFINES -DUSE_FIXED_POINT"
+ ;;
+
+ --lessopt)
+ LESS_OPT=1
+ ;;
+
+ --no-mmx)
+ USE_MMX=0
+ ;;
+
+ --no-css)
+ USE_CSS=0
+ ;;
+
+ --debug)
+ DEBUG=-g
+ ;;
+
+ --gcc-prefix=*)
+ CROSS=${ac_option#--gcc-prefix=}
+ PLATFORM_CFLAGS=""
+ ;;
+ -h | --help | -help)
+ cat << EOF
+Options:
+ --no-mmx Compile libmpeg3 with no MMX support.
+ --no-css Compile libmpeg3 with no CSS support.
+ --fixed-point Compile libmpeg3 to use integers instead of floats.
+ --debug Compile libmpeg3 with debug support.
+EOF
+ exit 0
+ ;;
+
+ *)
+ ;;
+esac
+done
+
+
+echo "Configuring libmpeg3"
+
+cat > global_config << EOF
+# DO NOT EDIT. EDIT ./configure INSTEAD AND RERUN IT.
+EOF
+
+
+if test -z "$CFLAGS"; then
+ CF="$DEFINES $DEBUG -funroll-loops -fomit-frame-pointer $PLATFORM_CFLAGS"
+ echo >> global_config "CFLAGS = $CF $OPTIMIZE"
+ if test -z "$LESS_OPT"; then
+ echo >> global_config "CFLAGS_lessopt = $CF $OPTIMIZE_less"
+ else
+ echo >> global_config "CFLAGS_lessopt = $CF $OPTIMIZE_less"
+ fi
+fi
+
+cat >> global_config << EOF
+CC = ${CROSS}$CC
+AR = ${CROSS}ar
+NASM = nasm
+EOF
+
+if [ ${USE_CSS} = 1 ]; then
+cat >> global_config << EOF
+CFLAGS += -DHAVE_CSS
+EOF
+fi
+
+if [ ${USE_MMX} = 1 ]; then
+cat >> global_config << EOF
+CFLAGS += -DHAVE_MMX
+MMXOBJS = \
+ video/mmxidct.o \
+ video/reconmmx.o
+MMXOBJS2 = \
+ mmxidct.o \
+ reconmmx.o
+EOF
+fi
+
+
+
+
+echo "done"
diff --git a/core/multimedia/opieplayer/libmpeg3/docs/index.html b/core/multimedia/opieplayer/libmpeg3/docs/index.html
new file mode 100644
index 0000000..2d79978
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/docs/index.html
@@ -0,0 +1,306 @@
+<TITLE>LibMPEG3</TITLE>
+
+<CENTER>
+<FONT FACE=HELVETICA SIZE=+4><B>Using LibMPEG3 to make your own MPEG applications</B></FONT><P>
+
+<TABLE>
+<TR>
+<TD>
+<CODE>
+Author: Adam Williams broadcast@earthling.net<BR>
+Homepage: heroinewarrior.com<BR>
+</CODE>
+</TD>
+</TR>
+</TABLE>
+</CENTER>
+
+<P>
+
+
+LibMPEG3 decodes the many many derivatives of MPEG standards into
+uncompressed data suitable for editing and playback.<P>
+
+libmpeg3 currently decodes:<P>
+
+<BLOCKQUOTE>MPEG-2 video<BR>
+MPEG-1 video<BR>
+mp3 audio<BR>
+mp2 audio<BR>
+ac3 audio<BR>
+MPEG-2 system streams<BR>
+MPEG-1 system streams
+</BLOCKQUOTE><P>
+
+The video output can be in many different color models and frame
+sizes. The audio output can be in twos compliment or floating
+point.<P>
+
+
+
+
+
+
+
+
+
+<FONT FACE=HELVETICA SIZE=+4><B>STEP 1: Verifying file compatibility</B></FONT><P>
+
+Programs using libmpeg3 must <CODE>#include "libmpeg3.h"</CODE>.<P>
+
+Call <CODE>mpeg3_check_sig</CODE> to verify if the file can be read by
+libmpeg3. This returns a 1 if it is compatible and 0 if it isn't.<P>
+
+
+
+
+
+
+
+
+
+
+
+<FONT FACE=HELVETICA SIZE=+4><B>STEP 2: Open the file</B></FONT><P>
+
+You need an <CODE>mpeg3_t*</CODE> file descriptor:<P>
+<CODE>
+mpeg3_t* file;
+</CODE>
+<P>
+
+Then you need to open the file:<P>
+
+<CODE>file = mpeg3_open(char *path);</CODE><P>
+
+<CODE>mpeg3_open</CODE> returns a NULL if the file couldn't be opened
+for some reason. Be sure to check this. Everything you do with
+libmpeg3 requires passing the <CODE>file</CODE> pointer.<P>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<FONT FACE=HELVETICA SIZE=+4><B>STEP 3: How many CPUs do you want to use?</B></FONT><P>
+
+Call <CODE>mpeg3_set_cpus(mpeg3_t *file, int cpus)</CODE> to set how
+many CPUs should be devoted to video decompression. LibMPEG3 can use
+any number. If you don't call this right after opening the file, the
+CPU number defaults to 1.<P>
+
+
+
+
+
+
+
+<FONT FACE=HELVETICA SIZE=+4><B>STEP 4: Get some information about the file.</B></FONT><P>
+
+There are a number of queries for the audio components of the stream:<P>
+
+<CODE><PRE>
+int mpeg3_has_audio(mpeg3_t *file);
+int mpeg3_total_astreams(mpeg3_t *file); // Number of multiplexed audio streams
+int mpeg3_audio_channels(mpeg3_t *file, int stream);
+int mpeg3_sample_rate(mpeg3_t *file, int stream);
+long mpeg3_audio_samples(mpeg3_t *file, int stream); // Total length
+</PRE></CODE>
+
+The audio is presented as a number of <B>streams</B> starting at 0 and
+including <CODE>mpeg3_total_astreams</CODE> - 1. Each stream contains a
+certain number of <B>channels</B> starting at 0 and including
+<CODE>mpeg3_audio_channels</CODE> - 1.
+
+The methodology is first determine if the file has audio, then get
+the number of streams in the file, then for each stream get the number
+of channels, sample rate, and length.<P>
+
+There are also queries for the video components:<P>
+
+<CODE><PRE>
+int mpeg3_has_video(mpeg3_t *file);
+int mpeg3_total_vstreams(mpeg3_t *file); // Number of multiplexed video streams
+int mpeg3_video_width(mpeg3_t *file, int stream);
+int mpeg3_video_height(mpeg3_t *file, int stream);
+float mpeg3_frame_rate(mpeg3_t *file, int stream); // Frames/sec
+long mpeg3_video_frames(mpeg3_t *file, int stream); // Total length
+</PRE></CODE>
+
+The video behavior is the same as with audio, except that video has no
+subdivision under <B>streams</B>. Frame rate is a floating point
+number of frames per second.<P>
+
+
+
+
+
+
+
+<FONT FACE=HELVETICA SIZE=+4><B>STEP 5: Seeking to a point in the file</B></FONT><P>
+
+Each audio stream and each video stream has a position in the file
+independant of each other stream. A variety of methods are available
+for specifying the position of a stream: percentage, frame, sample.
+Which method you use depends on whether you're seeking audio or video
+and whether you're seeking all tracks to a percentage of the file.<P>
+
+The preferred seeking method if you're writing a player is:<P>
+
+<CODE><PRE>
+int mpeg3_seek_percentage(mpeg3_t *file, double percentage);
+double mpeg3_tell_percentage(mpeg3_t *file);
+</PRE></CODE>
+
+This seeks all tracks to a percentage of the file length. The
+percentage is from 0 to 1.<P>
+
+The alternative is absolute seeking. The audio seeking is handled
+by:<P>
+
+<CODE><PRE>
+int mpeg3_set_sample(mpeg3_t *file, long sample, int stream); // Seek
+long mpeg3_get_sample(mpeg3_t *file, int stream); // Tell current position
+</PRE></CODE>
+
+and the video seeking is handled by:<P>
+
+<CODE><PRE>
+int mpeg3_set_frame(mpeg3_t *file, long frame, int stream); // Seek
+long mpeg3_get_frame(mpeg3_t *file, int stream); // Tell current position
+</PRE></CODE>
+
+
+You can either perform percentage seeking or absolute seeking but not
+both on the same file handle. Once you perform either method, the file
+becomes configured for that method.<P>
+
+If you're in percentage seeking mode and you want the current time
+stamp in the file you can't use mpeg3_tell_percentage because you don't
+know how many seconds the total length is. The
+<CODE>mpeg3_audio_samples</CODE> and <CODE>mpeg3_video_frames</CODE>
+commands don't work in percentage seeking. Instead use
+
+<CODE><PRE>
+double mpeg3_get_time(mpeg3_t *file);
+</PRE></CODE>
+
+which gives you the last timecode read in seconds. The MPEG standard
+specifies timecodes being placed in the streams.<P>
+
+
+
+
+
+
+
+
+
+
+
+<FONT FACE=HELVETICA SIZE=+4><B>STEP 6: Read the data</B></FONT><P>
+
+To read <B>audio</B> data use:<P>
+
+<CODE><PRE>
+int mpeg3_read_audio(mpeg3_t *file,
+ float *output_f, // Pointer to pre-allocated buffer of floats
+ short *output_i, // Pointer to pre-allocated buffer if int16's
+ int channel, // Channel to decode
+ long samples, // Number of samples to decode
+ int stream); // Stream containing the channel
+</PRE></CODE>
+
+This decodes a buffer of sequential floats or int16's for a single
+channel, depending on which *output... parameter has a nonzero
+argument. To get a floating point buffer pass a pre-allocated buffer
+to <CODE>output_f</CODE> and NULL to <CODE>output_i</CODE>. To get an
+int16 buffer pass NULL to <CODE>output_f</CODE> and a pre-allocated
+buffer to <CODE>output_i</CODE>.<P>
+
+After reading an audio buffer, the current position in the one stream
+is advanced. How then, do you read more than one channel of audio
+data? Use
+
+<CODE><PRE>
+mpeg3_reread_audio(mpeg3_t *file,
+ float *output_f, /* Pointer to pre-allocated buffer of floats */
+ short *output_i, /* Pointer to pre-allocated buffer of int16's */
+ int channel, /* Channel to decode */
+ long samples, /* Number of samples to decode */
+ int stream);
+</PRE></CODE>
+
+to read each remaining channel after the first channel.<P>
+
+To read <B>video</B> data there are two methods. RGB frames or YUV
+frames. To get an RGB frame use:<BR>
+
+<CODE><PRE>
+int mpeg3_read_frame(mpeg3_t *file,
+ unsigned char **output_rows, // Array of pointers to the start of each output row
+ int in_x, // Location in input frame to take picture
+ int in_y,
+ int in_w,
+ int in_h,
+ int out_w, // Dimensions of output_rows
+ int out_h,
+ int color_model, // One of the color model #defines given above.
+ int stream);
+</PRE></CODE>
+
+The video decoding works like a camcorder taking copy of a movie
+screen. The decoder "sees" a region of the movie screen defined by
+<CODE>in_x, in_y, in_w, in_h</CODE> and transfers it to the frame
+buffer defined by <CODE>**output_rows</CODE>. The input values must be
+within the boundaries given by <CODE>mpeg3_video_width</CODE> and
+<CODE>mpeg3_video_height</CODE>. The size of the frame buffer is
+defined by <CODE>out_w, out_h</CODE>. Although the input dimensions
+are constrained, the frame buffer can be any size.<P>
+
+<CODE>color_model</CODE> defines which RGB color model the picture
+should be decoded to and the possible values are given in
+<B>libmpeg3.h</B>. The frame buffer pointed to by
+<CODE>output_rows</CODE> must have enough memory allocated to store the
+color model you select.<P>
+
+<B>You must allocate 4 extra bytes in the last output_row.</B> This is
+scratch area for the MMX routines.<P>
+
+<CODE>mpeg3_read_frame</CODE> advances the position in the one stream by 1 frame.<P>
+
+The alternative is YUV frames:<BR>
+
+<CODE><PRE>
+int mpeg3_read_yuvframe(mpeg3_t *file,
+ char *y_output,
+ char *u_output,
+ char *v_output,
+ int in_x,
+ int in_y,
+ int in_w,
+ int in_h,
+ int stream);
+</PRE></CODE>
+
+The behavior of in_x, in_y, in_w, in_h is identical to mpeg3_read_frame
+except here you have no control over the output frame size. <B>You
+must allocate in_w * in_h for the y_output, and in_w * in_h / 4 for the
+chroma outputs.</B><P>
+
+
+
+
+
+<FONT FACE=HELVETICA SIZE=+4><B>STEP 7: Close the file</B></FONT><P>
+
+Be sure to close the file with <CODE>mpeg3_close(mpeg3_t *file)</CODE>
+when you're done with it.
diff --git a/core/multimedia/opieplayer/libmpeg3/dump.c b/core/multimedia/opieplayer/libmpeg3/dump.c
new file mode 100644
index 0000000..7158712
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/dump.c
@@ -0,0 +1,79 @@
+#include "libmpeg3.h"
+#include <stdlib.h>
+
+#define BUFSIZE 4096
+
+int main(int argc, char *argv[])
+{
+ mpeg3_t *file;
+ int i, result = 0;
+ unsigned char *output, **output_rows;
+ float *audio_output_f;
+ short *audio_output_i;
+ long total_samples = 0;
+
+ if(argc < 2)
+ {
+ printf("Need an MPEG stream.\n");
+ exit(1);
+ }
+
+ file = mpeg3_open(argv[1]);
+ if(file)
+ {
+ fprintf(stderr, "MMX supported %d\n", file->have_mmx);
+ fprintf(stderr, "Audio streams: %d\n", mpeg3_total_astreams(file));
+ for(i = 0; i < mpeg3_total_astreams(file); i++)
+ {
+ fprintf(stderr, " Stream %d: channels %d sample rate %d total samples %ld\n",
+ i,
+ mpeg3_audio_channels(file, i),
+ mpeg3_sample_rate(file, i),
+ mpeg3_audio_samples(file, i));
+ }
+ fprintf(stderr, "Video streams: %d\n", mpeg3_total_vstreams(file));
+ for(i = 0; i < mpeg3_total_vstreams(file); i++)
+ {
+ fprintf(stderr, " Stream %d: width %d height %d frame rate %0.3f total frames %ld\n",
+ i,
+ mpeg3_video_width(file, i),
+ mpeg3_video_height(file, i),
+ mpeg3_frame_rate(file, i),
+ mpeg3_video_frames(file, i));
+ }
+fprintf(stderr,"S");
+
+ mpeg3_set_cpus(file, 1);
+fprintf(stderr,"s");
+/* audio_output_f = malloc(BUFSIZE * sizeof(float)); */
+ audio_output_i = (short*)malloc(BUFSIZE * 2 * sizeof(short));
+fprintf(stderr,"x");
+/* mpeg3_set_sample(file, 11229518, 0); */
+ /*result = mpeg3_read_audio(file, audio_output_f, 0, 0, BUFSIZE, 0);*/
+ for (i=0; i<100; i++) {
+fprintf(stderr,"c");
+ result = mpeg3_read_audio(file, 0, audio_output_i, 0, BUFSIZE, 0);
+fprintf(stderr,"read\n");
+ }
+ //fwrite(audio_output_i, BUFSIZE, 1, stdout);
+
+ output = (unsigned char*)malloc(mpeg3_video_width(file, 0) * mpeg3_video_height(file, 0) * 3 + 4);
+ output_rows = (unsigned char**)malloc(sizeof(unsigned char*) * mpeg3_video_height(file, 0));
+ for(i = 0; i < mpeg3_video_height(file, 0); i++)
+ output_rows[i] = &output[i * mpeg3_video_width(file, 0) * 3];
+// mpeg3_set_frame(file, 1000, 0);
+ result = mpeg3_read_frame(file,
+ output_rows,
+ 0,
+ 0,
+ mpeg3_video_width(file, 0),
+ mpeg3_video_height(file, 0),
+ mpeg3_video_width(file, 0),
+ mpeg3_video_height(file, 0),
+ MPEG3_RGB888,
+ 0);
+
+ mpeg3_close(file);
+ }
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3.c b/core/multimedia/opieplayer/libmpeg3/libmpeg3.c
new file mode 100644
index 0000000..c0fc570
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3.c
@@ -0,0 +1,672 @@
+#include "libmpeg3.h"
+#include "mpeg3protos.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+mpeg3_t* mpeg3_new(char *path)
+{
+ int i;
+ mpeg3_t *file = (mpeg3_t*)calloc(1, sizeof(mpeg3_t));
+ file->cpus = 1;
+ file->fs = mpeg3_new_fs(path);
+ file->have_mmx = mpeg3_mmx_test();
+ file->demuxer = mpeg3_new_demuxer(file, 0, 0, -1);
+ return file;
+}
+
+int mpeg3_delete(mpeg3_t *file)
+{
+ int i;
+
+ for(i = 0; i < file->total_vstreams; i++)
+ mpeg3_delete_vtrack(file, file->vtrack[i]);
+
+ for(i = 0; i < file->total_astreams; i++)
+ mpeg3_delete_atrack(file, file->atrack[i]);
+
+ mpeg3_delete_fs(file->fs);
+ mpeg3_delete_demuxer(file->demuxer);
+ free(file);
+}
+
+int mpeg3_check_sig(char *path)
+{
+ mpeg3_fs_t *fs;
+ unsigned int bits;
+ char *ext;
+ int result = 0;
+
+ fs = mpeg3_new_fs(path);
+ if(mpeg3io_open_file(fs))
+ {
+/* File not found */
+ return 0;
+ }
+
+ bits = mpeg3io_read_int32(fs);
+/* Test header */
+ if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER)
+ {
+ result = 1;
+ }
+ else
+ if((((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE) ||
+ (bits == MPEG3_PACK_START_CODE) ||
+ ((bits & 0xfff00000) == 0xfff00000) ||
+ (bits == MPEG3_SEQUENCE_START_CODE) ||
+ (bits == MPEG3_PICTURE_START_CODE) ||
+ (((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE) ||
+ ((bits >> 8) == MPEG3_ID3_PREFIX) ||
+ (bits == MPEG3_RIFF_CODE))
+ {
+ result = 1;
+
+ ext = strrchr(path, '.');
+ if(ext)
+ {
+/* Test file extension. */
+ if(strncasecmp(ext, ".mp2", 4) &&
+ strncasecmp(ext, ".mp3", 4) &&
+ strncasecmp(ext, ".m1v", 4) &&
+ strncasecmp(ext, ".m2v", 4) &&
+ strncasecmp(ext, ".m2s", 4) &&
+ strncasecmp(ext, ".mpg", 4) &&
+ strncasecmp(ext, ".vob", 4) &&
+ strncasecmp(ext, ".mpeg", 4) &&
+ strncasecmp(ext, ".ac3", 4))
+ result = 0;
+ }
+ }
+
+ mpeg3io_close_file(fs);
+ mpeg3_delete_fs(fs);
+ return result;
+}
+
+mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file)
+{
+ mpeg3_t *file = 0;
+ unsigned int bits;
+ int i, done;
+
+/* Initialize the file structure */
+ file = mpeg3_new(path);
+
+/* Need to perform authentication before reading a single byte. */
+ if(mpeg3io_open_file(file->fs))
+ {
+ mpeg3_delete(file);
+ return 0;
+ }
+
+/* =============================== Create the title objects ========================= */
+ bits = mpeg3io_read_int32(file->fs);
+
+ if(bits == MPEG3_TOC_PREFIX || bits == MPEG3_TOC_PREFIXLOWER) /* TOCV */
+ {
+/* Table of contents for another file */
+ if(mpeg3_read_toc(file))
+ {
+ mpeg3_delete(file);
+ return 0;
+ }
+ mpeg3io_close_file(file->fs);
+ }
+ else
+ if(((bits >> 24) & 0xff) == MPEG3_SYNC_BYTE)
+ {
+/* Transport stream */
+ file->packet_size = MPEG3_TS_PACKET_SIZE;
+ file->is_transport_stream = 1;
+ }
+ else
+ if(bits == MPEG3_PACK_START_CODE)
+ {
+/* Program stream */
+ file->packet_size = MPEG3_DVD_PACKET_SIZE;
+ file->is_program_stream = 1;
+ }
+ else
+ if((bits & 0xfff00000) == 0xfff00000 ||
+ ((bits >> 8) == MPEG3_ID3_PREFIX) ||
+ (bits == MPEG3_RIFF_CODE))
+ {
+/* MPEG Audio only */
+ file->packet_size = MPEG3_DVD_PACKET_SIZE;
+ file->has_audio = 1;
+ file->is_audio_stream = 1;
+ }
+ else
+ if(bits == MPEG3_SEQUENCE_START_CODE ||
+ bits == MPEG3_PICTURE_START_CODE)
+ {
+/* Video only */
+ file->packet_size = MPEG3_DVD_PACKET_SIZE;
+ file->is_video_stream = 1;
+ }
+ else
+ if(((bits & 0xffff0000) >> 16) == MPEG3_AC3_START_CODE)
+ {
+/* AC3 Audio only */
+ file->packet_size = MPEG3_DVD_PACKET_SIZE;
+ file->has_audio = 1;
+ file->is_audio_stream = 1;
+ }
+ else
+ {
+/* file->packet_size = MPEG3_DVD_PACKET_SIZE; */
+/* file->is_audio_stream = 1; */
+ mpeg3_delete(file);
+ fprintf(stderr, "mpeg3_open: not an MPEG 2 stream\n");
+ return 0;
+ }
+
+/* Create title */
+/* Copy timecodes from an old demuxer */
+ if(old_file && mpeg3_get_demuxer(old_file))
+ {
+ mpeg3demux_copy_titles(file->demuxer, mpeg3_get_demuxer(old_file));
+ }
+ else
+/* Start from scratch */
+ if(!file->demuxer->total_titles)
+ {
+ mpeg3demux_create_title(file->demuxer, 0, 0);
+ }
+
+/* =============================== Get title information ========================= */
+ if(file->is_transport_stream || file->is_program_stream)
+ {
+/* Create video tracks */
+/* Video must be created before audio because audio uses the video timecode */
+/* to get its length. */
+ for(i = 0; i < MPEG3_MAX_STREAMS; i++)
+ {
+ if(file->demuxer->vstream_table[i])
+ {
+ file->vtrack[file->total_vstreams] = mpeg3_new_vtrack(file, i, file->demuxer);
+ if(file->vtrack[file->total_vstreams]) file->total_vstreams++;
+ }
+ }
+
+/* Create audio tracks */
+ for(i = 0; i < MPEG3_MAX_STREAMS; i++)
+ {
+ if(file->demuxer->astream_table[i])
+ {
+ file->atrack[file->total_astreams] = mpeg3_new_atrack(file,
+ i,
+ file->demuxer->astream_table[i],
+ file->demuxer);
+ if(file->atrack[file->total_astreams]) file->total_astreams++;
+ }
+ }
+ }
+ else
+ if(file->is_video_stream)
+ {
+/* Create video tracks */
+ file->vtrack[0] = mpeg3_new_vtrack(file, -1, file->demuxer);
+ if(file->vtrack[0]) file->total_vstreams++;
+ }
+ else
+ if(file->is_audio_stream)
+ {
+/* Create audio tracks */
+ file->atrack[0] = mpeg3_new_atrack(file, -1, AUDIO_UNKNOWN, file->demuxer);
+ if(file->atrack[0]) file->total_astreams++;
+ }
+
+ if(file->total_vstreams) file->has_video = 1;
+ if(file->total_astreams) file->has_audio = 1;
+
+ mpeg3io_close_file(file->fs);
+ return file;
+}
+
+mpeg3_t* mpeg3_open(char *path)
+{
+ return mpeg3_open_copy(path, 0);
+}
+
+int mpeg3_close(mpeg3_t *file)
+{
+/* File is closed in the same procedure it is opened in. */
+ mpeg3_delete(file);
+ return 0;
+}
+
+int mpeg3_set_cpus(mpeg3_t *file, int cpus)
+{
+ int i;
+ file->cpus = cpus;
+ for(i = 0; i < file->total_vstreams; i++)
+ mpeg3video_set_cpus(file->vtrack[i]->video, cpus);
+ return 0;
+}
+
+int mpeg3_set_mmx(mpeg3_t *file, int use_mmx)
+{
+ int i;
+ file->have_mmx = use_mmx;
+ for(i = 0; i < file->total_vstreams; i++)
+ mpeg3video_set_mmx(file->vtrack[i]->video, use_mmx);
+ return 0;
+}
+
+int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams)
+{
+ mpeg3_t *file = mpeg3_open(path);
+ mpeg3_demuxer_t *demuxer;
+ int i;
+
+ if(file)
+ {
+ fprintf(output, "TOCVERSION 2\n"
+ "PATH: %s\n", path);
+ demuxer = mpeg3_new_demuxer(file, 0, 0, -1);
+ mpeg3demux_create_title(demuxer, timecode_search, output);
+/* Just print the first title's streams */
+ if(print_streams) mpeg3demux_print_streams(demuxer, output);
+
+ fprintf(output, "SIZE: %ld\n", demuxer->titles[demuxer->current_title]->total_bytes);
+ fprintf(output, "PACKETSIZE: %ld\n", demuxer->packet_size);
+
+ mpeg3demux_print_timecodes(demuxer->titles[demuxer->current_title], output);
+
+ mpeg3_delete_demuxer(demuxer);
+ mpeg3_close(file);
+ return 0;
+ }
+ return 1;
+}
+
+int mpeg3_read_toc(mpeg3_t *file)
+{
+ char string[MPEG3_STRLEN];
+ int number1;
+
+/* Test version number */
+ file->is_program_stream = 1;
+ mpeg3io_seek(file->fs, 0);
+ fscanf(file->fs->fd, "%s %d", string, &number1);
+ if(number1 > 2 || number1 < 2) return 1;
+
+/* Read titles */
+ mpeg3demux_read_titles(file->demuxer);
+ return 0;
+}
+
+int mpeg3_has_audio(mpeg3_t *file)
+{
+ return file->has_audio;
+}
+
+int mpeg3_total_astreams(mpeg3_t *file)
+{
+ return file->total_astreams;
+}
+
+int mpeg3_audio_channels(mpeg3_t *file,
+ int stream)
+{
+ if(file->has_audio)
+ return file->atrack[stream]->channels;
+ return -1;
+}
+
+int mpeg3_sample_rate(mpeg3_t *file,
+ int stream)
+{
+ if(file->has_audio)
+ return file->atrack[stream]->sample_rate;
+ return -1;
+}
+
+long mpeg3_get_sample(mpeg3_t *file,
+ int stream)
+{
+ if(file->has_audio)
+ return file->atrack[stream]->current_position;
+ return -1;
+}
+
+int mpeg3_set_sample(mpeg3_t *file,
+ long sample,
+ int stream)
+{
+ if(file->has_audio)
+ {
+ file->atrack[stream]->current_position = sample;
+ mpeg3audio_seek_sample(file->atrack[stream]->audio, sample);
+ return 0;
+ }
+ return -1;
+}
+
+long mpeg3_audio_samples(mpeg3_t *file,
+ int stream)
+{
+ if(file->has_audio)
+ return file->atrack[stream]->total_samples;
+ return -1;
+}
+
+int mpeg3_has_video(mpeg3_t *file)
+{
+ return file->has_video;
+}
+
+int mpeg3_total_vstreams(mpeg3_t *file)
+{
+ return file->total_vstreams;
+}
+
+int mpeg3_video_width(mpeg3_t *file,
+ int stream)
+{
+ if(file->has_video)
+ return file->vtrack[stream]->width;
+ return -1;
+}
+
+int mpeg3_video_height(mpeg3_t *file,
+ int stream)
+{
+ if(file->has_video)
+ return file->vtrack[stream]->height;
+ return -1;
+}
+
+float mpeg3_frame_rate(mpeg3_t *file,
+ int stream)
+{
+ if(file->has_video)
+ return file->vtrack[stream]->frame_rate;
+ return -1;
+}
+
+long mpeg3_video_frames(mpeg3_t *file,
+ int stream)
+{
+ if(file->has_video)
+ return file->vtrack[stream]->total_frames;
+ return -1;
+}
+
+long mpeg3_get_frame(mpeg3_t *file,
+ int stream)
+{
+ if(file->has_video)
+ return file->vtrack[stream]->current_position;
+ return -1;
+}
+
+int mpeg3_set_frame(mpeg3_t *file,
+ long frame,
+ int stream)
+{
+ if(file->has_video)
+ {
+ file->vtrack[stream]->current_position = frame;
+ mpeg3video_seek_frame(file->vtrack[stream]->video, frame);
+ return 0;
+ }
+ return -1;
+}
+
+int mpeg3_seek_percentage(mpeg3_t *file, double percentage)
+{
+ int i;
+ for(i = 0; i < file->total_astreams; i++)
+ {
+ mpeg3audio_seek_percentage(file->atrack[i]->audio, percentage);
+ }
+
+ for(i = 0; i < file->total_vstreams; i++)
+ {
+ mpeg3video_seek_percentage(file->vtrack[i]->video, percentage);
+ }
+ return 0;
+}
+
+int mpeg3_previous_frame(mpeg3_t *file, int stream)
+{
+ file->last_type_read = 2;
+ file->last_stream_read = stream;
+
+ if(file->has_video)
+ return mpeg3video_previous_frame(file->vtrack[stream]->video);
+}
+
+double mpeg3_tell_percentage(mpeg3_t *file)
+{
+ double percent = 0;
+ if(file->last_type_read == 1)
+ {
+ percent = mpeg3demux_tell_percentage(file->atrack[file->last_stream_read]->demuxer);
+ }
+
+ if(file->last_type_read == 2)
+ {
+ percent = mpeg3demux_tell_percentage(file->vtrack[file->last_stream_read]->demuxer);
+ }
+ return percent;
+}
+
+double mpeg3_get_time(mpeg3_t *file)
+{
+ double atime = 0, vtime = 0;
+
+ if(file->is_transport_stream || file->is_program_stream)
+ {
+/* Timecode only available in transport stream */
+ if(file->last_type_read == 1)
+ {
+ atime = mpeg3demux_get_time(file->atrack[file->last_stream_read]->demuxer);
+ }
+ else
+ if(file->last_type_read == 2)
+ {
+ vtime = mpeg3demux_get_time(file->vtrack[file->last_stream_read]->demuxer);
+ }
+ }
+ else
+ {
+/* Use percentage and total time */
+ if(file->has_audio)
+ {
+ atime = mpeg3demux_tell_percentage(file->atrack[0]->demuxer) *
+ mpeg3_audio_samples(file, 0) / mpeg3_sample_rate(file, 0);
+ }
+
+ if(file->has_video)
+ {
+ vtime = mpeg3demux_tell_percentage(file->vtrack[0]->demuxer) *
+ mpeg3_video_frames(file, 0) / mpeg3_frame_rate(file, 0);
+ }
+ }
+
+ return MAX(atime, vtime);
+}
+
+int mpeg3_end_of_audio(mpeg3_t *file, int stream)
+{
+ int result = 0;
+ result = mpeg3demux_eof(file->atrack[stream]->demuxer);
+ return result;
+}
+
+int mpeg3_end_of_video(mpeg3_t *file, int stream)
+{
+ int result = 0;
+ result = mpeg3demux_eof(file->vtrack[stream]->demuxer);
+ return result;
+}
+
+
+int mpeg3_read_frame(mpeg3_t *file,
+ unsigned char **output_rows,
+ int in_x,
+ int in_y,
+ int in_w,
+ int in_h,
+ int out_w,
+ int out_h,
+ int color_model,
+ int stream)
+{
+ int result = -1;
+
+ if(file->has_video)
+ {
+ result = mpeg3video_read_frame(file->vtrack[stream]->video,
+ file->vtrack[stream]->current_position,
+ output_rows,
+ in_x,
+ in_y,
+ in_w,
+ in_h,
+ out_w,
+ out_h,
+ color_model);
+ file->last_type_read = 2;
+ file->last_stream_read = stream;
+ file->vtrack[stream]->current_position++;
+ }
+ return result;
+}
+
+int mpeg3_drop_frames(mpeg3_t *file, long frames, int stream)
+{
+ int result = -1;
+
+ if(file->has_video)
+ {
+ result = mpeg3video_drop_frames(file->vtrack[stream]->video,
+ frames);
+ if(frames > 0) file->vtrack[stream]->current_position += frames;
+ file->last_type_read = 2;
+ file->last_stream_read = stream;
+ }
+ return result;
+}
+
+int mpeg3_read_yuvframe(mpeg3_t *file,
+ char *y_output,
+ char *u_output,
+ char *v_output,
+ int in_x,
+ int in_y,
+ int in_w,
+ int in_h,
+ int stream)
+{
+ int result = -1;
+
+//printf("mpeg3_read_yuvframe 1 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer));
+ if(file->has_video)
+ {
+ result = mpeg3video_read_yuvframe(file->vtrack[stream]->video,
+ file->vtrack[stream]->current_position,
+ y_output,
+ u_output,
+ v_output,
+ in_x,
+ in_y,
+ in_w,
+ in_h);
+ file->last_type_read = 2;
+ file->last_stream_read = stream;
+ file->vtrack[stream]->current_position++;
+ }
+//printf("mpeg3_read_yuvframe 2 %d %d\n", mpeg3demux_tell(file->vtrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->vtrack[stream]->demuxer));
+ return result;
+}
+
+
+int mpeg3_read_audio(mpeg3_t *file,
+ mpeg3_real_t *output_f,
+ short *output_i, int sampleSpacing,
+ int channel,
+ long samples,
+ int stream)
+{
+ int result = -1;
+
+//printf("mpeg3_read_audio 1 %d %d\n", mpeg3demux_tell(file->atrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->atrack[stream]->demuxer));
+ if(file->has_audio)
+ {
+ result = mpeg3audio_decode_audio(file->atrack[stream]->audio,
+ output_f,
+ output_i, sampleSpacing,
+ channel,
+ file->atrack[stream]->current_position,
+ samples);
+ file->last_type_read = 1;
+ file->last_stream_read = stream;
+ file->atrack[stream]->current_position += samples;
+ }
+//printf("mpeg3_read_audio 2 %d %d\n", mpeg3demux_tell(file->atrack[stream]->demuxer), mpeg3demuxer_total_bytes(file->atrack[stream]->demuxer));
+
+ return result;
+}
+
+int mpeg3_reread_audio(mpeg3_t *file,
+ mpeg3_real_t *output_f,
+ short *output_i, int sampleSpacing,
+ int channel,
+ long samples,
+ int stream)
+{
+ if(file->has_audio)
+ {
+ mpeg3_set_sample(file,
+ file->atrack[stream]->current_position - samples,
+ stream);
+ file->last_type_read = 1;
+ file->last_stream_read = stream;
+ return mpeg3_read_audio(file,
+ output_f,
+ output_i, sampleSpacing,
+ channel,
+ samples,
+ stream);
+ }
+ return -1;
+}
+
+int mpeg3_read_audio_chunk(mpeg3_t *file,
+ unsigned char *output,
+ long *size,
+ long max_size,
+ int stream)
+{
+ int result = 0;
+ if(file->has_audio)
+ {
+ result = mpeg3audio_read_raw(file->atrack[stream]->audio, output, size, max_size);
+ file->last_type_read = 1;
+ file->last_stream_read = stream;
+ }
+ return result;
+}
+
+int mpeg3_read_video_chunk(mpeg3_t *file,
+ unsigned char *output,
+ long *size,
+ long max_size,
+ int stream)
+{
+ int result = 0;
+ if(file->has_video)
+ {
+ result = mpeg3video_read_raw(file->vtrack[stream]->video, output, size, max_size);
+ file->last_type_read = 2;
+ file->last_stream_read = stream;
+ }
+ return result;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3.h b/core/multimedia/opieplayer/libmpeg3/libmpeg3.h
new file mode 100644
index 0000000..f4eced4
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3.h
@@ -0,0 +1,175 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef LIBMPEG3_H
+#define LIBMPEG3_H
+
+#include "mpeg3private.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Supported color models for mpeg3_read_frame */
+#define MPEG3_RGB565 2
+#define MPEG3_BGR888 0
+#define MPEG3_BGRA8888 1
+#define MPEG3_RGB888 3
+#define MPEG3_RGBA8888 4
+#define MPEG3_RGBA16161616 5
+
+/* Color models for the 601 to RGB conversion */
+/* 601 not implemented for scalar code */
+#define MPEG3_601_RGB565 11
+#define MPEG3_601_BGR888 7
+#define MPEG3_601_BGRA8888 8
+#define MPEG3_601_RGB888 9
+#define MPEG3_601_RGBA8888 10
+
+/* Check for file compatibility. Return 1 if compatible. */
+LIBMPEG_EXPORT int mpeg3_check_sig(char *path);
+
+/* Open the MPEG3 stream. */
+LIBMPEG_EXPORT mpeg3_t* mpeg3_open(char *path);
+
+/* Open the MPEG3 stream and copy the tables from an already open stream. */
+/* Eliminates the initial timecode search. */
+LIBMPEG_EXPORT mpeg3_t* mpeg3_open_copy(char *path, mpeg3_t *old_file);
+LIBMPEG_EXPORT int mpeg3_close(mpeg3_t *file);
+
+/* Performance */
+LIBMPEG_EXPORT int mpeg3_set_cpus(mpeg3_t *file, int cpus);
+LIBMPEG_EXPORT int mpeg3_set_mmx(mpeg3_t *file, int use_mmx);
+
+/* Query the MPEG3 stream about audio. */
+LIBMPEG_EXPORT int mpeg3_has_audio(mpeg3_t *file);
+LIBMPEG_EXPORT int mpeg3_total_astreams(mpeg3_t *file); /* Number of multiplexed audio streams */
+LIBMPEG_EXPORT int mpeg3_audio_channels(mpeg3_t *file, int stream);
+LIBMPEG_EXPORT int mpeg3_sample_rate(mpeg3_t *file, int stream);
+
+/* Total length obtained from the timecode. */
+/* For DVD files, this is unreliable. */
+LIBMPEG_EXPORT long mpeg3_audio_samples(mpeg3_t *file, int stream);
+LIBMPEG_EXPORT int mpeg3_set_sample(mpeg3_t *file, long sample, int stream); /* Seek to a sample */
+LIBMPEG_EXPORT long mpeg3_get_sample(mpeg3_t *file, int stream); /* Tell current position */
+
+/* Read a PCM buffer of audio from 1 channel and advance the position. */
+/* Return a 1 if error. */
+/* Stream defines the number of the multiplexed stream to read. */
+LIBMPEG_EXPORT int mpeg3_read_audio(mpeg3_t *file,
+ mpeg3_real_t *output_f, /* Pointer to pre-allocated buffer of floats */
+ short *output_i, /* Pointer to pre-allocated buffer of int16's */
+ int sampleSpacing, // how many bytes to skip over inbetween samples
+ int channel, /* Channel to decode */
+ long samples, /* Number of samples to decode */
+ int stream); /* Stream containing the channel */
+
+/* Reread the last PCM buffer from a different channel and advance the position */
+LIBMPEG_EXPORT int mpeg3_reread_audio(mpeg3_t *file,
+ mpeg3_real_t *output_f, /* Pointer to pre-allocated buffer of floats */
+ short *output_i, /* Pointer to pre-allocated buffer of int16's */
+ int sampleSpacing, // how many bytes to skip over inbetween samples
+ int channel, /* Channel to decode */
+ long samples, /* Number of samples to decode */
+ int stream); /* Stream containing the channel */
+
+/* Read the next compressed audio chunk. Store the size in size and return a */
+/* 1 if error. */
+/* Stream defines the number of the multiplexed stream to read. */
+LIBMPEG_EXPORT int mpeg3_read_audio_chunk(mpeg3_t *file,
+ unsigned char *output,
+ long *size,
+ long max_size,
+ int stream);
+
+/* Query the stream about video. */
+LIBMPEG_EXPORT int mpeg3_has_video(mpeg3_t *file);
+LIBMPEG_EXPORT int mpeg3_total_vstreams(mpeg3_t *file); /* Number of multiplexed video streams */
+LIBMPEG_EXPORT int mpeg3_video_width(mpeg3_t *file, int stream);
+LIBMPEG_EXPORT int mpeg3_video_height(mpeg3_t *file, int stream);
+LIBMPEG_EXPORT float mpeg3_frame_rate(mpeg3_t *file, int stream); /* Frames/sec */
+
+/* Total length. */
+/* For DVD files, this is 1 indicating only percentage seeking is available. */
+LIBMPEG_EXPORT long mpeg3_video_frames(mpeg3_t *file, int stream);
+LIBMPEG_EXPORT int mpeg3_set_frame(mpeg3_t *file, long frame, int stream); /* Seek to a frame */
+LIBMPEG_EXPORT int mpeg3_skip_frames();
+LIBMPEG_EXPORT long mpeg3_get_frame(mpeg3_t *file, int stream); /* Tell current position */
+
+/* Seek all the tracks based on a percentage of the total bytes in the */
+/* file or the total */
+/* time in a toc if one exists. Percentage is a 0 to 1 double. */
+/* This eliminates the need for tocs and 64 bit longs but doesn't */
+/* give frame accuracy. */
+LIBMPEG_EXPORT int mpeg3_seek_percentage(mpeg3_t *file, double percentage);
+LIBMPEG_EXPORT double mpeg3_tell_percentage(mpeg3_t *file);
+LIBMPEG_EXPORT int mpeg3_previous_frame(mpeg3_t *file, int stream);
+LIBMPEG_EXPORT int mpeg3_end_of_audio(mpeg3_t *file, int stream);
+LIBMPEG_EXPORT int mpeg3_end_of_video(mpeg3_t *file, int stream);
+
+/* Give the seconds time in the last packet read */
+LIBMPEG_EXPORT double mpeg3_get_time(mpeg3_t *file);
+
+/* Read a frame. The dimensions of the input area and output frame must be supplied. */
+/* The frame is taken from the input area and scaled to fit the output frame in 1 step. */
+/* Stream defines the number of the multiplexed stream to read. */
+/* The last row of **output_rows must contain 4 extra bytes for scratch work. */
+LIBMPEG_EXPORT int mpeg3_read_frame(mpeg3_t *file,
+ unsigned char **output_rows, /* Array of pointers to the start of each output row */
+ int in_x, /* Location in input frame to take picture */
+ int in_y,
+ int in_w,
+ int in_h,
+ int out_w, /* Dimensions of output_rows */
+ int out_h,
+ int color_model, /* One of the color model #defines */
+ int stream);
+
+/* Read a YUV frame. The 3 planes are copied into the y, u, and v buffers provided. */
+/* The input is cropped to the dimensions given but not scaled. */
+LIBMPEG_EXPORT int mpeg3_read_yuvframe(mpeg3_t *file,
+ char *y_output,
+ char *u_output,
+ char *v_output,
+ int in_x,
+ int in_y,
+ int in_w,
+ int in_h,
+ int stream);
+
+LIBMPEG_EXPORT int mpeg3_drop_frames(mpeg3_t *file, long frames, int stream);
+
+/* Read the next compressed frame including headers. */
+/* Store the size in size and return a 1 if error. */
+/* Stream defines the number of the multiplexed stream to read. */
+LIBMPEG_EXPORT int mpeg3_read_video_chunk(mpeg3_t *file,
+ unsigned char *output,
+ long *size,
+ long max_size,
+ int stream);
+
+/* Master control */
+LIBMPEG_EXPORT int mpeg3_total_programs();
+LIBMPEG_EXPORT int mpeg3_set_program(int program);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3.pro b/core/multimedia/opieplayer/libmpeg3/libmpeg3.pro
new file mode 100644
index 0000000..e2c35d3
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3.pro
@@ -0,0 +1,42 @@
+TEMPLATE = lib
+CONFIG += qt warn_on release
+HEADERS = libmpeg3plugin.h libmpeg3pluginimpl.h
+SOURCES = libmpeg3plugin.cpp libmpeg3pluginimpl.cpp \
+ bitstream.c \
+ libmpeg3.c \
+ mpeg3atrack.c \
+ mpeg3css.c \
+ mpeg3demux.c \
+ mpeg3io.c \
+ mpeg3title.c \
+ mpeg3vtrack.c \
+ audio/ac3.c \
+ audio/bit_allocation.c \
+ audio/dct.c \
+ audio/exponents.c \
+ audio/header.c \
+ audio/layer2.c \
+ audio/layer3.c \
+ audio/mantissa.c \
+ audio/mpeg3audio.c \
+ audio/pcm.c \
+ audio/synthesizers.c \
+ audio/tables.c \
+ video/getpicture.c \
+ video/headers.c \
+ video/idct.c \
+ video/macroblocks.c \
+ video/mmxtest.c \
+ video/motion.c \
+ video/mpeg3video.c \
+ video/output.c \
+ video/reconstruct.c \
+ video/seek.c \
+ video/slice.c \
+ video/vlc.c
+TARGET = mpeg3plugin
+DESTDIR = ../../plugins/codecs
+INCLUDEPATH += $(QPEDIR)/include ..
+DEPENDPATH += ../$(QPEDIR)/include ..
+LIBS += -lqpe -lpthread -lm
+VERSION = 1.0.0
diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.cpp b/core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.cpp
new file mode 100644
index 0000000..044cb4a
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.cpp
@@ -0,0 +1,105 @@
+/**********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "libmpeg3plugin.h"
+
+/*
+bool LibMpeg3Plugin::audioReadSamples( short *output, int channel, long samples, int stream ) {
+ return file ? mpeg3_read_audio( file, 0, output, 0, channel, samples, stream ) == 1 : FALSE;
+}
+
+
+bool LibMpeg3Plugin::audioReReadSamples( short *output, int channel, long samples, int stream ) {
+ return file ? mpeg3_reread_audio( file, 0, output, 0, channel, samples, stream ) == 1 : FALSE;
+}
+
+
+bool LibMpeg3Plugin::audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ) {
+ samplesRead = samples;
+ return file ? mpeg3_read_audio( file, 0, output, 0, 0, samples, stream ) == 1 : FALSE;
+}
+
+
+bool LibMpeg3Plugin::audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ) {
+ bool err = FALSE;
+ if ( file ) {
+#if 1
+ err = mpeg3_read_audio ( file, 0, output, 1, 0, samples, stream ) == 1;
+ if ( err == FALSE ) {
+ err = mpeg3_reread_audio( file, 0, output + 1, 1, 1, samples, stream ) == 1;
+#else
+ short left[samples];
+ short right[samples];
+ err = mpeg3_read_audio ( file, 0, left, 0, samples, stream ) == 1;
+ if ( !err )
+ err = mpeg3_reread_audio( file, 0, right, 1, samples, stream ) == 1;
+ for ( int j = 0; j < samples; j++ ) {
+ output[j*2+0] = left[j];
+ output[j*2+1] = right[j];
+#endif
+ }
+ }
+ samplesRead = samples;
+ return err;
+}
+*/
+
+bool LibMpeg3Plugin::audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ) {
+ samplesRead = samples;
+ switch ( channels ) {
+ case 1:
+ return file ? mpeg3_read_audio( file, 0, output, 0, 0, samples, stream ) == 1 : FALSE;
+ case 2:
+ if ( ( file ) && ( mpeg3_read_audio( file, 0, output, 1, 0, samples, stream ) != 1 ) &&
+ ( mpeg3_reread_audio( file, 0, output + 1, 1, 1, samples, stream ) != 1 ) )
+ return TRUE;
+ return FALSE;
+ }
+ return FALSE;
+}
+
+bool LibMpeg3Plugin::videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ) {
+ int format = MPEG3_RGB565;
+ switch ( color_model ) {
+ case RGB565: format = MPEG3_RGB565; break;
+ case BGR565: /*format = MPEG3_BGR565;*/ break;
+ case RGBA8888: format = MPEG3_RGBA8888; break;
+ case BGRA8888: format = MPEG3_BGRA8888; break;
+ }
+ return file ? mpeg3_read_frame( file, output_rows, in_x, in_y, in_w, in_h, in_w, in_h, format, stream ) == 1 : FALSE;
+}
+
+
+bool LibMpeg3Plugin::videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream ) {
+ int format = MPEG3_RGB565;
+ switch ( color_model ) {
+ case RGB565: format = MPEG3_RGB565; break;
+ case BGR565: /*format = MPEG3_BGR565;*/ break;
+ case RGBA8888: format = MPEG3_RGBA8888; break;
+ case BGRA8888: format = MPEG3_BGRA8888; break;
+ }
+ return file ? mpeg3_read_frame( file, output_rows, in_x, in_y, in_w, in_h, out_w, out_h, format, stream ) == 1 : FALSE;
+}
+
+
+bool LibMpeg3Plugin::videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream ) {
+ return file ? mpeg3_read_yuvframe( file, y_output, u_output, v_output, in_x, in_y, in_w, in_h, stream ) == 1 : FALSE;
+}
+
+
diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.h b/core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.h
new file mode 100644
index 0000000..0a06264
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3plugin.h
@@ -0,0 +1,113 @@
+/**********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef LIBMPEG3_PLUGIN_H
+#define LIBMPEG3_PLUGIN_H
+
+
+#include <qstring.h>
+#include <qapplication.h>
+#include "libmpeg3.h"
+#include "mpeg3protos.h"
+#include "mediaplayerplugininterface.h"
+
+
+class LibMpeg3Plugin : public MediaPlayerDecoder {
+
+public:
+ LibMpeg3Plugin() { file = NULL; }
+ ~LibMpeg3Plugin() { close(); }
+
+ const char *pluginName() { return "LibMpeg3Plugin"; }
+ const char *pluginComment() { return "This is the libmpeg3 library writen by ... which has been modified by trolltech to use fixed point maths"; }
+ double pluginVersion() { return 1.0; }
+
+ bool isFileSupported( const QString& fileName ) { return mpeg3_check_sig( (char *)fileName.latin1() ) == 1; }
+ bool open( const QString& fileName ) { file = mpeg3_open( (char *)fileName.latin1() ); return file != NULL; }
+ bool close() { if ( file ) { int r = mpeg3_close( file ); file = NULL; return r == 1; } return FALSE; }
+ bool isOpen() { return file != NULL; }
+ const QString &fileInfo() { return strInfo = QString( "" ); }
+
+ // If decoder doesn't support audio then return 0 here
+ int audioStreams() { return file ? mpeg3_total_astreams( file ) : 0; }
+ int audioChannels( int stream ) { return file ? mpeg3_audio_channels( file, stream ) : 0; }
+ int audioFrequency( int stream ) { return file ? mpeg3_sample_rate( file, stream ) : 0; }
+ int audioSamples( int stream ) { return file ? mpeg3_audio_samples( file, stream ) : 0; }
+ bool audioSetSample( long sample, int stream ) { return file ? mpeg3_set_sample( file, sample, stream) == 1 : FALSE; }
+ long audioGetSample( int stream ) { return file ? mpeg3_get_sample( file, stream ) : 0; }
+// bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream );
+// bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream );
+ bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream );
+// bool audioReadSamples( short *output, int channel, long samples, int stream );
+// bool audioReReadSamples( short *output, int channel, long samples, int stream );
+
+ // If decoder doesn't support video then return 0 here
+ int videoStreams() { return file ? mpeg3_total_vstreams( file ) : 0; }
+ int videoWidth( int stream ) { return file ? mpeg3_video_width( file, stream ) : 0; }
+ int videoHeight( int stream ) { return file ? mpeg3_video_height( file, stream ) : 0; }
+ double videoFrameRate( int stream ) { return file ? mpeg3_frame_rate( file, stream ) : 0.0; }
+ int videoFrames( int stream )
+{ return file ? mpeg3_video_frames( file, stream ) : 0; }
+/*
+{
+ if ( file ) {
+ int frames = mpeg3_video_frames( file, stream );
+ if ( frames == 1 ) {
+ int res = mpeg3_seek_percentage( file, 0.99 );
+ printf("res: %i\n", res );
+ mpeg3video_seek( file->vtrack[stream]->video );
+ frames = mpeg3_get_frame( file, stream );
+ mpeg3_seek_percentage( file, 0.0 );
+ }
+ return frames;
+ }
+ return 0;
+}
+*/
+ bool videoSetFrame( long frame, int stream ) { return file ? mpeg3_set_frame( file, frame, stream) == 1 : FALSE; }
+ long videoGetFrame( int stream ) { return file ? mpeg3_get_frame( file, stream ) : 0; }
+ bool videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream );
+ bool videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream );
+ bool videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream );
+
+ // Profiling
+ double getTime() { return file ? mpeg3_get_time( file ) : 0.0; }
+
+ // Ignore if these aren't supported
+ bool setSMP( int cpus ) { return file ? mpeg3_set_cpus( file, cpus ) == 1 : FALSE; }
+ bool setMMX( bool useMMX ) { return file ? mpeg3_set_mmx( file, useMMX ) == 1 : FALSE; }
+
+ // Capabilities
+ bool supportsAudio() { return TRUE; }
+ bool supportsVideo() { return TRUE; }
+ bool supportsYUV() { return TRUE; }
+ bool supportsMMX() { return TRUE; }
+ bool supportsSMP() { return TRUE; }
+ bool supportsStereo() { return TRUE; }
+ bool supportsScaling() { return TRUE; }
+
+private:
+ mpeg3_t *file;
+ QString strInfo;
+
+};
+
+
+#endif
+
diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.cpp b/core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.cpp
new file mode 100644
index 0000000..e7216af
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.cpp
@@ -0,0 +1,70 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "libmpeg3plugin.h"
+#include "libmpeg3pluginimpl.h"
+
+
+LibMpeg3PluginImpl::LibMpeg3PluginImpl()
+ : libmpeg3plugin(0), ref(0)
+{
+}
+
+
+LibMpeg3PluginImpl::~LibMpeg3PluginImpl()
+{
+ if ( libmpeg3plugin )
+ delete libmpeg3plugin;
+}
+
+
+MediaPlayerDecoder *LibMpeg3PluginImpl::decoder()
+{
+ if ( !libmpeg3plugin )
+ libmpeg3plugin = new LibMpeg3Plugin;
+ return libmpeg3plugin;
+}
+
+
+MediaPlayerEncoder *LibMpeg3PluginImpl::encoder()
+{
+ return NULL;
+}
+
+
+#ifndef QT_NO_COMPONENT
+
+
+QRESULT LibMpeg3PluginImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
+{
+ *iface = 0;
+ if ( ( uuid == IID_QUnknown ) || ( uuid == IID_MediaPlayerPlugin ) )
+ *iface = this, (*iface)->addRef();
+ return QS_OK;
+}
+
+
+Q_EXPORT_INTERFACE()
+{
+ Q_CREATE_INSTANCE( LibMpeg3PluginImpl )
+}
+
+
+#endif
+
diff --git a/core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.h b/core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.h
new file mode 100644
index 0000000..29ec6ba
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/libmpeg3pluginimpl.h
@@ -0,0 +1,53 @@
+/**********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef LIBMPEG3_PLUGIN_IMPL_H
+#define LIBMPEG3_PLUGIN_IMPL_H
+
+
+#include "../mediaplayerplugininterface.h"
+
+
+class LibMpeg3Plugin;
+
+
+class LibMpeg3PluginImpl : public MediaPlayerPluginInterface
+{
+public:
+ LibMpeg3PluginImpl();
+ virtual ~LibMpeg3PluginImpl();
+
+#ifndef QT_NO_COMPONENT
+
+ QRESULT queryInterface( const QUuid&, QUnknownInterface** );
+ Q_REFCOUNT
+
+#endif
+
+ virtual MediaPlayerDecoder *decoder();
+ virtual MediaPlayerEncoder *encoder();
+
+private:
+ LibMpeg3Plugin *libmpeg3plugin;
+ ulong ref;
+};
+
+
+#endif
+
diff --git a/core/multimedia/opieplayer/libmpeg3/make_package b/core/multimedia/opieplayer/libmpeg3/make_package
new file mode 100755
index 0000000..4be86da
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/make_package
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+VERSION=1.2.1
+
+rm -r /tmp/libmpeg3-$VERSION
+mkdir -p /tmp/libmpeg3-$VERSION
+make clean
+cp -rd * /tmp/libmpeg3-$VERSION
+cd /tmp
+tar zcf libmpeg3-$VERSION.tar.gz libmpeg3-$VERSION
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3atrack.c b/core/multimedia/opieplayer/libmpeg3/mpeg3atrack.c
new file mode 100644
index 0000000..e1a900b
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3atrack.c
@@ -0,0 +1,36 @@
+#include "libmpeg3.h"
+#include "mpeg3protos.h"
+
+#include <stdlib.h>
+
+mpeg3_atrack_t* mpeg3_new_atrack(mpeg3_t *file, int stream_id, int format, mpeg3_demuxer_t *demuxer)
+{
+ mpeg3_atrack_t *new_atrack;
+
+ new_atrack = (mpeg3_atrack_t*)calloc(1, sizeof(mpeg3_atrack_t));
+ new_atrack->channels = 0;
+ new_atrack->sample_rate = 0;
+ new_atrack->total_samples = 0;
+ new_atrack->current_position = 0;
+ new_atrack->demuxer = mpeg3_new_demuxer(file, 1, 0, stream_id);
+ if(demuxer) mpeg3demux_copy_titles(new_atrack->demuxer, demuxer);
+ new_atrack->audio = mpeg3audio_new(file, new_atrack, format);
+
+ if(!new_atrack->audio)
+ {
+/* Failed */
+ mpeg3_delete_atrack(file, new_atrack);
+ new_atrack = 0;
+ }
+ return new_atrack;
+}
+
+int mpeg3_delete_atrack(mpeg3_t *file, mpeg3_atrack_t *atrack)
+{
+ if(atrack->audio)
+ mpeg3audio_delete(atrack->audio);
+ if(atrack->demuxer)
+ mpeg3_delete_demuxer(atrack->demuxer);
+ free(atrack);
+}
+
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3atrack.h b/core/multimedia/opieplayer/libmpeg3/mpeg3atrack.h
new file mode 100644
index 0000000..9d70640
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3atrack.h
@@ -0,0 +1,36 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEG3ATRACK_H
+#define MPEG3ATRACK_H
+
+#include "mpeg3demux.h"
+#include "audio/mpeg3audio.h"
+
+struct mpeg3_atrack_rec
+{
+ int channels;
+ int sample_rate;
+ mpeg3_demuxer_t *demuxer;
+ mpeg3audio_t *audio;
+ long current_position;
+ long total_samples;
+};
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3cat.c b/core/multimedia/opieplayer/libmpeg3/mpeg3cat.c
new file mode 100644
index 0000000..20f7660
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3cat.c
@@ -0,0 +1,225 @@
+/* Concatenate elementary streams */
+
+#include "libmpeg3.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MPEG3_SEQUENCE_START_CODE 0x000001b3
+#define BUFFER_SIZE 1000000
+
+int main(int argc, char *argv[])
+{
+ char inpath[1024];
+ mpeg3_t *in;
+ int current_file, current_output_file = 0, i;
+ unsigned int bits;
+ unsigned char *buffer;
+ long output_size;
+ int result = 0;
+ long total_frames = 0;
+ int do_audio = 0, do_video = 0;
+ int stream = 0;
+
+ if(argc < 2)
+ {
+ fprintf(stderr, "Concatenate elementary streams or demultiplex a program stream.\n"
+ "Usage: mpeg3cat -[av0123456789] <infile> [infile...] > <outfile>\n\n"
+ "Example: Concatenate 2 video files: mpeg3cat xena1.m2v xena2.m2v > xena.m2v\n"
+ " Extract audio stream 0: mpeg3cat -a0 xena.vob > war_cry.ac3\n");
+ exit(1);
+ }
+
+ for(i = 1; i < argc; i++)
+ {
+ if(argv[i][0] == '-')
+ {
+ if(argv[i][1] != 'a' && argv[i][1] != 'v')
+ {
+ fprintf(stderr, "invalid option %s\n", argv[i]);
+ }
+ else
+ {
+ if(argv[i][1] == 'a') do_audio = 1;
+ else
+ if(argv[i][1] == 'v') do_video = 1;
+
+ if(argv[i][2] != 0)
+ {
+ stream = argv[i][2] - 48;
+ }
+ }
+ }
+ }
+
+ buffer = (unsigned char*)malloc(BUFFER_SIZE);
+
+ for(current_file = 1; current_file < argc; current_file++)
+ {
+ if(argv[current_file][0] == '-') continue;
+
+ strcpy(inpath, argv[current_file]);
+ if(!(in = mpeg3_open(inpath)))
+ {
+ fprintf(stderr, "Skipping %s\n", inpath);
+ continue;
+ }
+
+ if((mpeg3_has_audio(in) && in->is_audio_stream) ||
+ (do_audio && !in->is_audio_stream && !in->is_video_stream))
+ {
+ do_audio = 1;
+/* Add audio stream to end */
+ while(!mpeg3_read_audio_chunk(in, buffer,
+ &output_size,
+ BUFFER_SIZE,
+ stream))
+ {
+ result = !fwrite(buffer, output_size, 1, stdout);
+ if(result)
+ {
+ perror("fwrite audio chunk");
+ break;
+ }
+ }
+ }
+ else
+ if((mpeg3_has_video(in) && in->is_video_stream) ||
+ (do_video && !in->is_video_stream && !in->is_audio_stream))
+ {
+/* Add video stream to end */
+ int hour, minute, second, frame;
+ long gop_frame;
+ unsigned long code;
+ float carry;
+ int i, offset;
+
+ do_video = 1;
+ while(!mpeg3_read_video_chunk(in,
+ buffer,
+ &output_size,
+ BUFFER_SIZE,
+ stream) &&
+ output_size >= 4)
+ {
+ code = (unsigned long)buffer[output_size - 4] << 24;
+ code |= (unsigned long)buffer[output_size - 3] << 16;
+ code |= (unsigned long)buffer[output_size - 2] << 8;
+ code |= (unsigned long)buffer[output_size - 1];
+
+/* Got a frame at the end of this buffer. */
+ if(code == MPEG3_PICTURE_START_CODE)
+ {
+ total_frames++;
+ }
+ else
+ if(code == MPEG3_SEQUENCE_END_CODE)
+ {
+/* Got a sequence end code at the end of this buffer. */
+ output_size -= 4;
+ }
+
+ code = (unsigned long)buffer[0] << 24;
+ code |= (unsigned long)buffer[1] << 16;
+ code |= (unsigned long)buffer[2] << 8;
+ code |= buffer[3];
+
+ i = 0;
+ offset = 0;
+ if(code == MPEG3_SEQUENCE_START_CODE && current_output_file > 0)
+ {
+/* Skip the sequence start code */
+ i += 4;
+ while(i < output_size &&
+ code != MPEG3_GOP_START_CODE)
+ {
+ code <<= 8;
+ code |= buffer[i++];
+ }
+ i -= 4;
+ offset = i;
+ }
+
+/* Search for GOP header to fix */
+ code = (unsigned long)buffer[i++] << 24;
+ code |= (unsigned long)buffer[i++] << 16;
+ code |= (unsigned long)buffer[i++] << 8;
+ code |= buffer[i++];
+ while(i < output_size &&
+ code != MPEG3_GOP_START_CODE)
+ {
+ code <<= 8;
+ code |= buffer[i++];
+ }
+
+ if(code == MPEG3_GOP_START_CODE)
+ {
+/* Get the time code */
+ code = (unsigned long)buffer[i] << 24;
+ code |= (unsigned long)buffer[i + 1] << 16;
+ code |= (unsigned long)buffer[i + 2] << 8;
+ code |= (unsigned long)buffer[i + 3];
+
+ hour = code >> 26 & 0x1f;
+ minute = code >> 20 & 0x3f;
+ second = code >> 13 & 0x3f;
+ frame = code >> 7 & 0x3f;
+
+ gop_frame = (long)(hour * 3600 * mpeg3_frame_rate(in, stream) +
+ minute * 60 * mpeg3_frame_rate(in, stream) +
+ second * mpeg3_frame_rate(in, stream) +
+ frame);
+/* fprintf(stderr, "old: %02d:%02d:%02d:%02d ", hour, minute, second, frame); */
+/* Write a new time code */
+ hour = (long)((float)(total_frames - 1) / mpeg3_frame_rate(in, stream) / 3600);
+ carry = hour * 3600 * mpeg3_frame_rate(in, stream);
+ minute = (long)((float)(total_frames - 1 - carry) / mpeg3_frame_rate(in, stream) / 60);
+ carry += minute * 60 * mpeg3_frame_rate(in, stream);
+ second = (long)((float)(total_frames - 1 - carry) / mpeg3_frame_rate(in, stream));
+ carry += second * mpeg3_frame_rate(in, stream);
+ frame = (int)(total_frames - 1 - carry);
+
+ buffer[i] = ((code >> 24) & 0x80) | (hour << 2) | (minute >> 4);
+ buffer[i + 1] = ((code >> 16) & 0x08) | ((minute & 0xf) << 4) | (second >> 3);
+ buffer[i + 2] = ((second & 0x7) << 5) | (frame >> 1);
+ buffer[i + 3] = (code & 0x7f) | ((frame & 0x1) << 7);
+/* fprintf(stderr, "new: %02d:%02d:%02d:%02d\n", hour, minute, second, frame); */
+ }
+
+/* Write the frame */
+ result = !fwrite(buffer + offset, output_size - offset, 1, stdout);
+ if(result)
+ {
+ perror("fwrite video chunk");
+ break;
+ }
+ }
+ }
+ else
+ {
+ fprintf(stderr, "Unsupported stream type.\n");
+ mpeg3_close(in);
+ in = 0;
+ continue;
+ }
+
+ mpeg3_close(in);
+ in = 0;
+ current_output_file++;
+ }
+
+/* Terminate output */
+ if(current_output_file > 0 && do_video)
+ {
+/*fprintf(stderr, "\n"); */
+/* Write new end of sequence */
+ buffer[0] = MPEG3_SEQUENCE_END_CODE >> 24;
+ buffer[1] = (MPEG3_SEQUENCE_END_CODE >> 16) & 0xff;
+ buffer[2] = (MPEG3_SEQUENCE_END_CODE >> 8) & 0xff;
+ buffer[3] = MPEG3_SEQUENCE_END_CODE & 0xff;
+ result = !fwrite(buffer, 4, 1, stdout);
+ }
+
+ exit(0);
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3css.c b/core/multimedia/opieplayer/libmpeg3/mpeg3css.c
new file mode 100644
index 0000000..7f9ad8c
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3css.c
@@ -0,0 +1,32 @@
+#include "mpeg3css.h"
+#include "mpeg3private.h"
+
+extern "C" {
+
+int mpeg3_init_css(mpeg3_t *file, mpeg3_css_t *css)
+{
+ return 0;
+}
+
+int mpeg3_get_keys(mpeg3_css_t *css, char *path)
+{
+ return 1;
+}
+
+int mpeg3_decrypt_packet(mpeg3_css_t *css, unsigned char *sector)
+{
+ return 1;
+}
+
+mpeg3_css_t* mpeg3_new_css()
+{
+ return 0;
+}
+
+int mpeg3_delete_css(mpeg3_css_t *css)
+{
+ return 0;
+}
+
+};
+
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3css.h b/core/multimedia/opieplayer/libmpeg3/mpeg3css.h
new file mode 100644
index 0000000..1272574
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3css.h
@@ -0,0 +1,29 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEG3CSS_H
+#define MPEG3CSS_H
+
+/* Stubs for deCSS which can't be distributed legally */
+
+typedef struct
+{
+} mpeg3_css_t;
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.c b/core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.c
new file mode 100644
index 0000000..0901195
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.c
@@ -0,0 +1,19 @@
+/* Stubs for deCSS which can't be distributed in source form */
+
+#include "mpeg3css.h"
+#include "mpeg3private.h"
+
+int mpeg3_init_css(mpeg3_t *file, mpeg3_css_t *css)
+{
+ return 0;
+}
+
+int mpeg3_get_keys(mpeg3_css_t *css, char *path)
+{
+ return 1;
+}
+
+int mpeg3_decrypt_packet(mpeg3_css_t *css, unsigned char *sector)
+{
+ return 1;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.h b/core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.h
new file mode 100644
index 0000000..1272574
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3css_fake.h
@@ -0,0 +1,29 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEG3CSS_H
+#define MPEG3CSS_H
+
+/* Stubs for deCSS which can't be distributed legally */
+
+typedef struct
+{
+} mpeg3_css_t;
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3demux.c b/core/multimedia/opieplayer/libmpeg3/mpeg3demux.c
new file mode 100644
index 0000000..cccc820
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3demux.c
@@ -0,0 +1,1849 @@
+#include "libmpeg3.h"
+#include "mpeg3io.h"
+#include "mpeg3protos.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ABS(x) ((x) >= 0 ? (x) : -(x))
+
+/* Don't advance pointer */
+static inline unsigned char mpeg3packet_next_char(mpeg3_demuxer_t *demuxer)
+{
+ return demuxer->raw_data[demuxer->raw_offset];
+}
+
+unsigned char mpeg3packet_read_char(mpeg3_demuxer_t *demuxer)
+{
+ unsigned char result = demuxer->raw_data[demuxer->raw_offset++];
+ return result;
+}
+
+static inline unsigned int mpeg3packet_read_int16(mpeg3_demuxer_t *demuxer)
+{
+ unsigned int a, b, result;
+ a = demuxer->raw_data[demuxer->raw_offset++];
+ b = demuxer->raw_data[demuxer->raw_offset++];
+ result = (a << 8) | b;
+
+ return result;
+}
+
+static inline unsigned int mpeg3packet_next_int24(mpeg3_demuxer_t *demuxer)
+{
+ unsigned int a, b, c, result;
+ a = demuxer->raw_data[demuxer->raw_offset];
+ b = demuxer->raw_data[demuxer->raw_offset + 1];
+ c = demuxer->raw_data[demuxer->raw_offset + 2];
+ result = (a << 16) | (b << 8) | c;
+
+ return result;
+}
+
+static inline unsigned int mpeg3packet_read_int24(mpeg3_demuxer_t *demuxer)
+{
+ unsigned int a, b, c, result;
+ a = demuxer->raw_data[demuxer->raw_offset++];
+ b = demuxer->raw_data[demuxer->raw_offset++];
+ c = demuxer->raw_data[demuxer->raw_offset++];
+ result = (a << 16) | (b << 8) | c;
+
+ return result;
+}
+
+static inline unsigned int mpeg3packet_read_int32(mpeg3_demuxer_t *demuxer)
+{
+ unsigned int a, b, c, d, result;
+ a = demuxer->raw_data[demuxer->raw_offset++];
+ b = demuxer->raw_data[demuxer->raw_offset++];
+ c = demuxer->raw_data[demuxer->raw_offset++];
+ d = demuxer->raw_data[demuxer->raw_offset++];
+ result = (a << 24) | (b << 16) | (c << 8) | d;
+
+ return result;
+}
+
+static inline unsigned int mpeg3packet_skip(mpeg3_demuxer_t *demuxer, long length)
+{
+ demuxer->raw_offset += length;
+ return 0;
+}
+
+int mpeg3_get_adaptation_field(mpeg3_demuxer_t *demuxer)
+{
+ long length;
+ int pcr_flag;
+
+ demuxer->adaptation_fields++;
+/* get adaptation field length */
+ length = mpeg3packet_read_char(demuxer);
+/* get first byte */
+ pcr_flag = (mpeg3packet_read_char(demuxer) >> 4) & 1;
+
+ if(pcr_flag)
+ {
+ unsigned long clk_ref_base = mpeg3packet_read_int32(demuxer);
+ unsigned int clk_ref_ext = mpeg3packet_read_int16(demuxer);
+
+ if (clk_ref_base > 0x7fffffff)
+ { /* correct for invalid numbers */
+ clk_ref_base = 0; /* ie. longer than 32 bits when multiplied by 2 */
+ clk_ref_ext = 0; /* multiplied by 2 corresponds to shift left 1 (<<=1) */
+ }
+ else
+ {
+ clk_ref_base <<= 1; /* Create space for bit */
+ clk_ref_base |= (clk_ref_ext >> 15); /* Take bit */
+ clk_ref_ext &= 0x01ff; /* Only lower 9 bits */
+ }
+ demuxer->time = clk_ref_base + clk_ref_ext / 300;
+ if(length) mpeg3packet_skip(demuxer, length - 7);
+ }
+ else
+ mpeg3packet_skip(demuxer, length - 1);
+
+ return 0;
+}
+
+int mpeg3_get_program_association_table(mpeg3_demuxer_t *demuxer)
+{
+ demuxer->program_association_tables++;
+ demuxer->table_id = mpeg3packet_read_char(demuxer);
+ demuxer->section_length = mpeg3packet_read_int16(demuxer) & 0xfff;
+ demuxer->transport_stream_id = mpeg3packet_read_int16(demuxer);
+ mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
+ return 0;
+}
+
+int mpeg3packet_get_data_buffer(mpeg3_demuxer_t *demuxer)
+{
+ while(demuxer->raw_offset < demuxer->raw_size && demuxer->data_size < demuxer->data_allocated)
+ {
+ demuxer->data_buffer[demuxer->data_size++] = demuxer->raw_data[demuxer->raw_offset++];
+ }
+ return 0;
+}
+
+int mpeg3_get_pes_packet_header(mpeg3_demuxer_t *demuxer, unsigned long *pts, unsigned long *dts)
+{
+ unsigned int pes_header_bytes = 0;
+ unsigned int pts_dts_flags;
+ int pes_header_data_length;
+
+/* drop first 8 bits */
+ mpeg3packet_read_char(demuxer);
+ pts_dts_flags = (mpeg3packet_read_char(demuxer) >> 6) & 0x3;
+ pes_header_data_length = mpeg3packet_read_char(demuxer);
+
+/* Get Presentation Time stamps and Decoding Time Stamps */
+ if(pts_dts_flags == 2)
+ {
+ *pts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */
+ *pts <<= 15;
+ *pts |= (mpeg3packet_read_int16(demuxer) >> 1);
+ *pts <<= 15;
+ *pts |= (mpeg3packet_read_int16(demuxer) >> 1);
+ pes_header_bytes += 5;
+ }
+ else if(pts_dts_flags == 3)
+ {
+ *pts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */
+ *pts <<= 15;
+ *pts |= (mpeg3packet_read_int16(demuxer) >> 1);
+ *pts <<= 15;
+ *pts |= (mpeg3packet_read_int16(demuxer) >> 1);
+ *dts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */
+ *dts <<= 15;
+ *dts |= (mpeg3packet_read_int16(demuxer) >> 1);
+ *dts <<= 15;
+ *dts |= (mpeg3packet_read_int16(demuxer) >> 1);
+ pes_header_bytes += 10;
+ }
+/* extract other stuff here! */
+
+ mpeg3packet_skip(demuxer, pes_header_data_length - pes_header_bytes);
+ return 0;
+}
+
+int get_unknown_data(mpeg3_demuxer_t *demuxer)
+{
+ mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
+ return 0;
+}
+
+int mpeg3_get_pes_packet_data(mpeg3_demuxer_t *demuxer, unsigned int stream_id)
+{
+ unsigned long pts = 0, dts = 0;
+
+ if((stream_id >> 4) == 12 || (stream_id >> 4) == 13)
+ {
+/* Just pick the first available stream if no ID is set */
+ if(demuxer->astream == -1)
+ demuxer->astream = (stream_id & 0x0f);
+
+ if((stream_id & 0x0f) == demuxer->astream && demuxer->do_audio)
+ {
+ mpeg3_get_pes_packet_header(demuxer, &pts, &dts);
+ demuxer->pes_audio_time = pts;
+ demuxer->audio_pid = demuxer->pid;
+ return mpeg3packet_get_data_buffer(demuxer);
+ }
+ }
+ else
+ if((stream_id >> 4)==14)
+ {
+/* Just pick the first available stream if no ID is set */
+ if(demuxer->vstream == -1)
+ demuxer->vstream = (stream_id & 0x0f);
+
+ if((stream_id & 0x0f) == demuxer->vstream && demuxer->do_video)
+ {
+ mpeg3_get_pes_packet_header(demuxer, &pts, &dts);
+ demuxer->pes_video_time = pts;
+ demuxer->video_pid = demuxer->pid;
+ return mpeg3packet_get_data_buffer(demuxer);
+ }
+ }
+ else
+ {
+ return get_unknown_data(demuxer);
+ }
+
+ mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
+
+ return 0;
+}
+
+int mpeg3_get_pes_packet(mpeg3_demuxer_t *demuxer)
+{
+ unsigned int stream_id;
+
+ demuxer->pes_packets++;
+ stream_id = mpeg3packet_read_char(demuxer);
+/* Skip startcode */
+ mpeg3packet_read_int24(demuxer);
+/* Skip pes packet length */
+ mpeg3packet_read_int16(demuxer);
+
+ if(stream_id != MPEG3_PRIVATE_STREAM_2 && stream_id != MPEG3_PADDING_STREAM)
+ {
+ return mpeg3_get_pes_packet_data(demuxer, stream_id);
+ }
+ else
+ if(stream_id == MPEG3_PRIVATE_STREAM_2)
+ {
+/* Dump private data! */
+ fprintf(stderr, "stream_id == MPEG3_PRIVATE_STREAM_2\n");
+ mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
+ return 0;
+ }
+ else
+ if(stream_id == MPEG3_PADDING_STREAM)
+ {
+ mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
+ return 0;
+ }
+ else
+ {
+ fprintf(stderr, "unknown stream_id in pes packet");
+ return 1;
+ }
+ return 0;
+}
+
+int mpeg3_get_payload(mpeg3_demuxer_t *demuxer)
+{
+ if(demuxer->payload_unit_start_indicator)
+ {
+ if(demuxer->pid==0) mpeg3_get_program_association_table(demuxer);
+ else
+ if(mpeg3packet_next_int24(demuxer) == MPEG3_PACKET_START_CODE_PREFIX) mpeg3_get_pes_packet(demuxer);
+ else
+ mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
+ }
+ else
+ {
+ if(demuxer->pid == demuxer->audio_pid && demuxer->do_audio)
+ {
+ mpeg3packet_get_data_buffer(demuxer);
+ }
+ else
+ if(demuxer->pid == demuxer->video_pid && demuxer->do_video)
+ {
+ mpeg3packet_get_data_buffer(demuxer);
+ }
+ else
+ mpeg3packet_skip(demuxer, demuxer->raw_size - demuxer->raw_offset);
+ }
+ return 0;
+}
+
+/* Read a transport packet */
+int mpeg3_read_transport(mpeg3_demuxer_t *demuxer)
+{
+ mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
+ int result = mpeg3io_read_data(demuxer->raw_data, demuxer->packet_size, title->fs);
+ unsigned int bits;
+ int table_entry;
+
+ demuxer->raw_size = demuxer->packet_size;
+ demuxer->raw_offset = 0;
+ if(result)
+ {
+ perror("mpeg3_read_transport");
+ return 1;
+ }
+
+/* Sync byte */
+ if(mpeg3packet_read_char(demuxer) != MPEG3_SYNC_BYTE)
+ {
+ fprintf(stderr, "mpeg3packet_read_char(demuxer) != MPEG3_SYNC_BYTE\n");
+ return 1;
+ }
+
+/* bits = mpeg3packet_read_int24(demuxer) & 0x0000ffff; */
+/* demuxer->transport_error_indicator = bits >> 15; */
+/* demuxer->payload_unit_start_indicator = (bits >> 14) & 1; */
+/* demuxer->pid = bits & 0x00001fff; */
+/* demuxer->transport_scrambling_control = (mpeg3packet_next_char(demuxer) >> 6) & 0x3; */
+/* demuxer->adaptation_field_control = (mpeg3packet_next_char(demuxer) >> 4) & 0x3; */
+/* demuxer->continuity_counter = (mpeg3packet_read_char(demuxer) & 0xf); */
+
+ bits = mpeg3packet_read_int24(demuxer) & 0x00ffffff;
+ demuxer->transport_error_indicator = (bits >> 23) & 0x1;
+ demuxer->payload_unit_start_indicator = (bits >> 22) & 0x1;
+ demuxer->pid = (bits >> 8) & 0x00001fff;
+ demuxer->transport_scrambling_control = (bits >> 6) & 0x3;
+ demuxer->adaptation_field_control = (bits >> 4) & 0x3;
+ demuxer->continuity_counter = bits & 0xf;
+
+ if(demuxer->transport_error_indicator)
+ {
+ fprintf(stderr, "demuxer->transport_error_indicator\n");
+ return 1;
+ }
+
+ if (demuxer->pid == 0x1fff)
+ {
+ demuxer->is_padding = 1; /* padding; just go to next */
+ return 0;
+ }
+ else
+ {
+ demuxer->is_padding = 0;
+ }
+
+/* Get pid */
+ for(table_entry = 0, result = 0; table_entry < demuxer->total_pids; table_entry++)
+ {
+ if(demuxer->pid == demuxer->pid_table[table_entry])
+ {
+ result = 1;
+ break;
+ }
+ }
+
+/* Not in pid table */
+ if(!result)
+ {
+ demuxer->pid_table[table_entry] = demuxer->pid;
+ demuxer->continuity_counters[table_entry] = demuxer->continuity_counter; /* init */
+ demuxer->total_pids++;
+ }
+ result = 0;
+
+/* Check counters */
+ if(demuxer->pid != MPEG3_PROGRAM_ASSOCIATION_TABLE &&
+ demuxer->pid != MPEG3_CONDITIONAL_ACCESS_TABLE &&
+ (demuxer->adaptation_field_control == 1 || demuxer->adaptation_field_control == 3))
+ {
+ if(demuxer->continuity_counters[table_entry] != demuxer->continuity_counter)
+ {
+ fprintf(stderr, "demuxer->continuity_counters[table_entry] != demuxer->continuity_counter\n");
+/* Reset it */
+ demuxer->continuity_counters[table_entry] = demuxer->continuity_counter;
+ }
+ if(++(demuxer->continuity_counters[table_entry]) > 15) demuxer->continuity_counters[table_entry] = 0;
+ }
+
+ if(demuxer->adaptation_field_control == 2 || demuxer->adaptation_field_control == 3)
+ result = mpeg3_get_adaptation_field(demuxer);
+
+ if(demuxer->adaptation_field_control == 1 || demuxer->adaptation_field_control == 3)
+ result = mpeg3_get_payload(demuxer);
+
+ return result;
+}
+
+int mpeg3_get_system_header(mpeg3_demuxer_t *demuxer)
+{
+ int length = mpeg3packet_read_int16(demuxer);
+ mpeg3packet_skip(demuxer, length);
+ return 0;
+}
+
+unsigned long mpeg3_get_timestamp(mpeg3_demuxer_t *demuxer)
+{
+ unsigned long timestamp;
+/* Only low 4 bits (7==1111) */
+ timestamp = (mpeg3packet_read_char(demuxer) >> 1) & 7;
+ timestamp <<= 15;
+ timestamp |= (mpeg3packet_read_int16(demuxer) >> 1);
+ timestamp <<= 15;
+ timestamp |= (mpeg3packet_read_int16(demuxer) >> 1);
+ return timestamp;
+}
+
+int mpeg3_get_pack_header(mpeg3_demuxer_t *demuxer, unsigned int *header)
+{
+ unsigned long i, j;
+ unsigned long clock_ref, clock_ref_ext;
+
+/* Get the time code */
+ if((mpeg3packet_next_char(demuxer) >> 4) == 2)
+ {
+/* MPEG-1 */
+ demuxer->time = (double)mpeg3_get_timestamp(demuxer) / 90000;
+/* Skip 3 bytes */
+ mpeg3packet_read_int24(demuxer);
+ }
+ else
+ if(mpeg3packet_next_char(demuxer) & 0x40)
+ {
+ i = mpeg3packet_read_int32(demuxer);
+ j = mpeg3packet_read_int16(demuxer);
+ if(i & 0x40000000 || (i >> 28) == 2)
+ {
+ clock_ref = ((i & 0x31000000) << 3);
+ clock_ref |= ((i & 0x03fff800) << 4);
+ clock_ref |= ((i & 0x000003ff) << 5);
+ clock_ref |= ((j & 0xf800) >> 11);
+ clock_ref_ext = (j >> 1) & 0x1ff;
+
+ demuxer->time = (double)(clock_ref + clock_ref_ext / 300) / 90000;
+/* Skip 3 bytes */
+ mpeg3packet_read_int24(demuxer);
+ i = mpeg3packet_read_char(demuxer) & 0x7;
+
+/* stuffing */
+ mpeg3packet_skip(demuxer, i);
+ }
+ }
+ else
+ {
+ mpeg3packet_skip(demuxer, 2);
+ }
+
+ *header = mpeg3packet_read_int32(demuxer);
+ if(*header == MPEG3_SYSTEM_START_CODE)
+ {
+ mpeg3_get_system_header(demuxer);
+ *header = mpeg3packet_read_int32(demuxer);
+ }
+ return 0;
+}
+
+/* Program packet reading core */
+int mpeg3_get_ps_pes_packet(mpeg3_demuxer_t *demuxer, unsigned int *header)
+{
+ unsigned long pts = 0, dts = 0;
+ int stream_id;
+ int pes_packet_length;
+ int pes_packet_start;
+ int i;
+ mpeg3_t *file = demuxer->file;
+
+ stream_id = *header & 0xff;
+ pes_packet_length = mpeg3packet_read_int16(demuxer);
+ pes_packet_start = demuxer->raw_offset;
+
+ if(stream_id != MPEG3_PRIVATE_STREAM_2 &&
+ stream_id != MPEG3_PADDING_STREAM)
+ {
+ if((mpeg3packet_next_char(demuxer) >> 6) == 0x02)
+ {
+/* Get MPEG-2 packet */
+ int pes_header_bytes = 0;
+ int scrambling = (mpeg3packet_read_char(demuxer) >> 4) & 0x3;
+ int pts_dts_flags = (mpeg3packet_read_char(demuxer) >> 6) & 0x3;
+ int pes_header_data_length = mpeg3packet_read_char(demuxer);
+
+ if(scrambling && (demuxer->do_audio || demuxer->do_video))
+ {
+/* Decrypt it */
+ if(mpeg3_decrypt_packet(demuxer->titles[demuxer->current_title]->fs->css,
+ demuxer->raw_data))
+ {
+ fprintf(stderr, "mpeg3_get_ps_pes_packet: Decryption not available\n");
+ return 1;
+ }
+ }
+
+/* Get Presentation and Decoding Time Stamps */
+ if(pts_dts_flags == 2)
+ {
+ pts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */
+ pts <<= 15;
+ pts |= (mpeg3packet_read_int16(demuxer) >> 1);
+ pts <<= 15;
+ pts |= (mpeg3packet_read_int16(demuxer) >> 1);
+ pes_header_bytes += 5;
+ }
+ else
+ if(pts_dts_flags == 3)
+ {
+ pts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */
+ pts <<= 15;
+ pts |= (mpeg3packet_read_int16(demuxer) >> 1);
+ pts <<= 15;
+ pts |= (mpeg3packet_read_int16(demuxer) >> 1);
+ dts = (mpeg3packet_read_char(demuxer) >> 1) & 7; /* Only low 4 bits (7==1111) */
+ dts <<= 15;
+ dts |= (mpeg3packet_read_int16(demuxer) >> 1);
+ dts <<= 15;
+ dts |= (mpeg3packet_read_int16(demuxer) >> 1);
+ pes_header_bytes += 10;
+ }
+
+/* Skip unknown */
+ mpeg3packet_skip(demuxer, pes_header_data_length - pes_header_bytes);
+ }
+ else
+ {
+ int pts_dts_flags;
+/* Get MPEG-1 packet */
+ while(mpeg3packet_next_char(demuxer) == 0xff)
+ {
+ mpeg3packet_read_char(demuxer);
+ }
+
+/* Skip STD buffer scale */
+ if((mpeg3packet_next_char(demuxer) & 0x40) == 0x40)
+ {
+ mpeg3packet_skip(demuxer, 2);
+ }
+
+/* Decide which timestamps are available */
+ pts_dts_flags = mpeg3packet_next_char(demuxer);
+
+ if(pts_dts_flags >= 0x30)
+ {
+/* Get the presentation and decoding time stamp */
+ pts = mpeg3_get_timestamp(demuxer);
+ dts = mpeg3_get_timestamp(demuxer);
+ }
+ else
+ if(pts_dts_flags >= 0x20)
+ {
+/* Get just the presentation time stamp */
+ pts = mpeg3_get_timestamp(demuxer);
+ }
+ else
+ if(pts_dts_flags == 0x0f)
+ {
+/* End of timestamps */
+ mpeg3packet_read_char(demuxer);
+ }
+ else
+ {
+ return 1; /* Error */
+ }
+ }
+
+/* Now extract the payload. */
+ if((stream_id >> 4) == 0xc || (stream_id >> 4) == 0xd)
+ {
+/* Audio data */
+/* Take first stream ID if -1 */
+ pes_packet_length -= demuxer->raw_offset - pes_packet_start;
+ if(!demuxer->do_audio && !demuxer->do_video)
+ demuxer->astream_table[stream_id & 0x0f] = AUDIO_MPEG;
+ else
+ if(demuxer->astream == -1)
+ demuxer->astream = stream_id & 0x0f;
+
+ if((stream_id & 0x0f) == demuxer->astream && demuxer->do_audio)
+ {
+ if(pts) demuxer->pes_audio_time = pts;
+
+ memcpy(&demuxer->data_buffer[demuxer->data_size],
+ &demuxer->raw_data[demuxer->raw_offset],
+ pes_packet_length);
+ demuxer->data_size += pes_packet_length;
+ demuxer->raw_offset += pes_packet_length;
+ }
+ else
+ {
+ mpeg3packet_skip(demuxer, pes_packet_length);
+ }
+ }
+ else
+ if((stream_id >> 4) == 0xe)
+ {
+/* Video data */
+/* Take first stream ID if -1 */
+ if(!demuxer->do_audio && !demuxer->do_video)
+ demuxer->vstream_table[stream_id & 0x0f] = 1;
+ else
+ if(demuxer->vstream == -1)
+ demuxer->vstream = stream_id & 0x0f;
+
+ pes_packet_length -= demuxer->raw_offset - pes_packet_start;
+ if((stream_id & 0x0f) == demuxer->vstream && demuxer->do_video)
+ {
+ if(pts) demuxer->pes_video_time = pts;
+
+ memcpy(&demuxer->data_buffer[demuxer->data_size],
+ &demuxer->raw_data[demuxer->raw_offset],
+ pes_packet_length);
+ demuxer->data_size += pes_packet_length;
+ demuxer->raw_offset += pes_packet_length;
+ }
+ else
+ {
+ mpeg3packet_skip(demuxer, pes_packet_length);
+ }
+ }
+ else
+ if(stream_id == 0xbd && demuxer->raw_data[demuxer->raw_offset] != 0xff)
+ {
+/* DVD audio data */
+/* Get the audio format */
+ int format;
+ if((demuxer->raw_data[demuxer->raw_offset] & 0xf0) == 0xa0)
+ format = AUDIO_PCM;
+ else
+ format = AUDIO_AC3;
+
+ stream_id = demuxer->raw_data[demuxer->raw_offset] - 0x80;
+
+/* Take first stream ID if not building TOC. */
+ if(!demuxer->do_audio && !demuxer->do_video)
+ demuxer->astream_table[stream_id] = format;
+ else
+ if(demuxer->astream == -1)
+ demuxer->astream = stream_id;
+
+ if(stream_id == demuxer->astream && demuxer->do_audio)
+ {
+ demuxer->aformat = format;
+ if(pts) demuxer->pes_audio_time = pts;
+ mpeg3packet_read_int32(demuxer);
+ pes_packet_length -= demuxer->raw_offset - pes_packet_start;
+
+ memcpy(&demuxer->data_buffer[demuxer->data_size],
+ &demuxer->raw_data[demuxer->raw_offset],
+ pes_packet_length);
+ demuxer->data_size += pes_packet_length;
+ demuxer->raw_offset += pes_packet_length;
+ }
+ else
+ {
+ pes_packet_length -= demuxer->raw_offset - pes_packet_start;
+ mpeg3packet_skip(demuxer, pes_packet_length);
+ }
+ }
+ else
+ if(stream_id == 0xbc || 1)
+ {
+ pes_packet_length -= demuxer->raw_offset - pes_packet_start;
+ mpeg3packet_skip(demuxer, pes_packet_length);
+ }
+ }
+ else
+ if(stream_id == MPEG3_PRIVATE_STREAM_2 || stream_id == MPEG3_PADDING_STREAM)
+ {
+ pes_packet_length -= demuxer->raw_offset - pes_packet_start;
+ mpeg3packet_skip(demuxer, pes_packet_length);
+ }
+
+ while(demuxer->raw_offset + 4 < demuxer->raw_size)
+ {
+ *header = mpeg3packet_read_int32(demuxer);
+ if((*header >> 8) != MPEG3_PACKET_START_CODE_PREFIX)
+ demuxer->raw_offset -= 3;
+ else
+ break;
+ }
+
+ return 0;
+}
+
+int mpeg3_read_program(mpeg3_demuxer_t *demuxer)
+{
+ int result = 0, count = 0;
+ mpeg3_t *file = demuxer->file;
+ mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
+ unsigned int header;
+ demuxer->raw_size = demuxer->packet_size;
+ demuxer->raw_offset = 0;
+ demuxer->data_size = 0;
+
+/* Search backward for it. */
+ header = mpeg3io_read_int32(title->fs);
+ result = mpeg3io_eof(title->fs);
+
+ if(!result) result = mpeg3io_seek_relative(title->fs, -4);
+
+// Search backwards for header
+ while(header != MPEG3_PACK_START_CODE && !result && count < demuxer->packet_size)
+ {
+ result = mpeg3io_seek_relative(title->fs, -1);
+ if(!result)
+ {
+ header >>= 8;
+ header |= mpeg3io_read_char(title->fs) << 24;
+ result = mpeg3io_seek_relative(title->fs, -1);
+ }
+ count++;
+ }
+
+ if(result)
+ {
+// couldn't find MPEG3_PACK_START_CODE
+ return 1;
+ }
+
+ result = mpeg3io_read_data(demuxer->raw_data, demuxer->packet_size, title->fs);
+
+ if(result)
+ {
+ perror("mpeg3_read_program");
+ return 1;
+ }
+
+ header = mpeg3packet_read_int32(demuxer);
+ while(demuxer->raw_offset + 4 < demuxer->raw_size && !result)
+ {
+ if(header == MPEG3_PACK_START_CODE)
+ {
+ result = mpeg3_get_pack_header(demuxer, &header);
+ }
+ else
+ if((header >> 8) == MPEG3_PACKET_START_CODE_PREFIX)
+ {
+ result = mpeg3_get_ps_pes_packet(demuxer, &header);
+ }
+ }
+ return result;
+}
+
+double mpeg3_lookup_time_offset(mpeg3_demuxer_t *demuxer, long byte)
+{
+ int i;
+ mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
+
+ if(!title->timecode_table_size) return 0;
+
+ for(i = title->timecode_table_size - 1;
+ i >= 0 && title->timecode_table[i].start_byte > byte;
+ i--)
+ ;
+ if(i < 0) i = 0;
+ return title->timecode_table[i].absolute_start_time - title->timecode_table[i].start_time;
+}
+
+int mpeg3_advance_timecode(mpeg3_demuxer_t *demuxer, int reverse)
+{
+ mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
+ int result = 0;
+ int do_seek = 0;
+
+/* Skip timecode advancing when constructing timecode table */
+ if(!title->timecode_table ||
+ !title->timecode_table_size ||
+ demuxer->generating_timecode) return 0;
+
+ if(!reverse)
+ {
+/* Get inside the current timecode */
+ if(mpeg3io_tell(title->fs) < title->timecode_table[demuxer->current_timecode].start_byte)
+ {
+ mpeg3io_seek(title->fs, title->timecode_table[demuxer->current_timecode].start_byte);
+ }
+
+/* Get the next timecode */
+ while(!result &&
+ (mpeg3io_tell(title->fs) >= title->timecode_table[demuxer->current_timecode].end_byte ||
+ demuxer->current_program != title->timecode_table[demuxer->current_timecode].program))
+ {
+
+/*
+ * printf("mpeg3_advance_timecode %d %d %d %d\n", mpeg3io_tell(title->fs), title->timecode_table[demuxer->current_timecode].end_byte,
+ * demuxer->current_program, title->timecode_table[demuxer->current_timecode].program);
+ */
+
+ demuxer->current_timecode++;
+ if(demuxer->current_timecode >= title->timecode_table_size)
+ {
+ demuxer->current_timecode = 0;
+ if(demuxer->current_title + 1 < demuxer->total_titles)
+ {
+ mpeg3demux_open_title(demuxer, demuxer->current_title + 1);
+ do_seek = 1;
+ }
+ else
+ {
+ mpeg3io_seek(title->fs, mpeg3io_total_bytes(title->fs));
+ result = 1;
+ }
+ }
+ title = demuxer->titles[demuxer->current_title];
+ }
+
+ if(!result && do_seek)
+ {
+ mpeg3io_seek(title->fs, title->timecode_table[demuxer->current_timecode].start_byte);
+ }
+ }
+ else
+ {
+/* Get the previous timecode */
+ while(!result &&
+ (mpeg3io_tell(title->fs) < title->timecode_table[demuxer->current_timecode].start_byte ||
+ demuxer->current_program != title->timecode_table[demuxer->current_timecode].program))
+ {
+/*
+ * if(demuxer->do_audio) printf("mpeg3_reverse_timecode %d %d %d %d\n", mpeg3io_tell(title->fs), title->timecode_table[demuxer->current_timecode].end_byte,
+ * demuxer->current_program, title->timecode_table[demuxer->current_timecode].program);
+ */
+ demuxer->current_timecode--;
+ if(demuxer->current_timecode < 0)
+ {
+ if(demuxer->current_title > 0)
+ {
+ mpeg3demux_open_title(demuxer, demuxer->current_title - 1);
+ title = demuxer->titles[demuxer->current_title];
+ demuxer->current_timecode = title->timecode_table_size - 1;
+ do_seek = 1;
+ }
+ else
+ {
+ mpeg3io_seek(title->fs, 0);
+ demuxer->current_timecode = 0;
+ result = 1;
+ }
+ }
+ }
+
+ if(!result && do_seek)
+ mpeg3io_seek(title->fs, title->timecode_table[demuxer->current_timecode].start_byte);
+ }
+
+ return result;
+}
+
+/* Read packet in the forward direction */
+int mpeg3_read_next_packet(mpeg3_demuxer_t *demuxer)
+{
+ int result = 0;
+ long current_position;
+ mpeg3_t *file = demuxer->file;
+ mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
+ demuxer->data_size = 0;
+ demuxer->data_position = 0;
+
+/* Flip the file descriptor back to the end of the packet for forward */
+/* reading. */
+ if(demuxer->reverse)
+ {
+ result = mpeg3io_seek_relative(title->fs, demuxer->packet_size);
+ demuxer->reverse = 0;
+ }
+
+/* Read packets until the output buffer is full */
+ if(!result)
+ {
+ do
+ {
+ result = mpeg3_advance_timecode(demuxer, 0);
+
+ if(!result)
+ {
+ demuxer->time_offset = mpeg3_lookup_time_offset(demuxer, mpeg3io_tell(title->fs));
+
+ if(file->is_transport_stream)
+ {
+ result = mpeg3_read_transport(demuxer);
+ }
+ else
+ if(file->is_program_stream)
+ {
+ result = mpeg3_read_program(demuxer);
+ }
+ else
+ {
+/* Read elementary stream. */
+ result = mpeg3io_read_data(demuxer->data_buffer, demuxer->packet_size, title->fs);
+ if(!result) demuxer->data_size = demuxer->packet_size;
+ }
+ }
+ }while(!result && demuxer->data_size == 0 && (demuxer->do_audio || demuxer->do_video));
+ }
+
+ return result;
+}
+
+/* Read the packet right before the packet we're currently on. */
+int mpeg3_read_prev_packet(mpeg3_demuxer_t *demuxer)
+{
+ int result = 0;
+ mpeg3_t *file = demuxer->file;
+ long current_position;
+ mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
+
+ demuxer->data_size = 0;
+ demuxer->data_position = 0;
+
+ do
+ {
+/* Rewind to the start of the packet to be read. */
+ result = mpeg3io_seek_relative(title->fs, -demuxer->packet_size);
+
+ if(!result) result = mpeg3_advance_timecode(demuxer, 1);
+ if(!result) demuxer->time_offset = mpeg3_lookup_time_offset(demuxer, mpeg3io_tell(title->fs));
+
+ if(file->is_transport_stream && !result)
+ {
+ result = mpeg3_read_transport(demuxer);
+ if(!mpeg3io_bof(title->fs))
+ /* if(!result) */result = mpeg3io_seek_relative(title->fs, -demuxer->packet_size);
+ }
+ else
+ if(file->is_program_stream && !result)
+ {
+
+ result = mpeg3_read_program(demuxer);
+ if(!mpeg3io_bof(title->fs))
+ /* if(!result) */result = mpeg3io_seek_relative(title->fs, -demuxer->packet_size);
+ }
+ else
+ if(!result)
+ {
+/* Elementary stream */
+/* Read the packet forwards and seek back to the start */
+ result = mpeg3io_read_data(demuxer->data_buffer, demuxer->packet_size, title->fs);
+ if(!result)
+ {
+ demuxer->data_size = demuxer->packet_size;
+ result = mpeg3io_seek_relative(title->fs, -demuxer->packet_size);
+ }
+ }
+ }while(!result && demuxer->data_size == 0 && (demuxer->do_audio || demuxer->do_video));
+
+/* Remember that the file descriptor is at the beginning of the packet just read. */
+ demuxer->reverse = 1;
+ demuxer->error_flag = result;
+ return result;
+}
+
+
+/* Used for audio */
+int mpeg3demux_read_data(mpeg3_demuxer_t *demuxer,
+ unsigned char *output,
+ long size)
+{
+ long i;
+ int result = 0;
+ mpeg3_t *file = demuxer->file;
+ demuxer->error_flag = 0;
+
+ if(demuxer->data_position >= 0)
+ {
+/* Read forwards */
+ for(i = 0; i < size && !result; )
+ {
+ int fragment_size = size - i;
+ if(fragment_size > demuxer->data_size - demuxer->data_position)
+ fragment_size = demuxer->data_size - demuxer->data_position;
+ memcpy(output + i, demuxer->data_buffer + demuxer->data_position, fragment_size);
+ demuxer->data_position += fragment_size;
+ i += fragment_size;
+
+ if(i < size)
+ {
+ result = mpeg3_read_next_packet(demuxer);
+ }
+ }
+ }
+ else
+ {
+/* Read backwards a full packet. */
+/* Only good for reading less than the size of a full packet, but */
+/* this routine should only be used for searching for previous markers. */
+ long current_position = demuxer->data_position;
+ result = mpeg3_read_prev_packet(demuxer);
+ if(!result) demuxer->data_position = demuxer->data_size + current_position;
+ memcpy(output, demuxer->data_buffer + demuxer->data_position, size);
+ demuxer->data_position += size;
+ }
+
+ demuxer->error_flag = result;
+ return result;
+}
+
+unsigned int mpeg3demux_read_char_packet(mpeg3_demuxer_t *demuxer)
+{
+ demuxer->error_flag = 0;
+ if(demuxer->data_position >= demuxer->data_size)
+ demuxer->error_flag = mpeg3_read_next_packet(demuxer);
+ demuxer->next_char = demuxer->data_buffer[demuxer->data_position++];
+ return demuxer->next_char;
+}
+
+unsigned int mpeg3demux_read_prev_char_packet(mpeg3_demuxer_t *demuxer)
+{
+ demuxer->error_flag = 0;
+ demuxer->data_position--;
+ if(demuxer->data_position < 0)
+ {
+ demuxer->error_flag = mpeg3_read_prev_packet(demuxer);
+ if(!demuxer->error_flag) demuxer->data_position = demuxer->data_size - 1;
+ }
+ demuxer->next_char = demuxer->data_buffer[demuxer->data_position];
+ return demuxer->next_char;
+}
+
+mpeg3demux_timecode_t* mpeg3_append_timecode(mpeg3_demuxer_t *demuxer,
+ mpeg3_title_t *title,
+ long prev_byte,
+ double prev_time,
+ long next_byte,
+ double next_time,
+ int dont_store)
+{
+ mpeg3demux_timecode_t *new_table;
+ mpeg3demux_timecode_t *new_timecode, *old_timecode;
+ long i;
+
+ if(!title->timecode_table ||
+ title->timecode_table_allocation <= title->timecode_table_size)
+ {
+ if(title->timecode_table_allocation == 0)
+ title->timecode_table_allocation = 1;
+ else
+ title->timecode_table_allocation *= 2;
+
+ new_table = (mpeg3demux_timecode_t*)calloc(1, sizeof(mpeg3demux_timecode_t) * title->timecode_table_allocation);
+ if(title->timecode_table)
+ {
+ for(i = 0; i < title->timecode_table_size; i++)
+ {
+ new_table[i] = title->timecode_table[i];
+ }
+
+ free(title->timecode_table);
+ }
+ title->timecode_table = new_table;
+ }
+
+ if(!dont_store)
+ {
+ new_timecode = &title->timecode_table[title->timecode_table_size];
+ new_timecode->start_byte = next_byte;
+ new_timecode->start_time = next_time;
+ new_timecode->absolute_start_time = 0;
+
+ if(title->timecode_table_size > 0)
+ {
+ old_timecode = &title->timecode_table[title->timecode_table_size - 1];
+ old_timecode->end_byte = prev_byte;
+ old_timecode->end_time = prev_time;
+ new_timecode->absolute_start_time =
+ prev_time -
+ old_timecode->start_time +
+ old_timecode->absolute_start_time;
+ new_timecode->absolute_end_time = next_time;
+ }
+ }
+
+ title->timecode_table_size++;
+ return new_timecode;
+}
+
+mpeg3demux_timecode_t* mpeg3demux_next_timecode(mpeg3_demuxer_t *demuxer,
+ int *current_title,
+ int *current_timecode,
+ int current_program)
+{
+ int done = 0;
+ while(!done)
+ {
+/* Increase timecode number */
+ if(*current_timecode < demuxer->titles[*current_title]->timecode_table_size - 1)
+ {
+ (*current_timecode)++;
+ if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program)
+ return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]);
+ }
+ else
+/* Increase title number */
+ if(*current_title < demuxer->total_titles - 1)
+ {
+ (*current_title)++;
+ (*current_timecode) = 0;
+ if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program)
+ return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]);
+ }
+ else
+/* End of disk */
+ done = 1;
+ }
+ return 0;
+}
+
+mpeg3demux_timecode_t* mpeg3demux_prev_timecode(mpeg3_demuxer_t *demuxer,
+ int *current_title,
+ int *current_timecode,
+ int current_program)
+{
+ int done = 0;
+ while(!done)
+ {
+/* Increase timecode number */
+ if(*current_timecode > 0)
+ {
+ (*current_timecode)--;
+ if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program)
+ return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]);
+ }
+ else
+/* Increase title number */
+ if(*current_title > 0)
+ {
+ (*current_title)--;
+ (*current_timecode) = demuxer->titles[*current_title]->timecode_table_size - 1;
+ if(demuxer->titles[*current_title]->timecode_table[*current_timecode].program == current_program)
+ return &(demuxer->titles[*current_title]->timecode_table[*current_timecode]);
+ }
+ else
+/* End of disk */
+ done = 1;
+
+ }
+ return 0;
+}
+
+int mpeg3demux_open_title(mpeg3_demuxer_t *demuxer, int title_number)
+{
+ mpeg3_title_t *title;
+
+ if(title_number < demuxer->total_titles)
+ {
+ if(demuxer->current_title >= 0)
+ {
+ mpeg3io_close_file(demuxer->titles[demuxer->current_title]->fs);
+ demuxer->current_title = -1;
+ }
+
+ title = demuxer->titles[title_number];
+ if(mpeg3io_open_file(title->fs))
+ {
+ demuxer->error_flag = 1;
+ perror("mpeg3demux_open_title");
+ }
+ else
+ {
+ demuxer->current_title = title_number;
+ }
+ }
+
+ demuxer->current_timecode = 0;
+
+ return demuxer->error_flag;
+}
+
+/* Assign program numbers to interleaved programs */
+int mpeg3demux_assign_programs(mpeg3_demuxer_t *demuxer)
+{
+ int current_program = 0;
+ int current_title = 0, previous_title;
+ int current_timecode = 0, previous_timecode;
+ double current_time, current_length;
+ int done = 0;
+ int interleaved = 0;
+ mpeg3demux_timecode_t *timecode1, *timecode2;
+ double program_times[MPEG3_MAX_STREAMS];
+ int total_programs = 1;
+ int i, j;
+ int program_exists, last_program_assigned = 0;
+ int total_timecodes;
+ mpeg3_title_t **titles = demuxer->titles;
+
+ for(i = 0, total_timecodes = 0; i < demuxer->total_titles; i++)
+ total_timecodes += demuxer->titles[i]->timecode_table_size;
+
+// if(total_timecodes < 3) return 0;
+
+/*
+ * // Assign programs based on length of contiguous timecode
+ * timecode1 = demuxer->titles[current_title]->timecode_table;
+ * while(!done)
+ * {
+ * if(!timecode1) done = 1;
+ * else
+ * if(timecode1->end_time - timecode1->start_time < MPEG3_PROGRAM_THRESHOLD)
+ * {
+ * // Got interleaved section
+ * interleaved = 1;
+ * program_times[0] = timecode1->end_time;
+ *
+ * while(interleaved && !done)
+ * {
+ * timecode2 = mpeg3demux_next_timecode(demuxer,
+ * &current_title,
+ * &current_timecode,
+ * 0);
+ *
+ * if(!timecode2) done = 1;
+ * else
+ * {
+ * // Another segment of interleaved data
+ * if(timecode2->end_time - timecode2->start_time < MPEG3_PROGRAM_THRESHOLD)
+ * {
+ * // Search program times for where the previous instance of the program left off
+ * for(program_exists = 0, i = 0;
+ * i < total_programs && !program_exists;
+ * i++)
+ * {
+ * // Got a previous instance of the program
+ * if(program_times[i] + 0.5 > timecode2->start_time &&
+ * program_times[i] - 0.5 < timecode2->start_time)
+ * {
+ * program_times[i] = timecode2->end_time;
+ * timecode2->program = i;
+ * program_exists = 1;
+ *
+ * // Programs must always start at 0 for an interleaved section
+ * if(i < last_program_assigned && i != 0)
+ * {
+ * // Shift programs in the interleaved section down until they start at 0
+ * for(j = 0; j < total_programs - 1; j++)
+ * program_times[j] = program_times[j + 1];
+ *
+ * for(previous_title = current_title, previous_timecode = current_timecode;
+ * titles[previous_title]->timecode_table[previous_timecode].program > 0 &&
+ * (previous_title >= 0 || previous_timecode >= 0); )
+ * {
+ * titles[previous_title]->timecode_table[previous_timecode].program--;
+ * previous_timecode--;
+ * if(previous_timecode < 0 && previous_title > 0)
+ * {
+ * previous_title--;
+ * previous_timecode = titles[previous_title]->timecode_table_size - 1;
+ * }
+ * }
+ * }
+ * }
+ * }
+ *
+ * // Didn't get one
+ * if(!program_exists)
+ * {
+ * program_times[total_programs] = timecode2->end_time;
+ * timecode2->program = total_programs++;
+ * }
+ * last_program_assigned = timecode2->program;
+ * }
+ * // No more interleaved section
+ * else
+ * {
+ * interleaved = 0;
+ * // Restart program table from the beginning
+ * total_programs = 1;
+ * last_program_assigned = 0;
+ * timecode1 = mpeg3demux_next_timecode(demuxer,
+ * &current_title,
+ * &current_timecode,
+ * 0);
+ * }
+ * }
+ * }
+ * }
+ * else
+ * // Get next timecode
+ * timecode1 = mpeg3demux_next_timecode(demuxer,
+ * &current_title,
+ * &current_timecode,
+ * 0);
+ * }
+ *
+ * demuxer->total_programs = total_programs;
+ */
+
+/* Assign absolute timecodes in each program. */
+ for(current_program = 0;
+ current_program < total_programs;
+ current_program++)
+ {
+ current_time = 0;
+ current_title = 0;
+ current_timecode = -1;
+ while(timecode1 = mpeg3demux_next_timecode(demuxer,
+ &current_title,
+ &current_timecode,
+ current_program))
+ {
+ timecode1->absolute_start_time = current_time;
+ current_time += timecode1->end_time - timecode1->start_time;
+ timecode1->absolute_end_time = current_time;
+ }
+ }
+//for(i = 0; i < demuxer->total_titles; i++) mpeg3_dump_title(demuxer->titles[i]);
+ demuxer->current_program = 0;
+ return 0;
+}
+
+/* ==================================================================== */
+/* Entry points */
+/* ==================================================================== */
+
+mpeg3_demuxer_t* mpeg3_new_demuxer(mpeg3_t *file, int do_audio, int do_video, int stream_id)
+{
+ mpeg3_demuxer_t *demuxer = (mpeg3_demuxer_t*)calloc(1, sizeof(mpeg3_demuxer_t));
+ int i;
+
+/* The demuxer will change the default packet size for its own use. */
+ demuxer->file = file;
+ demuxer->packet_size = file->packet_size;
+ demuxer->do_audio = do_audio;
+ demuxer->do_video = do_video;
+
+/* Allocate buffer + padding */
+ demuxer->raw_data = (unsigned char*)calloc(1, MPEG3_MAX_PACKSIZE);
+ demuxer->data_buffer = (unsigned char*)calloc(1, MPEG3_MAX_PACKSIZE);
+ demuxer->data_allocated = MPEG3_MAX_PACKSIZE;
+/* System specific variables */
+ demuxer->audio_pid = stream_id;
+ demuxer->video_pid = stream_id;
+ demuxer->astream = stream_id;
+ demuxer->vstream = stream_id;
+ demuxer->current_title = -1;
+ return demuxer;
+}
+
+int mpeg3_delete_demuxer(mpeg3_demuxer_t *demuxer)
+{
+ int i;
+
+ if(demuxer->current_title >= 0)
+ {
+ mpeg3io_close_file(demuxer->titles[demuxer->current_title]->fs);
+ }
+
+ for(i = 0; i < demuxer->total_titles; i++)
+ {
+ mpeg3_delete_title(demuxer->titles[i]);
+ }
+
+ if(demuxer->data_buffer) free(demuxer->data_buffer);
+ free(demuxer->raw_data);
+ free(demuxer);
+}
+
+/* Create a title. */
+/* Build a table of timecodes contained in the program stream. */
+/* If toc is 0 just read the first and last timecode. */
+int mpeg3demux_create_title(mpeg3_demuxer_t *demuxer, int timecode_search, FILE *toc)
+{
+ int result = 0, done = 0, counter_start, counter;
+ mpeg3_t *file = demuxer->file;
+ long next_byte, prev_byte;
+ double next_time, prev_time, absolute_time;
+ long i;
+ mpeg3_title_t *title;
+ unsigned long test_header = 0;
+ mpeg3demux_timecode_t *timecode = 0;
+
+ demuxer->error_flag = 0;
+ demuxer->generating_timecode = 1;
+
+/* Create a single title */
+ if(!demuxer->total_titles)
+ {
+ demuxer->titles[0] = mpeg3_new_title(file, file->fs->path);
+ demuxer->total_titles = 1;
+ mpeg3demux_open_title(demuxer, 0);
+ }
+ title = demuxer->titles[0];
+ title->total_bytes = mpeg3io_total_bytes(title->fs);
+
+
+/* Get the packet size from the file */
+ if(file->is_program_stream)
+ {
+ mpeg3io_seek(title->fs, 4);
+ for(i = 0; i < MPEG3_MAX_PACKSIZE &&
+ test_header != MPEG3_PACK_START_CODE; i++)
+ {
+ test_header <<= 8;
+ test_header |= mpeg3io_read_char(title->fs);
+ }
+ if(i < MPEG3_MAX_PACKSIZE) demuxer->packet_size = i;
+ mpeg3io_seek(title->fs, 0);
+ }
+ else
+ demuxer->packet_size = file->packet_size;
+
+/* Get timecodes for the title */
+ if(file->is_transport_stream || file->is_program_stream)
+ {
+ mpeg3io_seek(title->fs, 0);
+ while(!done && !result && !mpeg3io_eof(title->fs))
+ {
+ next_byte = mpeg3io_tell(title->fs);
+ result = mpeg3_read_next_packet(demuxer);
+
+ if(!result)
+ {
+ next_time = demuxer->time;
+//printf("%f %f\n", next_time, prev_time);
+ if(next_time < prev_time ||
+ next_time - prev_time > MPEG3_CONTIGUOUS_THRESHOLD ||
+ !title->timecode_table_size)
+ {
+/* Discontinuous */
+ timecode = mpeg3_append_timecode(demuxer,
+ title,
+ prev_byte,
+ prev_time,
+ next_byte,
+ next_time,
+ 0);
+/*
+ * printf("timecode: %ld %ld %f %f\n",
+ * timecode->start_byte,
+ * timecode->end_byte,
+ * timecode->start_time,
+ * timecode->end_time);
+ */
+
+ counter_start = (int)next_time;
+ }
+ prev_time = next_time;
+ prev_byte = next_byte;
+ counter = (int)next_time;
+ }
+
+/* Just get the first bytes if not building a toc to get the stream ID's. */
+ if(next_byte > 0x100000 &&
+ (!timecode_search || !toc)) done = 1;
+ }
+
+/* Get the last timecode */
+ if(!toc || !timecode_search)
+ {
+ result = mpeg3io_seek(title->fs, title->total_bytes);
+ if(!result) result = mpeg3_read_prev_packet(demuxer);
+ }
+
+ if(title->timecode_table && timecode)
+ {
+ timecode->end_byte = title->total_bytes;
+// timecode->end_byte = mpeg3io_tell(title->fs)/* + demuxer->packet_size */;
+ timecode->end_time = demuxer->time;
+ timecode->absolute_end_time = timecode->end_time - timecode->start_time;
+ }
+ }
+
+ mpeg3io_seek(title->fs, 0);
+ demuxer->generating_timecode = 0;
+ return 0;
+}
+
+int mpeg3demux_print_timecodes(mpeg3_title_t *title, FILE *output)
+{
+ mpeg3demux_timecode_t *timecode;
+ int i;
+
+ if(title->timecode_table)
+ {
+ for(i = 0; i < title->timecode_table_size; i++)
+ {
+ timecode = &title->timecode_table[i];
+
+ fprintf(output, "REGION: %ld %ld %f %f\n",
+ timecode->start_byte,
+ timecode->end_byte,
+ timecode->start_time,
+ timecode->end_time);
+ }
+ }
+ return 0;
+}
+
+/* Read the title information from a toc */
+int mpeg3demux_read_titles(mpeg3_demuxer_t *demuxer)
+{
+ char string1[MPEG3_STRLEN], string2[MPEG3_STRLEN];
+ long start_byte, end_byte;
+ float start_time, end_time;
+ mpeg3_title_t *title = 0;
+ mpeg3_t *file = demuxer->file;
+
+// Eventually use IFO file to generate titles
+ while(!feof(file->fs->fd))
+ {
+ fscanf(file->fs->fd, "%s %s %ld %f %f %f",
+ string1,
+ string2,
+ &end_byte,
+ &start_time,
+ &end_time);
+
+ if(!strncasecmp(string1, "PATH:", 5))
+ {
+ title = demuxer->titles[demuxer->total_titles++] = mpeg3_new_title(file, string2);
+
+ if(demuxer->current_title < 0)
+ mpeg3demux_open_title(demuxer, 0);
+ }
+ else
+ if(title)
+ {
+ start_byte = atol(string2);
+ if(!strcasecmp(string1, "REGION:"))
+ {
+ mpeg3_append_timecode(demuxer,
+ title,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1);
+ title->timecode_table[title->timecode_table_size - 1].start_byte = start_byte;
+ title->timecode_table[title->timecode_table_size - 1].end_byte = end_byte;
+ title->timecode_table[title->timecode_table_size - 1].start_time = start_time;
+ title->timecode_table[title->timecode_table_size - 1].end_time = end_time;
+ }
+ else
+ if(!strcasecmp(string1, "ASTREAM:"))
+ demuxer->astream_table[start_byte] = end_byte;
+ else
+ if(!strcasecmp(string1, "VSTREAM:"))
+ demuxer->vstream_table[start_byte] = end_byte;
+ else
+ if(!strcasecmp(string1, "SIZE:"))
+ title->total_bytes = start_byte;
+ else
+ if(!strcasecmp(string1, "PACKETSIZE:"))
+ demuxer->packet_size = start_byte;
+ }
+ }
+
+ mpeg3demux_assign_programs(demuxer);
+ return 0;
+}
+
+int mpeg3demux_copy_titles(mpeg3_demuxer_t *dst, mpeg3_demuxer_t *src)
+{
+ long i;
+ mpeg3_t *file = dst->file;
+ mpeg3_title_t *dst_title, *src_title;
+
+ dst->packet_size = src->packet_size;
+ dst->total_titles = src->total_titles;
+ dst->total_programs = src->total_programs;
+ for(i = 0; i < MPEG3_MAX_STREAMS; i++)
+ {
+ dst->astream_table[i] = src->astream_table[i];
+ dst->vstream_table[i] = src->vstream_table[i];
+ }
+ for(i = 0; i < src->total_titles; i++)
+ {
+ src_title = src->titles[i];
+ dst_title = dst->titles[i] = mpeg3_new_title(file, src->titles[i]->fs->path);
+ mpeg3_copy_title(dst_title, src_title);
+ }
+
+ mpeg3demux_open_title(dst, src->current_title);
+ return 0;
+}
+
+int mpeg3demux_print_streams(mpeg3_demuxer_t *demuxer, FILE *toc)
+{
+ int i;
+/* Print the stream information */
+ for(i = 0; i < MPEG3_MAX_STREAMS; i++)
+ {
+ if(demuxer->astream_table[i])
+ fprintf(toc, "ASTREAM: %d %d\n", i, demuxer->astream_table[i]);
+
+ if(demuxer->vstream_table[i])
+ fprintf(toc, "VSTREAM: %d %d\n", i, demuxer->vstream_table[i]);
+ }
+ return 0;
+}
+
+/* Need a timecode table to do this */
+double mpeg3demux_length(mpeg3_demuxer_t *demuxer)
+{
+ mpeg3_title_t *title;
+ int i, j;
+ double length;
+
+ for(i = demuxer->total_titles - 1; i >= 0; i--)
+ {
+ title = demuxer->titles[i];
+ for(j = title->timecode_table_size - 1; j >= 0; j--)
+ {
+ if(title->timecode_table[j].program == demuxer->current_program)
+ {
+ return title->timecode_table[j].end_time -
+ title->timecode_table[j].start_time +
+ title->timecode_table[j].absolute_start_time;
+ }
+ }
+ }
+
+ return 1;
+}
+
+int mpeg3demux_eof(mpeg3_demuxer_t *demuxer)
+{
+ if(demuxer->current_title >= 0)
+ {
+ if(mpeg3io_eof(demuxer->titles[demuxer->current_title]->fs) &&
+ demuxer->current_title >= demuxer->total_titles - 1)
+ return 1;
+ }
+
+ return 0;
+}
+
+int mpeg3demux_bof(mpeg3_demuxer_t *demuxer)
+{
+ if(demuxer->current_title >= 0)
+ {
+ if(mpeg3io_bof(demuxer->titles[demuxer->current_title]->fs) &&
+ demuxer->current_title <= 0)
+ return 1;
+ }
+ return 0;
+}
+
+
+/* For elemental streams seek to a byte */
+int mpeg3demux_seek_byte(mpeg3_demuxer_t *demuxer, long byte)
+{
+ long current_position;
+ mpeg3_t *file = demuxer->file;
+ mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
+
+ demuxer->data_position = 0;
+ demuxer->data_size = 0;
+
+ demuxer->error_flag = mpeg3io_seek(title->fs, byte);
+
+ if(!demuxer->error_flag && (file->is_transport_stream || file->is_program_stream))
+ {
+/* Get on a packet boundary only for system streams. */
+ current_position = mpeg3io_tell(title->fs);
+ if(byte % demuxer->packet_size)
+ {
+ demuxer->error_flag |= mpeg3io_seek(title->fs, current_position - (current_position % demuxer->packet_size));
+ }
+ }
+ return demuxer->error_flag;
+}
+
+/* For programs streams and toc seek to a time */
+int mpeg3demux_seek_time(mpeg3_demuxer_t *demuxer, double new_time)
+{
+ int i, j, done = 0, result = 0;
+ double byte_offset, new_byte_offset;
+ double guess = 0, minimum = 65535;
+ mpeg3_title_t *title;
+ mpeg3demux_timecode_t *timecode;
+
+ demuxer->error_flag = 0;
+
+ i = 0;
+ j = 0;
+ title = demuxer->titles[i];
+ timecode = &title->timecode_table[j];
+
+/* Get the title and timecode of the new position */
+ while(!demuxer->error_flag &&
+ !(timecode->absolute_start_time <= new_time &&
+ timecode->absolute_end_time > new_time &&
+ timecode->program == demuxer->current_program))
+ {
+/* Next timecode */
+ j++;
+ if(j >= title->timecode_table_size)
+ {
+ i++;
+ j = 0;
+ if(i >= demuxer->total_titles)
+ {
+ demuxer->error_flag = 1;
+ return 1;
+ }
+ else
+ {
+ mpeg3demux_open_title(demuxer, i);
+ }
+ }
+
+ title = demuxer->titles[i];
+ timecode = &title->timecode_table[j];
+ }
+
+/* Guess the new byte position */
+ demuxer->current_timecode = j;
+
+ byte_offset = ((new_time - timecode->absolute_start_time) /
+ (timecode->absolute_end_time - timecode->absolute_start_time) *
+ (timecode->end_byte - timecode->start_byte) +
+ timecode->start_byte);
+//printf("mpeg3demux_seek_time %f %f\n", new_time, byte_offset);
+
+ while(!done && !result && byte_offset >= 0)
+ {
+ result = mpeg3demux_seek_byte(demuxer, (long)byte_offset);
+//printf("seek_time 0 byte %.0f want %f result %d\n", byte_offset, new_time, result);
+
+ if(!result)
+ {
+ result = mpeg3_read_next_packet(demuxer);
+// printf("seek_time 1 guess %f want %f\n", guess, new_time);
+ guess = demuxer->time + demuxer->time_offset;
+
+ if(fabs(new_time - guess) >= fabs(minimum)) done = 1;
+ else
+ {
+ minimum = guess - new_time;
+ new_byte_offset = byte_offset + ((new_time - guess) /
+ (timecode->end_time - timecode->start_time) *
+ (timecode->end_byte - timecode->start_byte));
+ if(labs((long)new_byte_offset - (long)byte_offset) < demuxer->packet_size) done = 1;
+ byte_offset = new_byte_offset;
+ }
+ }
+ }
+
+/* Get one packet before the packet just read */
+ if(!result && byte_offset > demuxer->packet_size && minimum > 0)
+ {
+ mpeg3_read_prev_packet(demuxer);
+ mpeg3_read_prev_packet(demuxer);
+ }
+//printf("seek_time %d %d %d\n", demuxer->current_title, demuxer->current_timecode, mpeg3demux_tell(demuxer));
+ demuxer->error_flag = result;
+ return result;
+}
+
+int mpeg3demux_seek_percentage(mpeg3_demuxer_t *demuxer, double percentage)
+{
+ double total_bytes = 0;
+ double absolute_position;
+ long relative_position;
+ int i, new_title;
+ mpeg3_title_t *title;
+
+ demuxer->error_flag = 0;
+
+/* Get the absolute byte position; */
+ for(i = 0; i < demuxer->total_titles; i++)
+ total_bytes += demuxer->titles[i]->total_bytes;
+
+ absolute_position = percentage * total_bytes;
+
+/* Get the title the byte is inside */
+ for(new_title = 0, total_bytes = 0; new_title < demuxer->total_titles; new_title++)
+ {
+ total_bytes += demuxer->titles[new_title]->total_bytes;
+ if(absolute_position < total_bytes) break;
+ }
+
+ if(new_title >= demuxer->total_titles)
+ {
+ new_title = demuxer->total_titles - 1;
+ }
+
+/* Got a title */
+ title = demuxer->titles[new_title];
+ total_bytes -= title->total_bytes;
+ relative_position = (long)(absolute_position - total_bytes);
+
+/* Get the timecode the byte is inside */
+ for(demuxer->current_timecode = 0;
+ demuxer->current_timecode < title->timecode_table_size;
+ demuxer->current_timecode++)
+ {
+ if(title->timecode_table[demuxer->current_timecode].start_byte <= relative_position &&
+ title->timecode_table[demuxer->current_timecode].end_byte > relative_position)
+ {
+ break;
+ }
+ }
+
+ if(demuxer->current_timecode >= title->timecode_table_size)
+ demuxer->current_timecode = title->timecode_table_size - 1;
+
+/* Get the nearest timecode in the same program */
+ while(demuxer->current_timecode < title->timecode_table_size - 1 &&
+ title->timecode_table[demuxer->current_timecode].program != demuxer->current_program)
+ {
+ demuxer->current_timecode++;
+ }
+
+/* Open the new title and seek to the correct byte */
+ if(new_title != demuxer->current_title)
+ {
+ demuxer->error_flag = mpeg3demux_open_title(demuxer, new_title);
+ }
+
+ if(!demuxer->error_flag)
+ demuxer->error_flag = mpeg3io_seek(title->fs, relative_position);
+
+ return demuxer->error_flag;
+}
+
+double mpeg3demux_tell_percentage(mpeg3_demuxer_t *demuxer)
+{
+ double total_bytes = 0;
+ double position = 0;
+ int i;
+
+ demuxer->error_flag = 0;
+ position = mpeg3io_tell(demuxer->titles[demuxer->current_title]->fs);
+ for(i = 0; i < demuxer->total_titles; i++)
+ {
+ if(i == demuxer->current_title)
+ {
+ position += total_bytes;
+ }
+ total_bytes += demuxer->titles[i]->total_bytes;
+ }
+ return position / total_bytes;
+}
+
+double mpeg3demux_get_time(mpeg3_demuxer_t *demuxer)
+{
+ return demuxer->time;
+}
+
+long mpeg3demux_tell(mpeg3_demuxer_t *demuxer)
+{
+ return mpeg3io_tell(demuxer->titles[demuxer->current_title]->fs);
+}
+
+long mpeg3demuxer_total_bytes(mpeg3_demuxer_t *demuxer)
+{
+ mpeg3_title_t *title = demuxer->titles[demuxer->current_title];
+ return title->total_bytes;
+}
+
+mpeg3_demuxer_t* mpeg3_get_demuxer(mpeg3_t *file)
+{
+ if(file->is_program_stream || file->is_transport_stream)
+ {
+ if(file->has_audio) return file->atrack[0]->demuxer;
+ else
+ if(file->has_video) return file->vtrack[0]->demuxer;
+ }
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3demux.h b/core/multimedia/opieplayer/libmpeg3/mpeg3demux.h
new file mode 100644
index 0000000..9dfd182
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3demux.h
@@ -0,0 +1,118 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEG3DEMUX_H
+#define MPEG3DEMUX_H
+
+#include "mpeg3title.h"
+#include <stdio.h>
+
+typedef struct
+{
+ struct mpeg3_rec* file;
+/* Data consisting of the multiplexed packet */
+ unsigned char *raw_data;
+ long raw_offset;
+ int raw_size;
+ long packet_size;
+/* Only one is on depending on which track owns the demultiplexer. */
+ int do_audio;
+ int do_video;
+/* Data consisting of the elementary stream */
+ unsigned char *data_buffer;
+ long data_size;
+ long data_position;
+ long data_allocated;
+/* Remember when the file descriptor is at the beginning of the packet just read. */
+ int reverse;
+/* Set to 1 when eof or attempt to read before beginning */
+ int error_flag;
+/* Temp variables for returning */
+ unsigned char next_char;
+/* Correction factor for time discontinuity */
+ double time_offset;
+ int generating_timecode;
+
+/* Titles */
+ mpeg3_title_t *titles[MPEG3_MAX_STREAMS];
+ int total_titles;
+ int current_title;
+
+/* Tables of every stream ID encountered */
+ int astream_table[MPEG3_MAX_STREAMS]; /* macro of audio format if audio */
+ int vstream_table[MPEG3_MAX_STREAMS]; /* 1 if video */
+
+/* Programs */
+ int total_programs;
+ int current_program;
+
+/* Timecode in the current title */
+ int current_timecode;
+
+/* Byte position in the current title */
+ long current_byte;
+
+ int transport_error_indicator;
+ int payload_unit_start_indicator;
+ int pid;
+ int transport_scrambling_control;
+ int adaptation_field_control;
+ int continuity_counter;
+ int is_padding;
+ int pid_table[MPEG3_PIDMAX];
+ int continuity_counters[MPEG3_PIDMAX];
+ int total_pids;
+ int adaptation_fields;
+ double time; /* Time in seconds */
+ int audio_pid;
+ int video_pid;
+ int astream; /* Video stream ID being decoded. -1 = select first ID in stream */
+ int vstream; /* Audio stream ID being decoded. -1 = select first ID in stream */
+ int aformat; /* format of the audio derived from multiplexing codes */
+ long program_association_tables;
+ int table_id;
+ int section_length;
+ int transport_stream_id;
+ long pes_packets;
+ double pes_audio_time; /* Presentation Time stamps */
+ double pes_video_time; /* Presentation Time stamps */
+} mpeg3_demuxer_t;
+
+/* ========================================================================= */
+/* Entry points */
+/* ========================================================================= */
+
+#define mpeg3demux_error(demuxer) (((mpeg3_demuxer_t *)(demuxer))->error_flag)
+
+#define mpeg3demux_time_offset(demuxer) (((mpeg3_demuxer_t *)(demuxer))->time_offset)
+
+#define mpeg3demux_current_time(demuxer) (((mpeg3_demuxer_t *)(demuxer))->time + ((mpeg3_demuxer_t *)(demuxer))->time_offset)
+
+#define mpeg3demux_read_char(demuxer) \
+ ((((mpeg3_demuxer_t *)(demuxer))->data_position < ((mpeg3_demuxer_t *)(demuxer))->data_size) ? \
+ ((mpeg3_demuxer_t *)(demuxer))->data_buffer[((mpeg3_demuxer_t *)(demuxer))->data_position++] : \
+ mpeg3demux_read_char_packet(demuxer))
+
+#define mpeg3demux_read_prev_char(demuxer) \
+ ((((mpeg3_demuxer_t *)(demuxer))->data_position != 0) ? \
+ ((mpeg3_demuxer_t *)(demuxer))->data_buffer[((mpeg3_demuxer_t *)(demuxer))->data_position--] : \
+ mpeg3demux_read_prev_char_packet(demuxer))
+
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3io.c b/core/multimedia/opieplayer/libmpeg3/mpeg3io.c
new file mode 100644
index 0000000..c5807a7
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3io.c
@@ -0,0 +1,127 @@
+#include "mpeg3private.h"
+#include "mpeg3protos.h"
+
+#ifndef _WIN32
+#include <mntent.h>
+#else
+
+#endif
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+
+mpeg3_fs_t* mpeg3_new_fs(char *path)
+{
+ mpeg3_fs_t *fs = (mpeg3_fs_t*)calloc(1, sizeof(mpeg3_fs_t));
+ fs->css = mpeg3_new_css();
+ strcpy(fs->path, path);
+ return fs;
+}
+
+int mpeg3_delete_fs(mpeg3_fs_t *fs)
+{
+ mpeg3_delete_css(fs->css);
+ free(fs);
+ return 0;
+}
+
+int mpeg3_copy_fs(mpeg3_fs_t *dst, mpeg3_fs_t *src)
+{
+ strcpy(dst->path, src->path);
+ dst->current_byte = 0;
+ return 0;
+}
+
+long mpeg3io_get_total_bytes(mpeg3_fs_t *fs)
+{
+/*
+ * struct stat st;
+ * if(stat(fs->path, &st) < 0) return 0;
+ * return (long)st.st_size;
+ */
+
+ fseek(fs->fd, 0, SEEK_END);
+ fs->total_bytes = ftell(fs->fd);
+ fseek(fs->fd, 0, SEEK_SET);
+ return fs->total_bytes;
+}
+
+int mpeg3io_open_file(mpeg3_fs_t *fs)
+{
+/* Need to perform authentication before reading a single byte. */
+ mpeg3_get_keys(fs->css, fs->path);
+
+ if(!(fs->fd = fopen(fs->path, "rb")))
+ {
+ perror("mpeg3io_open_file");
+ return 1;
+ }
+
+ fs->total_bytes = mpeg3io_get_total_bytes(fs);
+
+ if(!fs->total_bytes)
+ {
+ fclose(fs->fd);
+ return 1;
+ }
+ fs->current_byte = 0;
+ return 0;
+}
+
+int mpeg3io_close_file(mpeg3_fs_t *fs)
+{
+ if(fs->fd) fclose(fs->fd);
+ fs->fd = 0;
+ return 0;
+}
+
+int mpeg3io_read_data(unsigned char *buffer, long bytes, mpeg3_fs_t *fs)
+{
+ int result = 0;
+//printf("read %d bytes\n",bytes);
+ result = !fread(buffer, 1, bytes, fs->fd);
+ fs->current_byte += bytes;
+ return (result && bytes);
+}
+
+int mpeg3io_device(char *path, char *device)
+{
+ struct stat file_st, device_st;
+ struct mntent *mnt;
+ FILE *fp;
+
+ if(stat(path, &file_st) < 0)
+ {
+ perror("mpeg3io_device");
+ return 1;
+ }
+
+#ifndef _WIN32
+ fp = setmntent(MOUNTED, "r");
+ while(fp && (mnt = getmntent(fp)))
+ {
+ if(stat(mnt->mnt_fsname, &device_st) < 0) continue;
+ if(device_st.st_rdev == file_st.st_dev)
+ {
+ strncpy(device, mnt->mnt_fsname, MPEG3_STRLEN);
+ break;
+ }
+ }
+ endmntent(fp);
+#endif
+
+ return 0;
+}
+
+int mpeg3io_seek(mpeg3_fs_t *fs, long byte)
+{
+ fs->current_byte = byte;
+ return fseek(fs->fd, byte, SEEK_SET);
+}
+
+int mpeg3io_seek_relative(mpeg3_fs_t *fs, long bytes)
+{
+ fs->current_byte += bytes;
+ return fseek(fs->fd, fs->current_byte, SEEK_SET);
+}
+
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3io.h b/core/multimedia/opieplayer/libmpeg3/mpeg3io.h
new file mode 100644
index 0000000..092e411
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3io.h
@@ -0,0 +1,74 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEG3IO_H
+#define MPEG3IO_H
+
+
+#include <stdio.h>
+#include "mpeg3css.h"
+#include "mpeg3private.inc"
+
+/* Filesystem structure */
+
+typedef struct
+{
+ FILE *fd;
+ mpeg3_css_t *css; /* Encryption object */
+ char path[MPEG3_STRLEN];
+/* Hypothetical position of file pointer */
+ long current_byte;
+ long total_bytes;
+} mpeg3_fs_t;
+
+#define mpeg3io_tell(fs) (((mpeg3_fs_t *)(fs))->current_byte)
+
+// End of file
+#define mpeg3io_eof(fs) (((mpeg3_fs_t *)(fs))->current_byte >= ((mpeg3_fs_t *)(fs))->total_bytes)
+
+// Beginning of file
+#define mpeg3io_bof(fs) (((mpeg3_fs_t *)(fs))->current_byte < 0)
+
+
+#define mpeg3io_total_bytes(fs) (((mpeg3_fs_t *)(fs))->total_bytes)
+
+extern inline unsigned int mpeg3io_read_int32(mpeg3_fs_t *fs)
+{
+ int a, b, c, d;
+ unsigned int result;
+/* Do not fread. This breaks byte ordering. */
+ a = (unsigned char)fgetc(fs->fd);
+ b = (unsigned char)fgetc(fs->fd);
+ c = (unsigned char)fgetc(fs->fd);
+ d = (unsigned char)fgetc(fs->fd);
+ result = ((int)a << 24) |
+ ((int)b << 16) |
+ ((int)c << 8) |
+ ((int)d);
+ fs->current_byte += 4;
+ return result;
+}
+
+extern inline unsigned int mpeg3io_read_char(mpeg3_fs_t *fs)
+{
+ fs->current_byte++;
+ return fgetc(fs->fd);
+}
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3private.h b/core/multimedia/opieplayer/libmpeg3/mpeg3private.h
new file mode 100644
index 0000000..f0e11aa
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3private.h
@@ -0,0 +1,62 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEG3PRIVATE_H
+#define MPEG3PRIVATE_H
+
+#include "mpeg3atrack.h"
+#include "mpeg3css.h"
+#include "mpeg3io.h"
+#include "mpeg3private.inc"
+#include "mpeg3title.h"
+#include "mpeg3vtrack.h"
+
+struct mpeg3_rec
+{
+ mpeg3_fs_t *fs; /* Store entry path here */
+ mpeg3_demuxer_t *demuxer; /* Master tables */
+
+/* Media specific */
+ int has_audio;
+ int has_video;
+ int total_astreams;
+ int total_vstreams;
+ mpeg3_atrack_t *atrack[MPEG3_MAX_STREAMS];
+ mpeg3_vtrack_t *vtrack[MPEG3_MAX_STREAMS];
+
+/* Only one of these is set to 1 to specify what kind of stream we have. */
+ int is_transport_stream;
+ int is_program_stream;
+ int is_audio_stream; /* Elemental stream */
+ int is_video_stream; /* Elemental stream */
+ long packet_size;
+/* Type and stream for getting current percentage */
+ int last_type_read; /* 1 - audio 2 - video */
+ int last_stream_read;
+
+ int program; /* Number of program to play */
+ int cpus;
+ int have_mmx;
+};
+
+typedef struct mpeg3_rec mpeg3_t;
+
+
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3private.inc b/core/multimedia/opieplayer/libmpeg3/mpeg3private.inc
new file mode 100644
index 0000000..7e56e7f
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3private.inc
@@ -0,0 +1,110 @@
+#ifndef LIBMPEG3_INC
+#define LIBMPEG3_INC
+
+#ifdef _WIN32
+
+// Disable some compiler warnings that happen a lot but don't matter
+#pragma warning( disable : 4003 ) // not enough parameters for macro
+#pragma warning( disable : 4305 ) // truncation frm double to float
+#pragma warning( disable : 4715 ) // not all control paths return a value
+#pragma warning( disable : 4716 ) // must return a value
+
+#ifdef LIBMPEG_EXPORTS
+#define LIBMPEG_EXPORT __declspec( dllexport )
+#else
+#define LIBMPEG_EXPORT __declspec( dllimport )
+#endif
+
+#ifdef ERROR
+#undef ERROR
+#include <windows.h>
+#undef ERROR
+#define ERROR (-1)
+#else
+#include <windows.h>
+#undef ERROR
+#endif
+
+#define inline __inline
+#define M_PI 3.14159265358979323846
+#define M_SQRT2 1.41421356237309504880
+
+#define pthread_mutexattr_t int
+#define pthread_mutexattr_init(a) // Nothing
+#define pthread_mutex_t CRITICAL_SECTION
+#define pthread_mutex_init(a,b) InitializeCriticalSection(a)
+#define pthread_mutex_lock(a) EnterCriticalSection(a)
+#define pthread_mutex_unlock(a) LeaveCriticalSection(a)
+#define pthread_mutex_destroy(a) //DeleteCriticalSection(a)
+
+#define pthread_attr_t int
+#define pthread_attr_init(a) // Nothing
+#define pthread_t unsigned long
+#define pthread_create(a,b,c,d) *(a) = _beginthread(c,0,d)
+//#define pthread_join(a,b) _endthread(b)
+//#define pthread_join(a,b) _cwait(NULL,b,NULL)
+#define pthread_join(a,b)
+
+#define strncasecmp(a,b,c) _strnicmp(a,b,c)
+#define strcasecmp(a,b) _stricmp(a,b)
+#define bzero(a,b) memset(a,0,b)
+
+#else
+
+#define LONGLONG long long
+#define ULONGLONG unsigned long long
+
+#endif
+
+#ifndef LIBMPEG_EXPORT
+#define LIBMPEG_EXPORT
+#endif
+
+#define MPEG3_FLOAT32 mpeg3_real_t
+#define MPEG3_INT16 short int
+#define MPEG3_INT32 int
+#define MPEG3_INT64 long
+
+#define MPEG3_TOC_PREFIX 0x544f4356
+#define MPEG3_TOC_PREFIXLOWER 0x746f6376
+#define MPEG3_ID3_PREFIX 0x494433
+#define MPEG3_RIFF_CODE 0x52494646
+#define MPEG3_PROC_CPUINFO "/proc/cpuinfo"
+#define MPEG3_TS_PACKET_SIZE 188
+#define MPEG3_DVD_PACKET_SIZE 0x800
+#define MPEG3_SYNC_BYTE 0x47
+#define MPEG3_PACK_START_CODE 0x000001ba
+#define MPEG3_SEQUENCE_START_CODE 0x000001b3
+#define MPEG3_SEQUENCE_END_CODE 0x000001b7
+#define MPEG3_SYSTEM_START_CODE 0x000001bb
+#define MPEG3_STRLEN 1024
+#define MPEG3_PIDMAX 20 /* Maximum number of PIDs in one stream */
+#define MPEG3_PROGRAM_ASSOCIATION_TABLE 0x00
+#define MPEG3_CONDITIONAL_ACCESS_TABLE 0x01
+#define MPEG3_PACKET_START_CODE_PREFIX 0x000001
+#define MPEG3_PRIVATE_STREAM_2 0xbf
+#define MPEG3_PADDING_STREAM 0xbe
+#define MPEG3_GOP_START_CODE 0x000001b8
+#define MPEG3_PICTURE_START_CODE 0x00000100
+#define MPEG3_EXT_START_CODE 0x000001b5
+#define MPEG3_USER_START_CODE 0x000001b2
+#define MPEG3_SLICE_MIN_START 0x00000101
+#define MPEG3_SLICE_MAX_START 0x000001af
+#define MPEG3_AC3_START_CODE 0x0b77
+#define MPEG3_PCM_START_CODE 0x0180
+#define MPEG3_MAX_CPUS 256
+#define MPEG3_MAX_STREAMS 256
+#define MPEG3_MAX_PACKSIZE 262144
+#define MPEG3_CONTIGUOUS_THRESHOLD 10 /* Positive difference before declaring timecodes discontinuous */
+#define MPEG3_PROGRAM_THRESHOLD 5 /* Minimum number of seconds before interleaving programs */
+#define MPEG3_SEEK_THRESHOLD 16 /* Number of frames difference before absolute seeking */
+
+/* Values for audio format */
+#define AUDIO_UNKNOWN 0
+#define AUDIO_MPEG 1
+#define AUDIO_AC3 2
+#define AUDIO_PCM 3
+#define AUDIO_AAC 4
+#define AUDIO_JESUS 5
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3protos.h b/core/multimedia/opieplayer/libmpeg3/mpeg3protos.h
new file mode 100644
index 0000000..631336b
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3protos.h
@@ -0,0 +1,278 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEG3PROTOS_H
+#define MPEG3PROTOS_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* CSS */
+
+mpeg3_css_t* mpeg3_new_css();
+
+/* DEMUX */
+
+mpeg3_demuxer_t* mpeg3_new_demuxer(mpeg3_t *file, int do_audio, int do_video, int stream_id);
+int mpeg3_delete_demuxer(mpeg3_demuxer_t *demuxer);
+int mpeg3demux_read_data(mpeg3_demuxer_t *demuxer, unsigned char *output, long size);
+unsigned int mpeg3demux_read_int32(mpeg3_demuxer_t *demuxer);
+unsigned int mpeg3demux_read_int24(mpeg3_demuxer_t *demuxer);
+unsigned int mpeg3demux_read_int16(mpeg3_demuxer_t *demuxer);
+double mpeg3demux_length(mpeg3_demuxer_t *demuxer);
+mpeg3_demuxer_t* mpeg3_get_demuxer(mpeg3_t *file);
+long mpeg3demux_tell(mpeg3_demuxer_t *demuxer);
+double mpeg3demux_tell_percentage(mpeg3_demuxer_t *demuxer);
+double mpeg3demux_get_time(mpeg3_demuxer_t *demuxer);
+int mpeg3demux_eof(mpeg3_demuxer_t *demuxer);
+int mpeg3demux_bof(mpeg3_demuxer_t *demuxer);
+int mpeg3demux_copy_titles(mpeg3_demuxer_t *dst, mpeg3_demuxer_t *src);
+int mpeg3demux_create_title(mpeg3_demuxer_t *demuxer, int timecode_search, FILE *toc);
+long mpeg3demuxer_total_bytes(mpeg3_demuxer_t *demuxer);
+int mpeg3demux_seek_byte(mpeg3_demuxer_t *demuxer, long byte);
+int mpeg3demux_seek_time(mpeg3_demuxer_t *demuxer, double new_time);
+int mpeg3demux_seek_percentage(mpeg3_demuxer_t *demuxer, double percentage);
+int mpeg3demux_print_streams(mpeg3_demuxer_t *demuxer, FILE *toc);
+int mpeg3demux_print_timecodes(mpeg3_title_t *title, FILE *output);
+int mpeg3demux_read_titles(mpeg3_demuxer_t *demuxer);
+int mpeg3demux_open_title(mpeg3_demuxer_t *demuxer, int title_number);
+
+/* TITLE */
+
+mpeg3_title_t* mpeg3_new_title(mpeg3_t *file, char *path);
+int mpeg3_delete_title(mpeg3_title_t *title);
+int mpeg3_copy_title(mpeg3_title_t *dst, mpeg3_title_t *src);
+
+
+/* ATRACK */
+
+mpeg3_atrack_t* mpeg3_new_atrack(mpeg3_t *file, int stream_id, int is_ac3, mpeg3_demuxer_t *demuxer);
+int mpeg3_delete_atrack(mpeg3_t *file, mpeg3_atrack_t *atrack);
+
+/* VTRACK */
+
+mpeg3_vtrack_t* mpeg3_new_vtrack(mpeg3_t *file, int stream_id, mpeg3_demuxer_t *demuxer);
+int mpeg3_delete_vtrack(mpeg3_t *file, mpeg3_vtrack_t *vtrack);
+
+/* AUDIO */
+mpeg3audio_t* mpeg3audio_new(mpeg3_t *file, mpeg3_atrack_t *track, int is_ac3);
+int mpeg3audio_delete(mpeg3audio_t *audio);
+int mpeg3audio_seek_sample(mpeg3audio_t *audio, long sample);
+int mpeg3audio_seek_percentage(mpeg3audio_t *audio, double percentage);
+int mpeg3audio_decode_audio(mpeg3audio_t *audio,
+ mpeg3_real_t *output_f,
+ short *output_i, int sampleSpacing,
+ int channel,
+ long start_position,
+ long len);
+int mpeg3audio_read_raw(mpeg3audio_t *audio, unsigned char *output, long *size, long max_size);
+int mpeg3audio_read_ac3_header(mpeg3audio_t *audio);
+int mpeg3audio_read_pcm_header(mpeg3audio_t *audio);
+int mpeg3audio_synth_mono(mpeg3audio_t *audio, mpeg3_real_t *bandPtr, mpeg3_real_t *samples, int *pnt);
+int mpeg3audio_synth_stereo(mpeg3audio_t *audio, mpeg3_real_t *bandPtr, int channel, mpeg3_real_t *out, int *pnt);
+int mpeg3audio_replace_buffer(mpeg3audio_t *audio, long new_allocation);
+int mpeg3audio_ac3_exponent_unpack(mpeg3audio_t *audio,
+ mpeg3_ac3bsi_t *bsi,
+ mpeg3_ac3audblk_t *audblk);
+int mpeg3audio_ac3_bit_allocate(mpeg3audio_t *audio,
+ unsigned int fscod,
+ mpeg3_ac3bsi_t *bsi,
+ mpeg3_ac3audblk_t *audblk);
+int mpeg3audio_ac3_coeff_unpack(mpeg3audio_t *audio,
+ mpeg3_ac3bsi_t *bsi,
+ mpeg3_ac3audblk_t *audblk,
+ mpeg3ac3_stream_samples_t samples);
+int mpeg3audio_ac3_imdct(mpeg3audio_t *audio,
+ mpeg3_ac3bsi_t *bsi,
+ mpeg3_ac3audblk_t *audblk,
+ mpeg3ac3_stream_samples_t samples);
+int mpeg3audio_replace_buffer(mpeg3audio_t *audio, long new_allocation);
+int mpeg3audio_dct36(mpeg3_real_t *inbuf, mpeg3_real_t *o1, mpeg3_real_t *o2, mpeg3_real_t *wintab, mpeg3_real_t *tsbuf);
+int mpeg3audio_dct12(mpeg3_real_t *in,mpeg3_real_t *rawout1,mpeg3_real_t *rawout2,register mpeg3_real_t *wi,register mpeg3_real_t *ts);
+int mpeg3audio_read_header(mpeg3audio_t *audio);
+int mpeg3audio_do_ac3(mpeg3audio_t *audio);
+int mpeg3audio_dolayer2(mpeg3audio_t *audio);
+int mpeg3audio_dolayer3(mpeg3audio_t *audio);
+int mpeg3audio_do_pcm(mpeg3audio_t *audio);
+int mpeg3audio_dct64(mpeg3_real_t *a, mpeg3_real_t *b, mpeg3_real_t *c);
+int mpeg3audio_reset_synths(mpeg3audio_t *audio);
+int mpeg3audio_prev_header(mpeg3audio_t *audio);
+int mpeg3audio_read_layer3_frame(mpeg3audio_t *audio);
+int mpeg3audio_new_decode_tables(mpeg3audio_t *audio);
+int mpeg3audio_imdct_init(mpeg3audio_t *audio);
+
+
+/* VIDEO */
+mpeg3video_t* mpeg3video_new(mpeg3_t *file, mpeg3_vtrack_t *track);
+int mpeg3video_delete(mpeg3video_t *video);
+int mpeg3video_read_frame(mpeg3video_t *video,
+ long frame_number,
+ unsigned char **output_rows,
+ int in_x,
+ int in_y,
+ int in_w,
+ int in_h,
+ int out_w,
+ int out_h,
+ int color_model);
+int mpeg3video_set_cpus(mpeg3video_t *video, int cpus);
+int mpeg3video_set_mmx(mpeg3video_t *video, int use_mmx);
+int mpeg3video_seek(mpeg3video_t *video);
+int mpeg3video_seek_frame(mpeg3video_t *video, long frame);
+int mpeg3video_seek_percentage(mpeg3video_t *video, double percentage);
+int mpeg3video_previous_frame(mpeg3video_t *video);
+int mpeg3video_drop_frames(mpeg3video_t *video, long frames);
+int mpeg3video_read_yuvframe(mpeg3video_t *video,
+ long frame_number,
+ char *y_output,
+ char *u_output,
+ char *v_output,
+ int in_x,
+ int in_y,
+ int in_w,
+ int in_h);
+int mpeg3video_read_raw(mpeg3video_t *video, unsigned char *output, long *size, long max_size);
+int mpeg3video_display_second_field(mpeg3video_t *video);
+int mpeg3video_init_output();
+int mpeg3video_get_header(mpeg3video_t *video, int dont_repeat);
+int mpeg3video_getpicture(mpeg3video_t *video, int framenum);
+int mpeg3video_match_refframes(mpeg3video_t *video);
+int mpeg3video_next_code(mpeg3_bits_t* stream, unsigned int code);
+int mpeg3video_prev_code(mpeg3_bits_t* stream, unsigned int code);
+int mpeg3video_getgophdr(mpeg3video_t *video);
+int mpeg3video_present_frame(mpeg3video_t *video);
+int mpeg3video_read_frame_backend(mpeg3video_t *video, int skip_bframes);
+int mpeg3video_getslicehdr(mpeg3_slice_t *slice, mpeg3video_t *video);
+int mpeg3video_get_macroblock_address(mpeg3_slice_t *slice);
+int mpeg3video_macroblock_modes(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int *pmb_type,
+ int *pstwtype,
+ int *pstwclass,
+ int *pmotion_type,
+ int *pmv_count,
+ int *pmv_format,
+ int *pdmv,
+ int *pmvscale,
+ int *pdct_type);
+int mpeg3video_motion_vectors(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int PMV[2][2][2],
+ int dmvector[2],
+ int mv_field_sel[2][2],
+ int s,
+ int mv_count,
+ int mv_format,
+ int h_r_size,
+ int v_r_size,
+ int dmv,
+ int mvscale);
+void mpeg3video_motion_vector(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int *PMV,
+ int *dmvector,
+ int h_r_size,
+ int v_r_size,
+ int dmv,
+ int mvscale,
+ int full_pel_vector);
+int mpeg3video_get_cbp(mpeg3_slice_t *slice);
+int mpeg3video_clearblock(mpeg3_slice_t *slice, int comp, int size);
+int mpeg3video_getmpg2intrablock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp,
+ int dc_dct_pred[]);
+int mpeg3video_getintrablock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp,
+ int dc_dct_pred[]);
+int mpeg3video_getmpg2interblock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp);
+int mpeg3video_getinterblock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp);
+int mpeg3video_reconstruct(mpeg3video_t *video,
+ int bx,
+ int by,
+ int mb_type,
+ int motion_type,
+ int PMV[2][2][2],
+ int mv_field_sel[2][2],
+ int dmvector[2],
+ int stwtype);
+void mpeg3video_calc_dmv(mpeg3video_t *video,
+ int DMV[][2],
+ int *dmvector,
+ int mvx,
+ int mvy);
+
+
+/* FILESYSTEM */
+
+mpeg3_fs_t* mpeg3_new_fs(char *path);
+int mpeg3_delete_fs(mpeg3_fs_t *fs);
+int mpeg3io_open_file(mpeg3_fs_t *fs);
+int mpeg3io_close_file(mpeg3_fs_t *fs);
+int mpeg3io_read_data(unsigned char *buffer, long bytes, mpeg3_fs_t *fs);
+
+/* BITSTREAM */
+mpeg3_bits_t* mpeg3bits_new_stream(mpeg3_t *file, mpeg3_demuxer_t *demuxer);
+unsigned int mpeg3bits_getbits(mpeg3_bits_t* stream, int n);
+int mpeg3bits_read_buffer(mpeg3_bits_t* stream, unsigned char *buffer, int bytes);
+int mpeg3bits_use_ptr(mpeg3_bits_t* stream, unsigned char *buffer);
+int mpeg3bits_use_demuxer(mpeg3_bits_t* stream);
+int mpeg3bits_refill(mpeg3_bits_t* stream);
+int mpeg3bits_getbitoffset(mpeg3_bits_t *stream);
+void mpeg3bits_start_reverse(mpeg3_bits_t* stream);
+void mpeg3bits_start_forward(mpeg3_bits_t* stream);
+int mpeg3bits_delete_stream(mpeg3_bits_t* stream);
+int mpeg3bits_byte_align(mpeg3_bits_t *stream);
+int mpeg3bits_seek_start(mpeg3_bits_t* stream);
+int mpeg3bits_seek_time(mpeg3_bits_t* stream, double time_position);
+int mpeg3bits_seek_byte(mpeg3_bits_t* stream, long position);
+int mpeg3bits_seek_percentage(mpeg3_bits_t* stream, double percentage);
+unsigned int mpeg3bits_next_startcode(mpeg3_bits_t* stream);
+int mpeg3bits_seek_end(mpeg3_bits_t* stream);
+
+/* MISC */
+int mpeg3_read_toc(mpeg3_t *file);
+int mpeg3_generate_toc(FILE *output, char *path, int timecode_search, int print_streams);
+int mpeg3_mmx_test();
+int mpeg3io_seek(mpeg3_fs_t *fs, long byte);
+int mpeg3io_seek_relative(mpeg3_fs_t *fs, long bytes);
+int mpeg3io_device(char *path, char *device);
+int mpeg3_decrypt_packet(mpeg3_css_t *css, unsigned char *sector);
+int mpeg3_delete_css(mpeg3_css_t *css);
+int mpeg3_get_keys(mpeg3_css_t *css, char *path);
+int mpeg3_copy_fs(mpeg3_fs_t *dst, mpeg3_fs_t *src);
+int mpeg3_min(int x, int y);
+int mpeg3_max(int x, int y);
+int mpeg3_new_slice_buffer(mpeg3_slice_buffer_t *slice_buffer);
+int mpeg3_expand_slice_buffer(mpeg3_slice_buffer_t *slice_buffer);
+int mpeg3_delete_slice_decoder(mpeg3_slice_t *slice);
+int mpeg3_new_slice_decoder(mpeg3video_t *video, mpeg3_slice_t *slice);
+int mpeg3_delete_slice_buffer(mpeg3_slice_buffer_t *slice_buffer);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3title.c b/core/multimedia/opieplayer/libmpeg3/mpeg3title.c
new file mode 100644
index 0000000..0c93363
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3title.c
@@ -0,0 +1,63 @@
+#include "mpeg3private.h"
+#include "mpeg3protos.h"
+#include "mpeg3title.h"
+
+
+#include <stdlib.h>
+
+
+mpeg3_title_t* mpeg3_new_title(mpeg3_t *file, char *path)
+{
+ mpeg3_title_t *title = (mpeg3_title_t*)calloc(1, sizeof(mpeg3_title_t));
+ title->fs = mpeg3_new_fs(path);
+ title->file = file;
+ return title;
+}
+
+int mpeg3_delete_title(mpeg3_title_t *title)
+{
+ mpeg3_delete_fs(title->fs);
+ if(title->timecode_table_size)
+ {
+ free(title->timecode_table);
+ }
+ free(title);
+ return 0;
+}
+
+
+int mpeg3_copy_title(mpeg3_title_t *dst, mpeg3_title_t *src)
+{
+ int i;
+
+ mpeg3_copy_fs(dst->fs, src->fs);
+ dst->total_bytes = src->total_bytes;
+
+ if(src->timecode_table_size)
+ {
+ dst->timecode_table_allocation = src->timecode_table_allocation;
+ dst->timecode_table_size = src->timecode_table_size;
+ dst->timecode_table = (mpeg3demux_timecode_t*)calloc(1, sizeof(mpeg3demux_timecode_t) * dst->timecode_table_allocation);
+
+ for(i = 0; i < dst->timecode_table_size; i++)
+ {
+ dst->timecode_table[i] = src->timecode_table[i];
+ }
+ }
+}
+
+int mpeg3_dump_title(mpeg3_title_t *title)
+{
+ int i;
+
+ for(i = 0; i < title->timecode_table_size; i++)
+ {
+ printf("%f: %d - %d %f %f %d\n",
+ title->timecode_table[i].absolute_start_time,
+ title->timecode_table[i].start_byte,
+ title->timecode_table[i].end_byte,
+ title->timecode_table[i].start_time,
+ title->timecode_table[i].end_time,
+ title->timecode_table[i].program);
+ }
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3title.h b/core/multimedia/opieplayer/libmpeg3/mpeg3title.h
new file mode 100644
index 0000000..a853217
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3title.h
@@ -0,0 +1,47 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEG3TITLE_H
+#define MPEG3TITLE_H
+
+#include "mpeg3io.h"
+
+typedef struct
+{
+ long start_byte;
+ double start_time;
+ double absolute_start_time;
+ double absolute_end_time;
+ long end_byte;
+ double end_time;
+ int program;
+} mpeg3demux_timecode_t;
+
+typedef struct
+{
+ struct mpeg3_rec *file;
+ mpeg3_fs_t *fs;
+ long total_bytes; /* Total bytes in file. Critical for seeking and length. */
+/* Timecode table */
+ mpeg3demux_timecode_t *timecode_table;
+ long timecode_table_size; /* Number of entries */
+ long timecode_table_allocation; /* Number of available slots */
+} mpeg3_title_t;
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3toc.c b/core/multimedia/opieplayer/libmpeg3/mpeg3toc.c
new file mode 100644
index 0000000..84b31cb
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3toc.c
@@ -0,0 +1,81 @@
+#include "libmpeg3.h"
+#include "mpeg3protos.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[])
+{
+ int i;
+/* FILE *output; */
+ char new_path[1024], *ext;
+ struct stat st;
+ long size;
+ int timecode_search = 0;
+
+ if(argc < 2)
+ {
+ fprintf(stderr, "Create a table of contents for a DVD.\n"
+ " Usage: mpeg3toc [-t] <filename>...\n"
+ " -t Perform timecode search.\n"
+ "\n"
+ " The filenames should be absolute paths unless you plan\n"
+ " to always run your movie player from the same directory\n"
+ " as the filename. Alternatively you can edit the toc by\n"
+ " hand.\n"
+ " The timecode search allows XMovie to play the Matrix.\n"
+ "Example: mpeg3toc /cd2/video_ts/vts_01_*.vob > titanic.toc\n");
+ exit(1);
+ }
+
+ for(i = 1; i < argc; i++)
+ {
+ if(!strcmp(argv[i], "-t"))
+ {
+ timecode_search = 1;
+ }
+ else
+ {
+/* Get just name */
+ ext = strrchr(argv[i], '/');
+ if(ext)
+ {
+ ext++;
+ strcpy(new_path, ext);
+ }
+ else
+ strcpy(new_path, argv[i]);
+
+
+/* Replace suffix */
+ ext = strrchr(new_path, '.');
+ if(ext)
+ {
+ sprintf(ext, ".toc");
+ }
+ else
+ strcat(new_path, ".toc");
+
+/* fprintf(stderr, "Creating %s\n", new_path); */
+
+ stat(argv[i], &st);
+ size = (long)st.st_size;
+
+ if(!size)
+ {
+ fprintf(stderr, "%s is 0 length. Skipping\n", new_path);
+ }
+ else
+ {
+/* Just want the first title's streams */
+ if(mpeg3_generate_toc(stdout, argv[i], timecode_search, i == argc - 1))
+ {
+ fprintf(stderr, "Skipping %s\n", argv[i]);
+ }
+ }
+ }
+ }
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.c b/core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.c
new file mode 100644
index 0000000..dffe9d0
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.c
@@ -0,0 +1,33 @@
+#include "libmpeg3.h"
+#include "mpeg3protos.h"
+
+#include <stdlib.h>
+
+mpeg3_vtrack_t* mpeg3_new_vtrack(mpeg3_t *file, int stream_id, mpeg3_demuxer_t *demuxer)
+{
+ int result = 0;
+ mpeg3_vtrack_t *new_vtrack;
+ new_vtrack = (mpeg3_vtrack_t*)calloc(1, sizeof(mpeg3_vtrack_t));
+ new_vtrack->demuxer = mpeg3_new_demuxer(file, 0, 1, stream_id);
+ if(demuxer) mpeg3demux_copy_titles(new_vtrack->demuxer, demuxer);
+ new_vtrack->current_position = 0;
+
+/* Get information about the track here. */
+ new_vtrack->video = mpeg3video_new(file, new_vtrack);
+ if(!new_vtrack->video)
+ {
+/* Failed */
+ mpeg3_delete_vtrack(file, new_vtrack);
+ new_vtrack = 0;
+ }
+ return new_vtrack;
+}
+
+int mpeg3_delete_vtrack(mpeg3_t *file, mpeg3_vtrack_t *vtrack)
+{
+ if(vtrack->video)
+ mpeg3video_delete(vtrack->video);
+ if(vtrack->demuxer)
+ mpeg3_delete_demuxer(vtrack->demuxer);
+ free(vtrack);
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.h b/core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.h
new file mode 100644
index 0000000..9a3c13d
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/mpeg3vtrack.h
@@ -0,0 +1,39 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEG3_VTRACK_H
+#define MPEG3_VTRACK_H
+
+#include "mpeg3demux.h"
+#include "video/mpeg3video.h"
+
+struct mpeg3_vtrack_rec
+{
+ int width;
+ int height;
+ float frame_rate;
+ mpeg3_demuxer_t *demuxer;
+ mpeg3video_t *video;
+ long current_position; /* Number of next frame to be played */
+ long total_frames; /* Total frames in the file */
+};
+
+typedef struct mpeg3_vtrack_rec mpeg3_vtrack_t;
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/ronin_narrow.toc b/core/multimedia/opieplayer/libmpeg3/ronin_narrow.toc
new file mode 100644
index 0000000..07cbbf8
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/ronin_narrow.toc
@@ -0,0 +1,26 @@
+TOCVERSION 2
+PATH: /cdrom/video_ts/vts_01_1.vob
+ASTREAM: 0 2
+VSTREAM: 0 1
+ASTREAM: 1 2
+ASTREAM: 2 2
+SIZE: 1073709056
+PACKETSIZE: 2048
+REGION: 0 35557376 0.000000 51.643256
+REGION: 35559424 307005440 0.000000 440.561122
+REGION: 307007488 556705792 0.000000 423.698289
+REGION: 556707840 792827904 0.000000 423.877622
+REGION: 792829952 967956480 0.000000 292.754122
+REGION: 967958528 1073709056 0.000000 191.720711
+TOCVERSION 2
+PATH: /cdrom/video_ts/vts_01_2.vob
+ASTREAM: 0 2
+VSTREAM: 0 1
+ASTREAM: 1 2
+ASTREAM: 2 2
+SIZE: 1073709056
+PACKETSIZE: 2048
+REGION: 0 268423168 191.722344 632.760000
+REGION: 268425216 539189248 0.000000 448.729167
+REGION: 539191296 823230464 0.000000 374.061122
+REGION: 823232512 1073709056 0.000000 421.215667
diff --git a/core/multimedia/opieplayer/libmpeg3/ronin_wide.toc b/core/multimedia/opieplayer/libmpeg3/ronin_wide.toc
new file mode 100644
index 0000000..a638304
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/ronin_wide.toc
@@ -0,0 +1,47 @@
+TOCVERSION 2
+PATH: /cdrom/video_ts/vts_01_1.vob
+SIZE: 1073709056
+PACKETSIZE: 2048
+REGION: 0 33830912 0.000000 51.643256
+REGION: 33832960 321945600 0.000000 440.561122
+REGION: 321947648 566126592 0.000000 423.698289
+REGION: 566128640 804149248 0.000000 423.877622
+REGION: 804151296 979050496 0.000000 292.754122
+REGION: 979052544 1073709056 0.000000 170.331700
+TOCVERSION 2
+PATH: /cdrom/video_ts/vts_01_2.vob
+SIZE: 1073709056
+PACKETSIZE: 2048
+REGION: 0 274845696 170.333322 632.760000
+REGION: 274847744 539138048 0.000000 448.729167
+REGION: 539140096 818880512 0.000000 374.061122
+REGION: 818882560 1073709056 0.000000 431.104722
+TOCVERSION 2
+PATH: /cdrom/video_ts/vts_01_3.vob
+SIZE: 1073709056
+PACKETSIZE: 2048
+REGION: 0 3602432 431.122100 437.362056
+REGION: 3604480 316528640 0.000000 508.150422
+REGION: 316530688 562409472 0.000000 446.758722
+REGION: 562411520 728014848 0.000000 317.737689
+REGION: 728016896 943480832 0.000000 401.809556
+REGION: 943482880 1073709056 0.000000 177.871922
+TOCVERSION 2
+PATH: /cdrom/video_ts/vts_01_4.vob
+SIZE: 1073709056
+PACKETSIZE: 2048
+REGION: 0 224798720 177.873544 496.357422
+REGION: 224800768 469219328 0.000000 431.833522
+REGION: 469221376 718004224 0.000000 426.048756
+REGION: 718006272 978356224 0.000000 411.668422
+REGION: 978358272 1073709056 0.000000 154.534211
+TOCVERSION 2
+PATH: /cdrom/video_ts/vts_01_5.vob
+ASTREAM: 0 2
+VSTREAM: 0 1
+ASTREAM: 1 2
+ASTREAM: 2 2
+SIZE: 78041088
+PACKETSIZE: 2048
+REGION: 0 78028800 154.545878 312.853122
+REGION: 78030848 78041088 0.000000 0.006500
diff --git a/core/multimedia/opieplayer/libmpeg3/timecode.h b/core/multimedia/opieplayer/libmpeg3/timecode.h
new file mode 100644
index 0000000..21e51e5
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/timecode.h
@@ -0,0 +1,31 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef TIMECODE_H
+#define TIMECODE_H
+
+typedef struct
+{
+ long hour;
+ long minute;
+ long second;
+ long frame;
+} mpeg3_timecode_t;
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/video/Makefile b/core/multimedia/opieplayer/libmpeg3/video/Makefile
new file mode 100644
index 0000000..46d8407
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/Makefile
@@ -0,0 +1,32 @@
+include ../global_config
+export CFLAGS
+export CFLAGS_lessopt
+
+OBJS = \
+ getpicture.o \
+ headers.o \
+ idct.o \
+ macroblocks.o \
+ mmxtest.o \
+ motion.o \
+ mpeg3video.o \
+ output.o \
+ reconstruct.o \
+ seek.o \
+ slice.o \
+ vlc.o
+
+
+all: $(OBJS) $(MMXOBJS2)
+
+.c.o:
+ $(CC) -c `./c_flags` -o $@ $<
+
+.s.o:
+ $(NASM) -f elf $*.s
+
+.S.o:
+ $(CC) -S `./c_flags` $*.S
+
+clean:
+ rm -f *.o
diff --git a/core/multimedia/opieplayer/libmpeg3/video/c_flags b/core/multimedia/opieplayer/libmpeg3/video/c_flags
new file mode 100755
index 0000000..d7943d0
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/c_flags
@@ -0,0 +1 @@
+echo $CFLAGS
diff --git a/core/multimedia/opieplayer/libmpeg3/video/getpicture.c b/core/multimedia/opieplayer/libmpeg3/video/getpicture.c
new file mode 100644
index 0000000..4f67484
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/getpicture.c
@@ -0,0 +1,767 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include "vlc.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int mpeg3video_get_cbp(mpeg3_slice_t *slice)
+{
+ int code;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+ if((code = mpeg3slice_showbits9(slice_buffer)) >= 128)
+ {
+ code >>= 4;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab0[code].len);
+ return mpeg3_CBPtab0[code].val;
+ }
+
+ if(code >= 8)
+ {
+ code >>= 1;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab1[code].len);
+ return mpeg3_CBPtab1[code].val;
+ }
+
+ if(code < 1)
+ {
+/* fprintf(stderr,"mpeg3video_get_cbp: invalid coded_block_pattern code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_CBPtab2[code].len);
+ return mpeg3_CBPtab2[code].val;
+}
+
+
+/* set block to zero */
+int mpeg3video_clearblock(mpeg3_slice_t *slice, int comp, int size)
+{
+ slice->sparse[comp] = 1;
+
+/* Compiler error */
+/*
+ * for(i = 0; i < size; i++)
+ * {
+ * bzero(slice->block[comp] + sizeof(short) * 64 * i, sizeof(short) * 64);
+ * }
+ */
+
+ if(size == 6)
+ {
+ bzero(slice->block[comp], sizeof(short) * 64 * 6);
+ }
+ else
+ {
+printf("mpeg3video_clearblock size = %d\n", size);
+ memset(slice->block[comp], 0, sizeof(short) * 64 * size);
+ }
+ return 0;
+}
+
+static inline int mpeg3video_getdclum(mpeg3_slice_buffer_t *slice_buffer)
+{
+ int code, size, val;
+/* decode length */
+ code = mpeg3slice_showbits5(slice_buffer);
+
+ if(code < 31)
+ {
+ size = mpeg3_DClumtab0[code].val;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab0[code].len);
+ }
+ else
+ {
+ code = mpeg3slice_showbits9(slice_buffer) - 0x1f0;
+ size = mpeg3_DClumtab1[code].val;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_DClumtab1[code].len);
+ }
+
+ if(size == 0) val = 0;
+ else
+ {
+ val = mpeg3slice_getbits(slice_buffer, size);
+ if((val & (1 << (size - 1))) == 0) val -= (1 << size) - 1;
+ }
+
+ return val;
+}
+
+
+int mpeg3video_getdcchrom(mpeg3_slice_buffer_t *slice_buffer)
+{
+ int code, size, val;
+
+/* decode length */
+ code = mpeg3slice_showbits5(slice_buffer);
+
+ if(code < 31)
+ {
+ size = mpeg3_DCchromtab0[code].val;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab0[code].len);
+ }
+ else
+ {
+ code = mpeg3slice_showbits(slice_buffer, 10) - 0x3e0;
+ size = mpeg3_DCchromtab1[code].val;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_DCchromtab1[code].len);
+ }
+
+ if(size == 0) val = 0;
+ else
+ {
+ val = mpeg3slice_getbits(slice_buffer, size);
+ if((val & (1 << (size - 1))) == 0) val -= (1 << size) - 1;
+ }
+
+ return val;
+}
+
+
+/* decode one intra coded MPEG-1 block */
+
+int mpeg3video_getintrablock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp,
+ int dc_dct_pred[])
+{
+ int val, i, j, sign;
+ unsigned int code;
+ mpeg3_DCTtab_t *tab = 0;
+ short *bp = slice->block[comp];
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+/* decode DC coefficients */
+ if(comp < 4)
+ bp[0] = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer)) << 3;
+ else
+ if(comp == 4)
+ bp[0] = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer)) << 3;
+ else
+ bp[0] = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer)) << 3;
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ bp[0] <<= 4;
+#endif
+
+ if(slice->fault) return 1;
+
+/* decode AC coefficients */
+ for(i = 1; ; i++)
+ {
+ code = mpeg3slice_showbits16(slice_buffer);
+ if(code >= 16384)
+ tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
+ else
+ if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4];
+ else
+ if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8];
+ else
+ if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];
+ else
+ if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16];
+ else
+ if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16];
+ else
+ if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16];
+ else
+ if(code >= 16) tab = &mpeg3_DCTtab6[code - 16];
+ else
+ {
+/* fprintf(stderr, "mpeg3video_getintrablock: invalid Huffman code\n"); */
+ slice->fault = 1;
+ return 1;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, tab->len);
+
+ if(tab->run == 64) break; /* end_of_block */
+
+ if(tab->run == 65)
+ {
+/* escape */
+ i += mpeg3slice_getbits(slice_buffer, 6);
+
+ if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0)
+ val = mpeg3slice_getbits(slice_buffer, 8);
+ else
+ if(val == 128)
+ val = mpeg3slice_getbits(slice_buffer, 8) - 256;
+ else
+ if(val > 128)
+ val -= 256;
+
+ if((sign = (val < 0)) != 0) val= -val;
+ }
+ else
+ {
+ i += tab->run;
+ val = tab->level;
+ sign = mpeg3slice_getbit(slice_buffer);
+ }
+
+ if(i < 64)
+ j = video->mpeg3_zigzag_scan_table[i];
+ else
+ {
+ slice->fault = 1;
+ return 1;
+ }
+
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ {
+ val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) << 1;
+ val = (val - 16) | 16;
+ }
+ else
+#endif
+ {
+ val = (val * slice->quant_scale * video->intra_quantizer_matrix[j]) >> 3;
+ val = (val - 1) | 1;
+ }
+
+ bp[j] = sign ? -val : val;
+ }
+
+ if(j != 0)
+ {
+/* not a sparse matrix ! */
+ slice->sparse[comp] = 0;
+ }
+ return 0;
+}
+
+
+/* decode one non-intra coded MPEG-1 block */
+
+int mpeg3video_getinterblock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp)
+{
+ int val, i, j, sign;
+ unsigned int code;
+ mpeg3_DCTtab_t *tab;
+ short *bp = slice->block[comp];
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+/* decode AC coefficients */
+ for(i = 0; ; i++)
+ {
+ code = mpeg3slice_showbits16(slice_buffer);
+ if(code >= 16384)
+ {
+ if(i == 0)
+ tab = &mpeg3_DCTtabfirst[(code >> 12) - 4];
+ else
+ tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
+ }
+ else
+ if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4];
+ else
+ if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8];
+ else
+ if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];
+ else
+ if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16];
+ else
+ if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16];
+ else
+ if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16];
+ else
+ if(code >= 16) tab = &mpeg3_DCTtab6[code - 16];
+ else
+ {
+// invalid Huffman code
+ slice->fault = 1;
+ return 1;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, tab->len);
+
+/* end of block */
+ if(tab->run == 64)
+ break;
+
+ if(tab->run == 65)
+ {
+/* escape */
+ i += mpeg3slice_getbits(slice_buffer, 6);
+ if((val = mpeg3slice_getbits(slice_buffer, 8)) == 0)
+ val = mpeg3slice_getbits(slice_buffer, 8);
+ else
+ if(val == 128)
+ val = mpeg3slice_getbits(slice_buffer, 8) - 256;
+ else
+ if(val > 128)
+ val -= 256;
+
+ if((sign = (val < 0)) != 0) val = -val;
+ }
+ else
+ {
+ i += tab->run;
+ val = tab->level;
+ sign = mpeg3slice_getbit(slice_buffer);
+ }
+
+ j = video->mpeg3_zigzag_scan_table[i];
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ {
+ val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]);
+ val = (val - 16) | 16;
+ }
+ else
+#endif
+ {
+ val = (((val << 1)+1) * slice->quant_scale * video->non_intra_quantizer_matrix[j]) >> 4;
+ val = (val - 1) | 1;
+ }
+
+ bp[j] = sign ? -val : val;
+ }
+
+ if(j != 0)
+ {
+/* not a sparse matrix ! */
+ slice->sparse[comp] = 0;
+ }
+ return 0;
+}
+
+
+/* decode one intra coded MPEG-2 block */
+int mpeg3video_getmpg2intrablock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp,
+ int dc_dct_pred[])
+{
+ int val, i, j, sign, nc;
+ unsigned int code;
+ mpeg3_DCTtab_t *tab;
+ short *bp;
+ int *qmat;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+/* with data partitioning, data always goes to base layer */
+ bp = slice->block[comp];
+
+ qmat = (comp < 4 || video->chroma_format == CHROMA420)
+ ? video->intra_quantizer_matrix
+ : video->chroma_intra_quantizer_matrix;
+
+/* decode DC coefficients */
+ if(comp < 4)
+ val = (dc_dct_pred[0] += mpeg3video_getdclum(slice_buffer));
+ else
+ if((comp & 1) == 0)
+ val = (dc_dct_pred[1] += mpeg3video_getdcchrom(slice_buffer));
+ else
+ val = (dc_dct_pred[2] += mpeg3video_getdcchrom(slice_buffer));
+
+ if(slice->fault) return 1;
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ bp[0] = val << (7 - video->dc_prec);
+ else
+#endif
+ bp[0] = val << (3 - video->dc_prec);
+
+ nc = 0;
+
+/* decode AC coefficients */
+ for(i = 1; ; i++)
+ {
+ code = mpeg3slice_showbits16(slice_buffer);
+
+ if(code >= 16384 && !video->intravlc)
+ tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
+ else
+ if(code >= 1024)
+ {
+ if(video->intravlc)
+ tab = &mpeg3_DCTtab0a[(code >> 8) - 4];
+ else
+ tab = &mpeg3_DCTtab0[(code >> 8) - 4];
+ }
+ else
+ if(code >= 512)
+ {
+ if(video->intravlc)
+ tab = &mpeg3_DCTtab1a[(code >> 6) - 8];
+ else
+ tab = &mpeg3_DCTtab1[(code >> 6) - 8];
+ }
+ else
+ if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];
+ else
+ if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16];
+ else
+ if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16];
+ else
+ if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16];
+ else
+ if(code >= 16) tab = &mpeg3_DCTtab6[code - 16];
+ else
+ {
+/* fprintf(stderr,"mpeg3video_getmpg2intrablock: invalid Huffman code\n"); */
+ slice->fault = 1;
+ return 1;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, tab->len);
+
+/* end_of_block */
+ if(tab->run == 64)
+ break;
+
+ if(tab->run == 65)
+ {
+/* escape */
+ i += mpeg3slice_getbits(slice_buffer, 6);
+
+ val = mpeg3slice_getbits(slice_buffer, 12);
+ if((val & 2047) == 0)
+ {
+// invalid signed_level (escape)
+ slice->fault = 1;
+ return 1;
+ }
+ if((sign = (val >= 2048)) != 0) val = 4096 - val;
+ }
+ else
+ {
+ i += tab->run;
+ val = tab->level;
+ sign = mpeg3slice_getbit(slice_buffer);
+ }
+
+ j = (video->altscan ? video->mpeg3_alternate_scan_table : video->mpeg3_zigzag_scan_table)[i];
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ val = (val * slice->quant_scale * qmat[j]);
+ else
+#endif
+ val = (val * slice->quant_scale * qmat[j]) >> 4;
+
+ bp[j] = sign ? -val : val;
+ nc++;
+ }
+
+ if(j != 0)
+ {
+/* not a sparse matrix ! */
+ slice->sparse[comp] = 0;
+ }
+ return 1;
+}
+
+
+/* decode one non-intra coded MPEG-2 block */
+
+int mpeg3video_getmpg2interblock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp)
+{
+ int val, i, j, sign, nc;
+ unsigned int code;
+ mpeg3_DCTtab_t *tab;
+ short *bp;
+ int *qmat;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+/* with data partitioning, data always goes to base layer */
+ bp = slice->block[comp];
+
+ qmat = (comp < 4 || video->chroma_format == CHROMA420)
+ ? video->non_intra_quantizer_matrix
+ : video->chroma_non_intra_quantizer_matrix;
+
+ nc = 0;
+
+/* decode AC coefficients */
+ for(i = 0; ; i++)
+ {
+ code = mpeg3slice_showbits16(slice_buffer);
+ if(code >= 16384)
+ {
+ if(i == 0) tab = &mpeg3_DCTtabfirst[(code >> 12) - 4];
+ else tab = &mpeg3_DCTtabnext[(code >> 12) - 4];
+ }
+ else
+ if(code >= 1024) tab = &mpeg3_DCTtab0[(code >> 8) - 4];
+ else
+ if(code >= 512) tab = &mpeg3_DCTtab1[(code >> 6) - 8];
+ else
+ if(code >= 256) tab = &mpeg3_DCTtab2[(code >> 4) - 16];
+ else
+ if(code >= 128) tab = &mpeg3_DCTtab3[(code >> 3) - 16];
+ else
+ if(code >= 64) tab = &mpeg3_DCTtab4[(code >> 2) - 16];
+ else
+ if(code >= 32) tab = &mpeg3_DCTtab5[(code >> 1) - 16];
+ else
+ if(code >= 16) tab = &mpeg3_DCTtab6[code - 16];
+ else
+ {
+// invalid Huffman code
+ slice->fault = 1;
+ return 1;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, tab->len);
+
+/* end_of_block */
+ if(tab->run == 64)
+ break;
+
+ if(tab->run == 65)
+ {
+/* escape */
+ i += mpeg3slice_getbits(slice_buffer, 6);
+ val = mpeg3slice_getbits(slice_buffer, 12);
+ if((val & 2047) == 0)
+ {
+/* fprintf(stderr, "mpeg3video_getmpg2interblock: invalid signed_level (escape)\n"); */
+ slice->fault = 1;
+ return 1;
+ }
+ if((sign = (val >= 2048)) != 0) val = 4096 - val;
+ }
+ else
+ {
+ i += tab->run;
+ val = tab->level;
+ sign = mpeg3slice_getbit(slice_buffer);
+ }
+
+ j = (video->altscan ? video->mpeg3_alternate_scan_table : video->mpeg3_zigzag_scan_table)[i];
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ val = (((val << 1)+1) * slice->quant_scale * qmat[j]) >> 1;
+ else
+#endif
+ val = (((val << 1)+1) * slice->quant_scale * qmat[j]) >> 5;
+
+ bp[j] = sign ? (-val) : val ;
+ nc++;
+ }
+
+ if(j != 0)
+ {
+ slice->sparse[comp] = 0;
+ }
+ return 0;
+}
+
+
+/* decode all macroblocks of the current picture */
+int mpeg3video_get_macroblocks(mpeg3video_t *video, int framenum)
+{
+ unsigned int code;
+ mpeg3_slice_buffer_t *slice_buffer; /* Buffer being loaded */
+ int i;
+ int current_buffer;
+ mpeg3_bits_t *vstream = video->vstream;
+
+/* Load every slice into a buffer array */
+ video->total_slice_buffers = 0;
+ current_buffer = 0;
+ while(!mpeg3bits_eof(vstream) &&
+ mpeg3bits_showbits32_noptr(vstream) >= MPEG3_SLICE_MIN_START &&
+ mpeg3bits_showbits32_noptr(vstream) <= MPEG3_SLICE_MAX_START)
+ {
+/* Initialize the buffer */
+ if(current_buffer >= video->slice_buffers_initialized)
+ mpeg3_new_slice_buffer(&(video->slice_buffers[video->slice_buffers_initialized++]));
+ slice_buffer = &(video->slice_buffers[current_buffer]);
+ slice_buffer->buffer_size = 0;
+ slice_buffer->current_position = 0;
+ slice_buffer->bits_size = 0;
+ slice_buffer->done = 0;
+
+/* Read the slice into the buffer including the slice start code */
+ do
+ {
+/* Expand buffer */
+ if(slice_buffer->buffer_allocation <= slice_buffer->buffer_size)
+ mpeg3_expand_slice_buffer(slice_buffer);
+
+/* Load 1 char into buffer */
+ slice_buffer->data[slice_buffer->buffer_size++] = mpeg3bits_getbyte_noptr(vstream);
+ }while(!mpeg3bits_eof(vstream) &&
+ mpeg3bits_showbits24_noptr(vstream) != MPEG3_PACKET_START_CODE_PREFIX);
+
+/* Pad the buffer to get the last macroblock */
+ if(slice_buffer->buffer_allocation <= slice_buffer->buffer_size + 4)
+ mpeg3_expand_slice_buffer(slice_buffer);
+
+ slice_buffer->data[slice_buffer->buffer_size++] = 0;
+ slice_buffer->data[slice_buffer->buffer_size++] = 0;
+ slice_buffer->data[slice_buffer->buffer_size++] = 1;
+ slice_buffer->data[slice_buffer->buffer_size++] = 0;
+ slice_buffer->bits_size = 0;
+
+ pthread_mutex_lock(&(slice_buffer->completion_lock)); fflush(stdout);
+ current_buffer++;
+ video->total_slice_buffers++;
+ }
+
+/* Run the slice decoders */
+ if(video->total_slice_buffers > 0)
+ {
+ for(i = 0; i < video->total_slice_decoders; i++)
+ {
+ if(i == 0 && video->total_slice_decoders > 1)
+ {
+ video->slice_decoders[i].current_buffer = 0;
+ video->slice_decoders[i].buffer_step = 1;
+ video->slice_decoders[i].last_buffer = (video->total_slice_buffers - 1);
+ }
+ else
+ if(i == 1)
+ {
+ video->slice_decoders[i].current_buffer = video->total_slice_buffers - 1;
+ video->slice_decoders[i].buffer_step = -1;
+ video->slice_decoders[i].last_buffer = 0;
+ }
+ else
+ {
+ video->slice_decoders[i].current_buffer = i;
+ video->slice_decoders[i].buffer_step = 1;
+ video->slice_decoders[i].last_buffer = video->total_slice_buffers - 1;
+ }
+ pthread_mutex_unlock(&(video->slice_decoders[i].input_lock));
+ }
+ }
+
+/* Wait for the slice decoders to finish */
+ if(video->total_slice_buffers > 0)
+ {
+ for(i = 0; i < video->total_slice_buffers; i++)
+ {
+ pthread_mutex_lock(&(video->slice_buffers[i].completion_lock));
+ pthread_mutex_unlock(&(video->slice_buffers[i].completion_lock));
+ }
+ }
+ return 0;
+}
+
+int mpeg3video_allocate_decoders(mpeg3video_t *video, int decoder_count)
+{
+ int i;
+ mpeg3_t *file = video->file;
+/* Get the slice decoders */
+ if(video->total_slice_decoders != file->cpus)
+ {
+ for(i = 0; i < video->total_slice_decoders; i++)
+ {
+ mpeg3_delete_slice_decoder(&video->slice_decoders[i]);
+ }
+
+ for(i = 0; i < file->cpus && i < MPEG3_MAX_CPUS; i++)
+ {
+ mpeg3_new_slice_decoder(video, &(video->slice_decoders[i]));
+ video->slice_decoders[i].thread_number = i;
+ }
+
+ video->total_slice_decoders = file->cpus;
+ }
+ return 0;
+}
+
+/* decode one frame or field picture */
+
+int mpeg3video_getpicture(mpeg3video_t *video, int framenum)
+{
+ int i, result = 0;
+ mpeg3_t *file = video->file;
+
+ if(video->pict_struct == FRAME_PICTURE && video->secondfield)
+ {
+/* recover from illegal number of field pictures */
+ video->secondfield = 0;
+ }
+
+ if(!video->mpeg2)
+ {
+ video->current_repeat = video->repeat_count = 0;
+ }
+
+ mpeg3video_allocate_decoders(video, file->cpus);
+
+ for(i = 0; i < 3; i++)
+ {
+ if(video->pict_type == B_TYPE)
+ {
+ video->newframe[i] = video->auxframe[i];
+ }
+ else
+ {
+ if(!video->secondfield && !video->current_repeat)
+ {
+/* Swap refframes for I frames */
+ unsigned char* tmp = video->oldrefframe[i];
+ video->oldrefframe[i] = video->refframe[i];
+ video->refframe[i] = tmp;
+ }
+
+ video->newframe[i] = video->refframe[i];
+ }
+
+ if(video->pict_struct == BOTTOM_FIELD)
+ {
+/* Only used if fields are in different pictures */
+ video->newframe[i] += (i == 0) ? video->coded_picture_width : video->chrom_width;
+ }
+ }
+
+/* The problem is when a B frame lands on the first repeat and is skipped, */
+/* the second repeat goes for the same bitmap as the skipped repeat, */
+/* so it picks up a frame from 3 frames back. */
+/* The first repeat must consititutively read a B frame if its B frame is going to be */
+/* used in a later repeat. */
+ if(!video->current_repeat)
+ if(!(video->skip_bframes && video->pict_type == B_TYPE) ||
+ (video->repeat_count >= 100 + 100 * video->skip_bframes))
+ result = mpeg3video_get_macroblocks(video, framenum);
+
+/* Set the frame to display */
+ video->output_src = 0;
+ if(framenum > -1 && !result)
+ {
+ if(video->pict_struct == FRAME_PICTURE || video->secondfield)
+ {
+ if(video->pict_type == B_TYPE)
+ {
+ video->output_src = video->auxframe;
+ }
+ else
+ {
+ video->output_src = video->oldrefframe;
+ }
+ }
+ else
+ {
+ mpeg3video_display_second_field(video);
+ }
+ }
+
+ if(video->mpeg2)
+ {
+ video->current_repeat += 100;
+ }
+
+ if(video->pict_struct != FRAME_PICTURE) video->secondfield = !video->secondfield;
+ return result;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/video/headers.c b/core/multimedia/opieplayer/libmpeg3/video/headers.c
new file mode 100644
index 0000000..5274530
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/headers.c
@@ -0,0 +1,492 @@
+#include "../mpeg3demux.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int mpeg3video_getseqhdr(mpeg3video_t *video)
+{
+ int i;
+ mpeg3_t *file = video->file;
+
+ int aspect_ratio, picture_rate, vbv_buffer_size;
+ int constrained_parameters_flag;
+ int load_intra_quantizer_matrix, load_non_intra_quantizer_matrix;
+
+ video->horizontal_size = mpeg3bits_getbits(video->vstream, 12);
+ video->vertical_size = mpeg3bits_getbits(video->vstream, 12);
+ aspect_ratio = mpeg3bits_getbits(video->vstream, 4);
+ video->framerate_code = mpeg3bits_getbits(video->vstream, 4);
+ video->bitrate = mpeg3bits_getbits(video->vstream, 18);
+ mpeg3bits_getbit_noptr(video->vstream); /* marker bit (=1) */
+ vbv_buffer_size = mpeg3bits_getbits(video->vstream, 10);
+ constrained_parameters_flag = mpeg3bits_getbit_noptr(video->vstream);
+ video->frame_rate = mpeg3_frame_rate_table[video->framerate_code];
+
+ load_intra_quantizer_matrix = mpeg3bits_getbit_noptr(video->vstream);
+ if(load_intra_quantizer_matrix)
+ {
+ for(i = 0; i < 64; i++)
+ video->intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+ else
+ {
+ for(i = 0; i < 64; i++)
+ video->intra_quantizer_matrix[i] = mpeg3_default_intra_quantizer_matrix[i];
+ }
+
+ load_non_intra_quantizer_matrix = mpeg3bits_getbit_noptr(video->vstream);
+ if(load_non_intra_quantizer_matrix)
+ {
+ for(i = 0; i < 64; i++)
+ video->non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+ else
+ {
+ for(i = 0; i < 64; i++)
+ video->non_intra_quantizer_matrix[i] = 16;
+ }
+
+/* copy luminance to chrominance matrices */
+ for(i = 0; i < 64; i++)
+ {
+ video->chroma_intra_quantizer_matrix[i] = video->intra_quantizer_matrix[i];
+ video->chroma_non_intra_quantizer_matrix[i] = video->non_intra_quantizer_matrix[i];
+ }
+
+ return 0;
+}
+
+
+/* decode sequence extension */
+
+int mpeg3video_sequence_extension(mpeg3video_t *video)
+{
+ int prof_lev;
+ int horizontal_size_extension, vertical_size_extension;
+ int bit_rate_extension, vbv_buffer_size_extension, low_delay;
+ int frame_rate_extension_n, frame_rate_extension_d;
+ int pos = 0;
+
+ video->mpeg2 = 1;
+ video->scalable_mode = SC_NONE; /* unless overwritten by seq. scal. ext. */
+ prof_lev = mpeg3bits_getbyte_noptr(video->vstream);
+ video->prog_seq = mpeg3bits_getbit_noptr(video->vstream);
+ video->chroma_format = mpeg3bits_getbits(video->vstream, 2);
+ horizontal_size_extension = mpeg3bits_getbits(video->vstream, 2);
+ vertical_size_extension = mpeg3bits_getbits(video->vstream, 2);
+ bit_rate_extension = mpeg3bits_getbits(video->vstream, 12);
+ mpeg3bits_getbit_noptr(video->vstream);
+ vbv_buffer_size_extension = mpeg3bits_getbyte_noptr(video->vstream);
+ low_delay = mpeg3bits_getbit_noptr(video->vstream);
+ frame_rate_extension_n = mpeg3bits_getbits(video->vstream, 2);
+ frame_rate_extension_d = mpeg3bits_getbits(video->vstream, 5);
+ video->horizontal_size = (horizontal_size_extension << 12) | (video->horizontal_size & 0x0fff);
+ video->vertical_size = (vertical_size_extension << 12) | (video->vertical_size & 0x0fff);
+}
+
+
+/* decode sequence display extension */
+
+int mpeg3video_sequence_display_extension(mpeg3video_t *video)
+{
+ int colour_primaries = 0, transfer_characteristics = 0;
+ int display_horizontal_size, display_vertical_size;
+ int pos = 0;
+ int video_format = mpeg3bits_getbits(video->vstream, 3);
+ int colour_description = mpeg3bits_getbit_noptr(video->vstream);
+
+ if(colour_description)
+ {
+ colour_primaries = mpeg3bits_getbyte_noptr(video->vstream);
+ transfer_characteristics = mpeg3bits_getbyte_noptr(video->vstream);
+ video->matrix_coefficients = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+
+ display_horizontal_size = mpeg3bits_getbits(video->vstream, 14);
+ mpeg3bits_getbit_noptr(video->vstream);
+ display_vertical_size = mpeg3bits_getbits(video->vstream, 14);
+}
+
+
+/* decode quant matrix entension */
+
+int mpeg3video_quant_matrix_extension(mpeg3video_t *video)
+{
+ int i;
+ int load_intra_quantiser_matrix, load_non_intra_quantiser_matrix;
+ int load_chroma_intra_quantiser_matrix;
+ int load_chroma_non_intra_quantiser_matrix;
+ int pos = 0;
+
+ if((load_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0)
+ {
+ for(i = 0; i < 64; i++)
+ {
+ video->chroma_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]]
+ = video->intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]]
+ = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+ }
+
+ if((load_non_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0)
+ {
+ for (i = 0; i < 64; i++)
+ {
+ video->chroma_non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]]
+ = video->non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]]
+ = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+ }
+
+ if((load_chroma_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0)
+ {
+ for(i = 0; i < 64; i++)
+ video->chroma_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+
+ if((load_chroma_non_intra_quantiser_matrix = mpeg3bits_getbit_noptr(video->vstream)) != 0)
+ {
+ for(i = 0; i < 64; i++)
+ video->chroma_non_intra_quantizer_matrix[video->mpeg3_zigzag_scan_table[i]] = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+}
+
+
+/* decode sequence scalable extension */
+
+int mpeg3video_sequence_scalable_extension(mpeg3video_t *video)
+{
+ int layer_id;
+
+ video->scalable_mode = mpeg3bits_getbits(video->vstream, 2) + 1; /* add 1 to make SC_DP != SC_NONE */
+ layer_id = mpeg3bits_getbits(video->vstream, 4);
+
+ if(video->scalable_mode == SC_SPAT)
+ {
+ video->llw = mpeg3bits_getbits(video->vstream, 14); /* lower_layer_prediction_horizontal_size */
+ mpeg3bits_getbit_noptr(video->vstream);
+ video->llh = mpeg3bits_getbits(video->vstream, 14); /* lower_layer_prediction_vertical_size */
+ video->hm = mpeg3bits_getbits(video->vstream, 5);
+ video->hn = mpeg3bits_getbits(video->vstream, 5);
+ video->vm = mpeg3bits_getbits(video->vstream, 5);
+ video->vn = mpeg3bits_getbits(video->vstream, 5);
+ }
+
+ if(video->scalable_mode == SC_TEMP)
+ fprintf(stderr, "mpeg3video_sequence_scalable_extension: temporal scalability not implemented\n");
+}
+
+
+/* decode picture display extension */
+
+int mpeg3video_picture_display_extension(mpeg3video_t *video)
+{
+ int n, i;
+ short frame_centre_horizontal_offset[3];
+ short frame_centre_vertical_offset[3];
+
+ if(video->prog_seq || video->pict_struct != FRAME_PICTURE)
+ n = 1;
+ else
+ n = video->repeatfirst ? 3 : 2;
+
+ for(i = 0; i < n; i++)
+ {
+ frame_centre_horizontal_offset[i] = (short)mpeg3bits_getbits(video->vstream, 16);
+ mpeg3bits_getbit_noptr(video->vstream);
+ frame_centre_vertical_offset[i] = (short)mpeg3bits_getbits(video->vstream, 16);
+ mpeg3bits_getbit_noptr(video->vstream);
+ }
+}
+
+
+/* decode picture coding extension */
+
+int mpeg3video_picture_coding_extension(mpeg3video_t *video)
+{
+ int chroma_420_type, composite_display_flag;
+ int v_axis = 0, field_sequence = 0, sub_carrier = 0, burst_amplitude = 0, sub_carrier_phase = 0;
+
+ video->h_forw_r_size = mpeg3bits_getbits(video->vstream, 4) - 1;
+ video->v_forw_r_size = mpeg3bits_getbits(video->vstream, 4) - 1;
+ video->h_back_r_size = mpeg3bits_getbits(video->vstream, 4) - 1;
+ video->v_back_r_size = mpeg3bits_getbits(video->vstream, 4) - 1;
+ video->dc_prec = mpeg3bits_getbits(video->vstream, 2);
+ video->pict_struct = mpeg3bits_getbits(video->vstream, 2);
+ video->topfirst = mpeg3bits_getbit_noptr(video->vstream);
+ video->frame_pred_dct = mpeg3bits_getbit_noptr(video->vstream);
+ video->conceal_mv = mpeg3bits_getbit_noptr(video->vstream);
+ video->qscale_type = mpeg3bits_getbit_noptr(video->vstream);
+ video->intravlc = mpeg3bits_getbit_noptr(video->vstream);
+ video->altscan = mpeg3bits_getbit_noptr(video->vstream);
+ video->repeatfirst = mpeg3bits_getbit_noptr(video->vstream);
+ chroma_420_type = mpeg3bits_getbit_noptr(video->vstream);
+ video->prog_frame = mpeg3bits_getbit_noptr(video->vstream);
+
+ if(video->repeat_count > 100)
+ video->repeat_count = 0;
+ video->repeat_count += 100;
+
+ video->current_repeat = 0;
+
+ if(video->prog_seq)
+ {
+ if(video->repeatfirst)
+ {
+ if(video->topfirst)
+ video->repeat_count += 200;
+ else
+ video->repeat_count += 100;
+ }
+ }
+ else
+ if(video->prog_frame)
+ {
+ if(video->repeatfirst)
+ {
+ video->repeat_count += 50;
+ }
+ }
+
+/*printf("mpeg3video_picture_coding_extension %d\n", video->repeat_count); */
+ composite_display_flag = mpeg3bits_getbit_noptr(video->vstream);
+
+ if(composite_display_flag)
+ {
+ v_axis = mpeg3bits_getbit_noptr(video->vstream);
+ field_sequence = mpeg3bits_getbits(video->vstream, 3);
+ sub_carrier = mpeg3bits_getbit_noptr(video->vstream);
+ burst_amplitude = mpeg3bits_getbits(video->vstream, 7);
+ sub_carrier_phase = mpeg3bits_getbyte_noptr(video->vstream);
+ }
+}
+
+
+/* decode picture spatial scalable extension */
+
+int mpeg3video_picture_spatial_scalable_extension(mpeg3video_t *video)
+{
+ video->pict_scal = 1; /* use spatial scalability in this picture */
+
+ video->lltempref = mpeg3bits_getbits(video->vstream, 10);
+ mpeg3bits_getbit_noptr(video->vstream);
+ video->llx0 = mpeg3bits_getbits(video->vstream, 15);
+ if(video->llx0 >= 16384) video->llx0 -= 32768;
+ mpeg3bits_getbit_noptr(video->vstream);
+ video->lly0 = mpeg3bits_getbits(video->vstream, 15);
+ if(video->lly0 >= 16384) video->lly0 -= 32768;
+ video->stwc_table_index = mpeg3bits_getbits(video->vstream, 2);
+ video->llprog_frame = mpeg3bits_getbit_noptr(video->vstream);
+ video->llfieldsel = mpeg3bits_getbit_noptr(video->vstream);
+}
+
+
+/* decode picture temporal scalable extension
+ *
+ * not implemented
+ *
+ */
+
+int mpeg3video_picture_temporal_scalable_extension(mpeg3video_t *video)
+{
+ fprintf(stderr, "mpeg3video_picture_temporal_scalable_extension: temporal scalability not supported\n");
+}
+
+
+/* decode extension and user data */
+
+int mpeg3video_ext_user_data(mpeg3video_t *video)
+{
+ int code = mpeg3bits_next_startcode(video->vstream);
+
+
+ while(code == MPEG3_EXT_START_CODE || code == MPEG3_USER_START_CODE &&
+ !mpeg3bits_eof(video->vstream))
+ {
+ mpeg3bits_refill(video->vstream);
+
+ if(code == MPEG3_EXT_START_CODE)
+ {
+ int ext_id = mpeg3bits_getbits(video->vstream, 4);
+ switch(ext_id)
+ {
+ case SEQ_ID:
+ mpeg3video_sequence_extension(video);
+ break;
+ case DISP_ID:
+ mpeg3video_sequence_display_extension(video);
+ break;
+ case QUANT_ID:
+ mpeg3video_quant_matrix_extension(video);
+ break;
+ case SEQSCAL_ID:
+ mpeg3video_sequence_scalable_extension(video);
+ break;
+ case PANSCAN_ID:
+ mpeg3video_picture_display_extension(video);
+ break;
+ case CODING_ID:
+ mpeg3video_picture_coding_extension(video);
+ break;
+ case SPATSCAL_ID:
+ mpeg3video_picture_spatial_scalable_extension(video);
+ break;
+ case TEMPSCAL_ID:
+ mpeg3video_picture_temporal_scalable_extension(video);
+ break;
+ default:
+ fprintf(stderr,"mpeg3video_ext_user_data: reserved extension start code ID %d\n", ext_id);
+ break;
+ }
+ }
+ code = mpeg3bits_next_startcode(video->vstream);
+ }
+}
+
+
+/* decode group of pictures header */
+
+int mpeg3video_getgophdr(mpeg3video_t *video)
+{
+ int drop_flag, closed_gop, broken_link;
+
+ drop_flag = mpeg3bits_getbit_noptr(video->vstream);
+ video->gop_timecode.hour = mpeg3bits_getbits(video->vstream, 5);
+ video->gop_timecode.minute = mpeg3bits_getbits(video->vstream, 6);
+ mpeg3bits_getbit_noptr(video->vstream);
+ video->gop_timecode.second = mpeg3bits_getbits(video->vstream, 6);
+ video->gop_timecode.frame = mpeg3bits_getbits(video->vstream, 6);
+ closed_gop = mpeg3bits_getbit_noptr(video->vstream);
+ broken_link = mpeg3bits_getbit_noptr(video->vstream);
+
+/*
+ * printf("%d:%d:%d:%d %d %d %d\n", video->gop_timecode.hour, video->gop_timecode.minute, video->gop_timecode.second, video->gop_timecode.frame,
+ * drop_flag, closed_gop, broken_link);
+ */
+ return mpeg3bits_error(video->vstream);
+}
+
+/* decode picture header */
+
+int mpeg3video_getpicturehdr(mpeg3video_t *video)
+{
+ int temp_ref, vbv_delay;
+
+ video->pict_scal = 0; /* unless overwritten by pict. spat. scal. ext. */
+
+ temp_ref = mpeg3bits_getbits(video->vstream, 10);
+ video->pict_type = mpeg3bits_getbits(video->vstream, 3);
+ vbv_delay = mpeg3bits_getbits(video->vstream, 16);
+
+ if(video->pict_type == P_TYPE || video->pict_type == B_TYPE)
+ {
+ video->full_forw = mpeg3bits_getbit_noptr(video->vstream);
+ video->forw_r_size = mpeg3bits_getbits(video->vstream, 3) - 1;
+ }
+
+ if(video->pict_type == B_TYPE)
+ {
+ video->full_back = mpeg3bits_getbit_noptr(video->vstream);
+ video->back_r_size = mpeg3bits_getbits(video->vstream, 3) - 1;
+ }
+
+/* get extra bit picture */
+ while(mpeg3bits_getbit_noptr(video->vstream) &&
+ !mpeg3bits_eof(video->vstream)) mpeg3bits_getbyte_noptr(video->vstream);
+ return 0;
+}
+
+
+int mpeg3video_get_header(mpeg3video_t *video, int dont_repeat)
+{
+ unsigned int code;
+
+/* a sequence header should be found before returning from `getheader' the */
+/* first time (this is to set horizontal/vertical size properly) */
+
+/* Repeat the frame until it's less than 1 count from repeat_count */
+ if(video->repeat_count - video->current_repeat >= 100 && !dont_repeat)
+ {
+ return 0;
+ }
+
+ if(dont_repeat)
+ {
+ video->repeat_count = 0;
+ video->current_repeat = 0;
+ }
+ else
+ video->repeat_count -= video->current_repeat;
+
+ while(1)
+ {
+/* look for startcode */
+ code = mpeg3bits_next_startcode(video->vstream);
+ if(mpeg3bits_eof(video->vstream)) return 1;
+ if(code != MPEG3_SEQUENCE_END_CODE) mpeg3bits_refill(video->vstream);
+
+ switch(code)
+ {
+ case MPEG3_SEQUENCE_START_CODE:
+ video->found_seqhdr = 1;
+ mpeg3video_getseqhdr(video);
+ mpeg3video_ext_user_data(video);
+ break;
+
+ case MPEG3_GOP_START_CODE:
+ mpeg3video_getgophdr(video);
+ mpeg3video_ext_user_data(video);
+ break;
+
+ case MPEG3_PICTURE_START_CODE:
+ mpeg3video_getpicturehdr(video);
+ mpeg3video_ext_user_data(video);
+ if(video->found_seqhdr) return 0; /* Exit here */
+ break;
+
+ case MPEG3_SEQUENCE_END_CODE:
+// Continue until the end
+ mpeg3bits_refill(video->vstream);
+ break;
+
+ default:
+ break;
+ }
+ }
+ return 1; /* Shouldn't be reached. */
+}
+
+int mpeg3video_ext_bit_info(mpeg3_slice_buffer_t *slice_buffer)
+{
+ while(mpeg3slice_getbit(slice_buffer)) mpeg3slice_getbyte(slice_buffer);
+ return 0;
+}
+
+/* decode slice header */
+int mpeg3video_getslicehdr(mpeg3_slice_t *slice, mpeg3video_t *video)
+{
+ int slice_vertical_position_extension, intra_slice;
+ int qs;
+
+ slice_vertical_position_extension = (video->mpeg2 && video->vertical_size > 2800) ?
+ mpeg3slice_getbits(slice->slice_buffer, 3) : 0;
+
+ if(video->scalable_mode == SC_DP) slice->pri_brk = mpeg3slice_getbits(slice->slice_buffer, 7);
+
+ qs = mpeg3slice_getbits(slice->slice_buffer, 5);
+ slice->quant_scale = video->mpeg2 ? (video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1)) : qs;
+
+ if(mpeg3slice_getbit(slice->slice_buffer))
+ {
+ intra_slice = mpeg3slice_getbit(slice->slice_buffer);
+ mpeg3slice_getbits(slice->slice_buffer, 7);
+ mpeg3video_ext_bit_info(slice->slice_buffer);
+ }
+ else
+ intra_slice = 0;
+
+ return slice_vertical_position_extension;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/video/idct.c b/core/multimedia/opieplayer/libmpeg3/video/idct.c
new file mode 100644
index 0000000..c79f90a
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/idct.c
@@ -0,0 +1,160 @@
+#include "idct.h"
+#include <stdlib.h>
+
+/**********************************************************/
+/* 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 */
+
+#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) */
+
+/* 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)
+ */
+
+int mpeg3video_idctrow(short *blk)
+{
+ int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+ /* shortcut */
+ if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) |
+ (x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3])))
+ {
+ blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3;
+ return 0;
+ }
+
+ x0 = (blk[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 */
+ blk[0] = (x7+x1)>>8;
+ blk[1] = (x3+x2)>>8;
+ blk[2] = (x0+x4)>>8;
+ blk[3] = (x8+x6)>>8;
+ blk[4] = (x8-x6)>>8;
+ blk[5] = (x0-x4)>>8;
+ blk[6] = (x3-x2)>>8;
+ blk[7] = (x7-x1)>>8;
+
+ return 1;
+}
+
+/* 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)
+ */
+
+int mpeg3video_idctcol(short *blk)
+{
+ int x0, x1, x2, x3, x4, x5, x6, x7, x8;
+
+ /* shortcut */
+ if (!((x1 = (blk[8 * 4]<<8)) | (x2 = blk[8 * 6]) | (x3 = blk[8 * 2]) |
+ (x4 = blk[8*1]) | (x5 = blk[8 * 7]) | (x6 = blk[8 * 5]) | (x7 = blk[8 * 3]))){
+ blk[8*0]=blk[8*1]=blk[8 * 2]=blk[8 * 3]=blk[8 * 4]=blk[8 * 5]=blk[8 * 6]=blk[8 * 7]=
+ (blk[8*0]+32)>>6;
+ return 0;
+ }
+
+ x0 = (blk[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 */
+ blk[8 * 0] = (x7 + x1) >> 14;
+ blk[8 * 1] = (x3 + x2) >> 14;
+ blk[8 * 2] = (x0 + x4) >> 14;
+ blk[8 * 3] = (x8 + x6) >> 14;
+ blk[8 * 4] = (x8 - x6) >> 14;
+ blk[8 * 5] = (x0 - x4) >> 14;
+ blk[8 * 6] = (x3 - x2) >> 14;
+ blk[8 * 7] = (x7 - x1) >> 14;
+
+ return 1;
+}
+
+
+/* two dimensional inverse discrete cosine transform */
+void mpeg3video_idct_conversion(short* block)
+{
+ int i;
+ for(i = 0; i < 8; i++) mpeg3video_idctrow(block + 8 * i);
+ for(i = 0; i < 8; i++) mpeg3video_idctcol(block + i);
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/video/idct.h b/core/multimedia/opieplayer/libmpeg3/video/idct.h
new file mode 100644
index 0000000..f0aa1d8
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/idct.h
@@ -0,0 +1,24 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef IDCT_H
+#define IDCT_H
+
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/video/layerdata.h b/core/multimedia/opieplayer/libmpeg3/video/layerdata.h
new file mode 100644
index 0000000..3ef0f90
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/layerdata.h
@@ -0,0 +1,35 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef LAYERDATA_H
+#define LAYERDATA_H
+
+typedef struct
+{
+/* sequence header */
+ int intra_quantizer_matrix[64], non_intra_quantizer_matrix[64];
+ int chroma_intra_quantizer_matrix[64], chroma_non_intra_quantizer_matrix[64];
+ int mpeg2;
+ int qscale_type, altscan; /* picture coding extension */
+ int pict_scal; /* picture spatial scalable extension */
+ int scalable_mode; /* sequence scalable extension */
+} mpeg3_layerdata_t;
+
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c b/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c
new file mode 100644
index 0000000..11e17c1
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/macroblocks.c
@@ -0,0 +1,338 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include "slice.h"
+#include "vlc.h"
+
+#include <stdio.h>
+
+int mpeg3video_get_macroblock_address(mpeg3_slice_t *slice)
+{
+ int code, val = 0;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+ while((code = mpeg3slice_showbits(slice_buffer, 11)) < 24)
+ {
+/* Is not macroblock_stuffing */
+ if(code != 15)
+ {
+/* Is macroblock_escape */
+ if(code == 8)
+ {
+ val += 33;
+ }
+ else
+ {
+/* fprintf(stderr, "mpeg3video_get_macroblock_address: invalid macroblock_address_increment code\n"); */
+ slice->fault = 1;
+ return 1;
+ }
+ }
+
+ mpeg3slice_flushbits(slice_buffer, 11);
+ }
+
+ if(code >= 1024)
+ {
+ mpeg3slice_flushbit(slice_buffer);
+ return val + 1;
+ }
+
+ if(code >= 128)
+ {
+ code >>= 6;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab1[code].len);
+ return val + mpeg3_MBAtab1[code].val;
+ }
+
+ code -= 24;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_MBAtab2[code].len);
+
+ return val + mpeg3_MBAtab2[code].val;
+}
+
+/* macroblock_type for pictures with spatial scalability */
+
+static inline int mpeg3video_getsp_imb_type(mpeg3_slice_t *slice)
+{
+// ### This looks wrong.
+// slice_buffer is used without being initialised and slice is not used
+// mpeg3_slice_buffer_t *slice_buffer = slice_buffer;
+// I think this would make more sense and might be what is intended
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ unsigned int code = mpeg3slice_showbits(slice_buffer, 4);
+ if(!code)
+ {
+/* fprintf(stderr,"mpeg3video_getsp_imb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_spIMBtab[code].len);
+ return mpeg3_spIMBtab[code].val;
+}
+
+static inline int mpeg3video_getsp_pmb_type(mpeg3_slice_t *slice)
+{
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ int code = mpeg3slice_showbits(slice_buffer, 7);
+ if(code < 2)
+ {
+/* fprintf(stderr,"mpeg3video_getsp_pmb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ if(code >= 16)
+ {
+ code >>= 3;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab0[code].len);
+
+ return mpeg3_spPMBtab0[code].val;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_spPMBtab1[code].len);
+ return mpeg3_spPMBtab1[code].val;
+}
+
+static inline int mpeg3video_getsp_bmb_type(mpeg3_slice_t *slice)
+{
+ mpeg3_VLCtab_t *p;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ int code = mpeg3slice_showbits9(slice_buffer);
+
+ if(code >= 64)
+ p = &mpeg3_spBMBtab0[(code >> 5) - 2];
+ else
+ if(code >= 16)
+ p = &mpeg3_spBMBtab1[(code >> 2) - 4];
+ else
+ if(code >= 8)
+ p = &mpeg3_spBMBtab2[code - 8];
+ else
+ {
+/* fprintf(stderr,"mpeg3video_getsp_bmb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, p->len);
+ return p->val;
+}
+
+static inline int mpeg3video_get_imb_type(mpeg3_slice_t *slice)
+{
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ if(mpeg3slice_getbit(slice_buffer))
+ {
+ return 1;
+ }
+
+ if(!mpeg3slice_getbit(slice_buffer))
+ {
+/* fprintf(stderr,"mpeg3video_get_imb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ }
+
+ return 17;
+}
+
+static inline int mpeg3video_get_pmb_type(mpeg3_slice_t *slice)
+{
+ int code;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+ if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8)
+ {
+ code >>= 3;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab0[code].len);
+ return mpeg3_PMBtab0[code].val;
+ }
+
+ if(code == 0)
+ {
+/* fprintf(stderr,"mpeg3video_get_pmb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_PMBtab1[code].len);
+ return mpeg3_PMBtab1[code].val;
+}
+
+static inline int mpeg3video_get_bmb_type(mpeg3_slice_t *slice)
+{
+ int code;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+ if((code = mpeg3slice_showbits(slice_buffer, 6)) >= 8)
+ {
+ code >>= 2;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab0[code].len);
+ return mpeg3_BMBtab0[code].val;
+ }
+
+ if(code == 0)
+ {
+/* fprintf(stderr,"mpeg3video_get_bmb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_BMBtab1[code].len);
+
+ return mpeg3_BMBtab1[code].val;
+}
+
+static inline int mpeg3video_get_dmb_type(mpeg3_slice_t *slice)
+{
+ if(!mpeg3slice_getbit(slice->slice_buffer))
+ {
+/* fprintf(stderr,"mpeg3video_get_dmb_type: invalid macroblock_type code\n"); */
+ slice->fault=1;
+ }
+
+ return 1;
+}
+
+
+static inline int mpeg3video_get_snrmb_type(mpeg3_slice_t *slice)
+{
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ int code = mpeg3slice_showbits(slice_buffer, 3);
+
+ if(code == 0)
+ {
+/* fprintf(stderr,"mpeg3video_get_snrmb_type: invalid macroblock_type code\n"); */
+ slice->fault = 1;
+ return 0;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_SNRMBtab[code].len);
+ return mpeg3_SNRMBtab[code].val;
+}
+
+int mpeg3video_get_mb_type(mpeg3_slice_t *slice, mpeg3video_t *video)
+{
+ if(video->scalable_mode == SC_SNR)
+ {
+ return mpeg3video_get_snrmb_type(slice);
+ }
+ else
+ {
+ switch(video->pict_type)
+ {
+ case I_TYPE: return video->pict_scal ? mpeg3video_getsp_imb_type(slice) : mpeg3video_get_imb_type(slice);
+ case P_TYPE: return video->pict_scal ? mpeg3video_getsp_pmb_type(slice) : mpeg3video_get_pmb_type(slice);
+ case B_TYPE: return video->pict_scal ? mpeg3video_getsp_bmb_type(slice) : mpeg3video_get_bmb_type(slice);
+ case D_TYPE: return mpeg3video_get_dmb_type(slice);
+ default:
+ /*fprintf(stderr, "mpeg3video_getmbtype: unknown coding type\n"); */
+ break;
+/* MPEG-1 only, not implemented */
+ }
+ }
+
+ return 0;
+}
+
+int mpeg3video_macroblock_modes(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int *pmb_type,
+ int *pstwtype,
+ int *pstwclass,
+ int *pmotion_type,
+ int *pmv_count,
+ int *pmv_format,
+ int *pdmv,
+ int *pmvscale,
+ int *pdct_type)
+{
+ int mb_type;
+ int stwtype, stwcode, stwclass;
+ int motion_type = 0, mv_count, mv_format, dmv, mvscale;
+ int dct_type;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ static unsigned char stwc_table[3][4]
+ = { {6,3,7,4}, {2,1,5,4}, {2,5,7,4} };
+ static unsigned char stwclass_table[9]
+ = {0, 1, 2, 1, 1, 2, 3, 3, 4};
+
+/* get macroblock_type */
+ mb_type = mpeg3video_get_mb_type(slice, video);
+
+ if(slice->fault) return 1;
+
+/* get spatial_temporal_weight_code */
+ if(mb_type & MB_WEIGHT)
+ {
+ if(video->stwc_table_index == 0)
+ stwtype = 4;
+ else
+ {
+ stwcode = mpeg3slice_getbits2(slice_buffer);
+ stwtype = stwc_table[video->stwc_table_index - 1][stwcode];
+ }
+ }
+ else
+ stwtype = (mb_type & MB_CLASS4) ? 8 : 0;
+
+/* derive spatial_temporal_weight_class (Table 7-18) */
+ stwclass = stwclass_table[stwtype];
+
+/* get frame/field motion type */
+ if(mb_type & (MB_FORWARD | MB_BACKWARD))
+ {
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+/* frame_motion_type */
+ motion_type = video->frame_pred_dct ? MC_FRAME : mpeg3slice_getbits2(slice_buffer);
+ }
+ else
+ {
+/* field_motion_type */
+ motion_type = mpeg3slice_getbits2(slice_buffer);
+ }
+ }
+ else
+ if((mb_type & MB_INTRA) && video->conceal_mv)
+ {
+/* concealment motion vectors */
+ motion_type = (video->pict_struct == FRAME_PICTURE) ? MC_FRAME : MC_FIELD;
+ }
+
+/* derive mv_count, mv_format and dmv, (table 6-17, 6-18) */
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+ mv_count = (motion_type == MC_FIELD && stwclass < 2) ? 2 : 1;
+ mv_format = (motion_type == MC_FRAME) ? MV_FRAME : MV_FIELD;
+ }
+ else
+ {
+ mv_count = (motion_type == MC_16X8) ? 2 : 1;
+ mv_format = MV_FIELD;
+ }
+
+ dmv = (motion_type == MC_DMV); /* dual prime */
+
+/* field mv predictions in frame pictures have to be scaled */
+ mvscale = ((mv_format == MV_FIELD) && (video->pict_struct == FRAME_PICTURE));
+
+/* get dct_type (frame DCT / field DCT) */
+ dct_type = (video->pict_struct == FRAME_PICTURE) &&
+ (!video->frame_pred_dct) &&
+ (mb_type & (MB_PATTERN | MB_INTRA)) ?
+ mpeg3slice_getbit(slice_buffer) : 0;
+
+/* return values */
+ *pmb_type = mb_type;
+ *pstwtype = stwtype;
+ *pstwclass = stwclass;
+ *pmotion_type = motion_type;
+ *pmv_count = mv_count;
+ *pmv_format = mv_format;
+ *pdmv = dmv;
+ *pmvscale = mvscale;
+ *pdct_type = dct_type;
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/video/mmxidct.S b/core/multimedia/opieplayer/libmpeg3/video/mmxidct.S
new file mode 100644
index 0000000..9c3bebe
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/mmxidct.S
@@ -0,0 +1,675 @@
+/*
+ * the input data is tranposed and each 16 bit element in the 8x8 matrix
+ * is left aligned:
+ * for example in 11...1110000 format
+ * If the iDCT is of I macroblock then 0.5 needs to be added to the;DC Component
+ * (element[0][0] of the matrix)
+ */
+
+/* extrn re_matrix */
+
+/* constants */
+
+.data
+ .align 16
+ .type preSC, @object
+preSC: .short 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520
+ .short 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270
+ .short 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906
+ .short 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315
+ .short 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520
+ .short 12873, 17855, 16819, 15137, 25746, 20228, 13933, 7103
+ .short 17734, 24598, 23170, 20853, 17734, 13933, 9597, 4892
+ .short 18081, 25080, 23624, 21261, 18081, 14206, 9785, 4988
+ .size preSC, 128
+ .align 8
+ .type x0005000200010001, @object
+ .size x0005000200010001, 8
+x0005000200010001:
+ .long 0x00010001, 0x00050002
+ .align 8
+ .type x0040000000000000, @object
+ .size x0040000000000000, 8
+x0040000000000000:
+ .long 0, 0x00400000
+ .align 8
+ .type x5a825a825a825a82, @object
+ .size x5a825a825a825a82, 8
+x5a825a825a825a82:
+ .long 0x5a825a82, 0x5a825a82
+ .align 8
+ .type x539f539f539f539f, @object
+ .size x539f539f539f539f, 8
+x539f539f539f539f:
+ .long 0x539f539f, 0x539f539f
+ .align 8
+ .type x4546454645464546, @object
+ .size x4546454645464546, 8
+x4546454645464546:
+ .long 0x45464546, 0x45464546
+ .align 8
+ .type x61f861f861f861f8, @object
+ .size x61f861f861f861f8, 8
+x61f861f861f861f8:
+ .long 0x61f861f8, 0x61f861f8
+/* Static variables */
+ .align 8
+ .type x0, @object
+ .size x0, 8
+x0:
+ .long 0, 0
+/* Procedure */
+
+
+ .align 8
+.text
+ .align 4
+.globl IDCT_mmx
+ .type IDCT_mmx, @function
+IDCT_mmx:
+ pushl %ebp
+ movl %esp, %ebp
+ pushl %ebx
+ pushl %ecx
+ pushl %edx
+ pushl %esi
+ pushl %edi
+
+ pushl $0 /* allocate the temp variables */
+ pushl $0
+ pushl $0
+ pushl $0
+ pushl $0
+ pushl $0
+ pushl $0
+ pushl $0
+
+ movl 8(%ebp), %esi /* source matrix */
+ leal preSC, %ecx
+/* column 0: even part
+ * use V4, V12, V0, V8 to produce V22..V25
+ */
+ movq 8*12(%ecx), %mm0 /* maybe the first mul can be done together */
+ /* with the dequantization in iHuff module */
+ pmulhw 8*12(%esi), %mm0 /* V12 */
+ movq 8*4(%ecx), %mm1
+ pmulhw 8*4(%esi), %mm1 /* V4 */
+ movq (%ecx), %mm3
+ psraw $1, %mm0 /* t64=t66 */
+ pmulhw (%esi), %mm3 /* V0 */
+ movq 8*8(%ecx), %mm5 /* duplicate V4 */
+ movq %mm1, %mm2 /* added 11/1/96 */
+ pmulhw 8*8(%esi),%mm5 /* V8 */
+ psubsw %mm0, %mm1 /* V16 */
+ pmulhw x5a825a825a825a82, %mm1 /* 23170 ->V18 */
+ paddsw %mm0, %mm2 /* V17 */
+ movq %mm2, %mm0 /* duplicate V17 */
+ psraw $1, %mm2 /* t75=t82 */
+ psraw $2, %mm0 /* t72 */
+ movq %mm3, %mm4 /* duplicate V0 */
+ paddsw %mm5, %mm3 /* V19 */
+ psubsw %mm5, %mm4 /* V20 ;mm5 free */
+/* moved from the block below */
+ movq 8*10(%ecx), %mm7
+ psraw $1, %mm3 /* t74=t81 */
+ movq %mm3, %mm6 /* duplicate t74=t81 */
+ psraw $2, %mm4 /* t77=t79 */
+ psubsw %mm0, %mm1 /* V21 ; mm0 free */
+ paddsw %mm2, %mm3 /* V22 */
+ movq %mm1, %mm5 /* duplicate V21 */
+ paddsw %mm4, %mm1 /* V23 */
+ movq %mm3, 8*4(%esi) /* V22 */
+ psubsw %mm5, %mm4 /* V24; mm5 free */
+ movq %mm1, 8*12(%esi) /* V23 */
+ psubsw %mm2, %mm6 /* V25; mm2 free */
+ movq %mm4, (%esi) /* V24 */
+/* keep mm6 alive all along the next block */
+ /* movq %mm6, 8*8(%esi) V25 */
+/* column 0: odd part
+ * use V2, V6, V10, V14 to produce V31, V39, V40, V41
+ */
+/* moved above: movq 8*10(%ecx), %mm7 */
+
+ pmulhw 8*10(%esi), %mm7 /* V10 */
+ movq 8*6(%ecx), %mm0
+ pmulhw 8*6(%esi), %mm0 /* V6 */
+ movq 8*2(%ecx), %mm5
+ movq %mm7, %mm3 /* duplicate V10 */
+ pmulhw 8*2(%esi), %mm5 /* V2 */
+ movq 8*14(%ecx), %mm4
+ psubsw %mm0, %mm7 /* V26 */
+ pmulhw 8*14(%esi), %mm4 /* V14 */
+ paddsw %mm0, %mm3 /* V29 ; free mm0 */
+ movq %mm7, %mm1 /* duplicate V26 */
+ psraw $1, %mm3 /* t91=t94 */
+ pmulhw x539f539f539f539f,%mm7 /* V33 */
+ psraw $1, %mm1 /* t96 */
+ movq %mm5, %mm0 /* duplicate V2 */
+ psraw $2, %mm4 /* t85=t87 */
+ paddsw %mm4,%mm5 /* V27 */
+ psubsw %mm4, %mm0 /* V28 ; free mm4 */
+ movq %mm0, %mm2 /* duplicate V28 */
+ psraw $1, %mm5 /* t90=t93 */
+ pmulhw x4546454645464546,%mm0 /* V35 */
+ psraw $1, %mm2 /* t97 */
+ movq %mm5, %mm4 /* duplicate t90=t93 */
+ psubsw %mm2, %mm1 /* V32 ; free mm2 */
+ pmulhw x61f861f861f861f8,%mm1 /* V36 */
+ psllw $1, %mm7 /* t107 */
+ paddsw %mm3, %mm5 /* V31 */
+ psubsw %mm3, %mm4 /* V30 ; free mm3 */
+ pmulhw x5a825a825a825a82,%mm4 /* V34 */
+ nop
+ psubsw %mm1, %mm0 /* V38 */
+ psubsw %mm7, %mm1 /* V37 ; free mm7 */
+ psllw $1, %mm1 /* t114 */
+/* move from the next block */
+ movq %mm6, %mm3 /* duplicate V25 */
+/* move from the next block */
+ movq 8*4(%esi), %mm7 /* V22 */
+ psllw $1, %mm0 /* t110 */
+ psubsw %mm5, %mm0 /* V39 (mm5 needed for next block) */
+ psllw $2, %mm4 /* t112 */
+/* moved from the next block */
+ movq 8*12(%esi), %mm2 /* V23 */
+ psubsw %mm0, %mm4 /* V40 */
+ paddsw %mm4, %mm1 /* V41; free mm0 */
+/* moved from the next block */
+ psllw $1, %mm2 /* t117=t125 */
+/* column 0: output butterfly */
+/* moved above:
+ * movq %mm6, %mm3 duplicate V25
+ * movq 8*4(%esi), %mm7 V22
+ * movq 8*12(%esi), %mm2 V23
+ * psllw $1, %mm2 t117=t125
+ */
+ psubsw %mm1, %mm6 /* tm6 */
+ paddsw %mm1, %mm3 /* tm8; free mm1 */
+ movq %mm7, %mm1 /* duplicate V22 */
+ paddsw %mm5, %mm7 /* tm0 */
+ movq %mm3, 8*8(%esi) /* tm8; free mm3 */
+ psubsw %mm5, %mm1 /* tm14; free mm5 */
+ movq %mm6, 8*6(%esi) /* tm6; free mm6 */
+ movq %mm2, %mm3 /* duplicate t117=t125 */
+ movq (%esi), %mm6 /* V24 */
+ paddsw %mm0, %mm2 /* tm2 */
+ movq %mm7, (%esi) /* tm0; free mm7 */
+ psubsw %mm0, %mm3 /* tm12; free mm0 */
+ movq %mm1, 8*14(%esi) /* tm14; free mm1 */
+ psllw $1, %mm6 /* t119=t123 */
+ movq %mm2, 8*2(%esi) /* tm2; free mm2 */
+ movq %mm6, %mm0 /* duplicate t119=t123 */
+ movq %mm3, 8*12(%esi) /* tm12; free mm3 */
+ paddsw %mm4, %mm6 /* tm4 */
+/* moved from next block */
+ movq 8*5(%ecx), %mm1
+ psubsw %mm4, %mm0 /* tm10; free mm4 */
+/* moved from next block */
+ pmulhw 8*5(%esi), %mm1 /* V5 */
+ movq %mm6, 8*4(%esi) /* tm4; free mm6 */
+ movq %mm0, 8*10(%esi) /* tm10; free mm0 */
+/* column 1: even part
+ * use V5, V13, V1, V9 to produce V56..V59
+ */
+/* moved to prev block:
+ * movq 8*5(%ecx), %mm1
+ * pmulhw 8*5(%esi), %mm1 V5
+ */
+ movq 8*13(%ecx), %mm7
+ psllw $1, %mm1 /* t128=t130 */
+ pmulhw 8*13(%esi), %mm7 /* V13 */
+ movq %mm1, %mm2 /* duplicate t128=t130 */
+ movq 8(%ecx), %mm3
+ pmulhw 8(%esi), %mm3 /* V1 */
+ movq 8*9(%ecx), %mm5
+ psubsw %mm7, %mm1 /* V50 */
+ pmulhw 8*9(%esi), %mm5 /* V9 */
+ paddsw %mm7, %mm2 /* V51 */
+ pmulhw x5a825a825a825a82, %mm1 /* 23170 ->V52 */
+ movq %mm2, %mm6 /* duplicate V51 */
+ psraw $1, %mm2 /* t138=t144 */
+ movq %mm3, %mm4 /* duplicate V1 */
+ psraw $2, %mm6 /* t136 */
+ paddsw %mm5, %mm3 /* V53 */
+ psubsw %mm5, %mm4 /* V54 ;mm5 free */
+ movq %mm3, %mm7 /* duplicate V53 */
+/* moved from next block */
+ movq 8*11(%ecx), %mm0
+ psraw $1, %mm4 /* t140=t142 */
+ psubsw %mm6, %mm1 /* V55 ; mm6 free */
+ paddsw %mm2, %mm3 /* V56 */
+ movq %mm4, %mm5 /* duplicate t140=t142 */
+ paddsw %mm1, %mm4 /* V57 */
+ movq %mm3, 8*5(%esi) /* V56 */
+ psubsw %mm1, %mm5 /* V58; mm1 free */
+ movq %mm4, 8*13(%esi) /* V57 */
+ psubsw %mm2, %mm7 /* V59; mm2 free */
+ movq %mm5, 8*9(%esi) /* V58 */
+/* keep mm7 alive all along the next block
+ * movq %mm7, 8(%esi) V59
+ * moved above
+ * movq 8*11(%ecx), %mm0
+ */
+ pmulhw 8*11(%esi), %mm0 /* V11 */
+ movq 8*7(%ecx), %mm6
+ pmulhw 8*7(%esi), %mm6 /* V7 */
+ movq 8*15(%ecx), %mm4
+ movq %mm0, %mm3 /* duplicate V11 */
+ pmulhw 8*15(%esi), %mm4 /* V15 */
+ movq 8*3(%ecx), %mm5
+ psllw $1, %mm6 /* t146=t152 */
+ pmulhw 8*3(%esi), %mm5 /* V3 */
+ paddsw %mm6, %mm0 /* V63 */
+/* note that V15 computation has a correction step:
+ * this is a 'magic' constant that rebiases the results to be closer to the
+ * expected result. this magic constant can be refined to reduce the error
+ * even more by doing the correction step in a later stage when the number
+ * is actually multiplied by 16
+ */
+ paddw x0005000200010001, %mm4
+ psubsw %mm6, %mm3 /* V60 ; free mm6 */
+ psraw $1, %mm0 /* t154=t156 */
+ movq %mm3, %mm1 /* duplicate V60 */
+ pmulhw x539f539f539f539f, %mm1 /* V67 */
+ movq %mm5, %mm6 /* duplicate V3 */
+ psraw $2, %mm4 /* t148=t150 */
+ paddsw %mm4, %mm5 /* V61 */
+ psubsw %mm4, %mm6 /* V62 ; free mm4 */
+ movq %mm5, %mm4 /* duplicate V61 */
+ psllw $1, %mm1 /* t169 */
+ paddsw %mm0, %mm5 /* V65 -> result */
+ psubsw %mm0, %mm4 /* V64 ; free mm0 */
+ pmulhw x5a825a825a825a82, %mm4 /* V68 */
+ psraw $1, %mm3 /* t158 */
+ psubsw %mm6, %mm3 /* V66 */
+ movq %mm5, %mm2 /* duplicate V65 */
+ pmulhw x61f861f861f861f8, %mm3 /* V70 */
+ psllw $1, %mm6 /* t165 */
+ pmulhw x4546454645464546, %mm6 /* V69 */
+ psraw $1, %mm2 /* t172 */
+/* moved from next block */
+ movq 8*5(%esi), %mm0 /* V56 */
+ psllw $1, %mm4 /* t174 */
+/* moved from next block */
+ psraw $1, %mm0 /* t177=t188 */
+ nop
+ psubsw %mm3, %mm6 /* V72 */
+ psubsw %mm1, %mm3 /* V71 ; free mm1 */
+ psubsw %mm2, %mm6 /* V73 ; free mm2 */
+/* moved from next block */
+ psraw $1, %mm5 /* t178=t189 */
+ psubsw %mm6, %mm4 /* V74 */
+/* moved from next block */
+ movq %mm0, %mm1 /* duplicate t177=t188 */
+ paddsw %mm4, %mm3 /* V75 */
+/* moved from next block */
+ paddsw %mm5, %mm0 /* tm1 */
+/* location
+ * 5 - V56
+ * 13 - V57
+ * 9 - V58
+ * X - V59, mm7
+ * X - V65, mm5
+ * X - V73, mm6
+ * X - V74, mm4
+ * X - V75, mm3
+ * free mm0, mm1 & mm2
+ * moved above
+ * movq 8*5(%esi), %mm0 V56
+ * psllw $1, %mm0 t177=t188 ! new !!
+ * psllw $1, %mm5 t178=t189 ! new !!
+ * movq %mm0, %mm1 duplicate t177=t188
+ * paddsw %mm5, %mm0 tm1
+ */
+ movq 8*13(%esi), %mm2 /* V57 */
+ psubsw %mm5, %mm1 /* tm15; free mm5 */
+ movq %mm0, 8(%esi) /* tm1; free mm0 */
+ psraw $1, %mm7 /* t182=t184 ! new !! */
+/* save the store as used directly in the transpose
+ * movq %mm1, 120(%esi) tm15; free mm1
+ */
+ movq %mm7, %mm5 /* duplicate t182=t184 */
+ psubsw %mm3, %mm7 /* tm7 */
+ paddsw %mm3, %mm5 /* tm9; free mm3 */
+ movq 8*9(%esi), %mm0 /* V58 */
+ movq %mm2, %mm3 /* duplicate V57 */
+ movq %mm7, 8*7(%esi) /* tm7; free mm7 */
+ psubsw %mm6, %mm3 /* tm13 */
+ paddsw %mm6, %mm2 /* tm3 ; free mm6 */
+/* moved up from the transpose */
+ movq %mm3, %mm7
+/* moved up from the transpose */
+ punpcklwd %mm1, %mm3
+ movq %mm0, %mm6 /* duplicate V58 */
+ movq %mm2, 8*3(%esi) /* tm3; free mm2 */
+ paddsw %mm4, %mm0 /* tm5 */
+ psubsw %mm4, %mm6 /* tm11; free mm4 */
+/* moved up from the transpose */
+ punpckhwd %mm1, %mm7
+ movq %mm0, 8*5(%esi) /* tm5; free mm0 */
+/* moved up from the transpose */
+ movq %mm5, %mm2
+/* transpose - M4 part
+ * --------- ---------
+ * | M1 | M2 | | M1'| M3'|
+ * --------- --> ---------
+ * | M3 | M4 | | M2'| M4'|
+ * --------- ---------
+ * Two alternatives: use full mmword approach so the following code can be
+ * scheduled before the transpose is done without stores, or use the faster
+ * half mmword stores (when possible)
+ */
+ movd %mm3, 8*9+4(%esi) /* MS part of tmt9 */
+ punpcklwd %mm6, %mm5
+ movd %mm7, 8*13+4(%esi) /* MS part of tmt13 */
+ punpckhwd %mm6, %mm2
+ movd %mm5, 8*9(%esi) /* LS part of tmt9 */
+ punpckhdq %mm3, %mm5 /* free mm3 */
+ movd %mm2, 8*13(%esi) /* LS part of tmt13 */
+ punpckhdq %mm7, %mm2 /* free mm7 */
+/* moved up from the M3 transpose */
+ movq 8*8(%esi), %mm0
+/* moved up from the M3 transpose */
+ movq 8*10(%esi), %mm1
+/* moved up from the M3 transpose */
+ movq %mm0, %mm3
+/* shuffle the rest of the data, and write it with 2 mmword writes */
+ movq %mm5, 8*11(%esi) /* tmt11 */
+/* moved up from the M3 transpose */
+ punpcklwd %mm1, %mm0
+ movq %mm2, 8*15(%esi) /* tmt15 */
+/* moved up from the M3 transpose */
+ punpckhwd %mm1, %mm3
+/* transpose - M3 part
+ * moved up to previous code section
+ * movq 8*8(%esi), %mm0
+ * movq 8*10(%esi), %mm1
+ * movq %mm0, %mm3
+ * punpcklwd %mm1, %mm0
+ * punpckhwd %mm1, %mm3
+ */
+ movq 8*12(%esi), %mm6
+ movq 8*14(%esi), %mm4
+ movq %mm6, %mm2
+/* shuffle the data and write the lower parts of the transposed in 4 dwords */
+ punpcklwd %mm4, %mm6
+ movq %mm0, %mm1
+ punpckhdq %mm6, %mm1
+ movq %mm3, %mm7
+ punpckhwd %mm4, %mm2 /* free mm4 */
+ punpckldq %mm6, %mm0 /* free mm6 */
+/* moved from next block */
+ movq 8*13(%esi), %mm4 /* tmt13 */
+ punpckldq %mm2, %mm3
+ punpckhdq %mm2, %mm7 /* free mm2 */
+/* moved from next block */
+ movq %mm3, %mm5 /* duplicate tmt5 */
+/* column 1: even part (after transpose)
+* moved above
+* movq %mm3, %mm5 duplicate tmt5
+* movq 8*13(%esi), %mm4 tmt13
+*/
+ psubsw %mm4, %mm3 /* V134 */
+ pmulhw x5a825a825a825a82, %mm3 /* 23170 ->V136 */
+ movq 8*9(%esi), %mm6 /* tmt9 */
+ paddsw %mm4, %mm5 /* V135 ; mm4 free */
+ movq %mm0, %mm4 /* duplicate tmt1 */
+ paddsw %mm6, %mm0 /* V137 */
+ psubsw %mm6, %mm4 /* V138 ; mm6 free */
+ psllw $2, %mm3 /* t290 */
+ psubsw %mm5, %mm3 /* V139 */
+ movq %mm0, %mm6 /* duplicate V137 */
+ paddsw %mm5, %mm0 /* V140 */
+ movq %mm4, %mm2 /* duplicate V138 */
+ paddsw %mm3, %mm2 /* V141 */
+ psubsw %mm3, %mm4 /* V142 ; mm3 free */
+ movq %mm0, 8*9(%esi) /* V140 */
+ psubsw %mm5, %mm6 /* V143 ; mm5 free */
+/* moved from next block */
+ movq 8*11(%esi), %mm0 /* tmt11 */
+ movq %mm2, 8*13(%esi) /* V141 */
+/* moved from next block */
+ movq %mm0, %mm2 /* duplicate tmt11 */
+/* column 1: odd part (after transpose) */
+/* moved up to the prev block
+ * movq 8*11(%esi), %mm0 tmt11
+ * movq %mm0, %mm2 duplicate tmt11
+ */
+ movq 8*15(%esi), %mm5 /* tmt15 */
+ psubsw %mm7, %mm0 /* V144 */
+ movq %mm0, %mm3 /* duplicate V144 */
+ paddsw %mm7, %mm2 /* V147 ; free mm7 */
+ pmulhw x539f539f539f539f, %mm0 /* 21407-> V151 */
+ movq %mm1, %mm7 /* duplicate tmt3 */
+ paddsw %mm5, %mm7 /* V145 */
+ psubsw %mm5, %mm1 /* V146 ; free mm5 */
+ psubsw %mm1, %mm3 /* V150 */
+ movq %mm7, %mm5 /* duplicate V145 */
+ pmulhw x4546454645464546, %mm1 /* 17734-> V153 */
+ psubsw %mm2, %mm5 /* V148 */
+ pmulhw x61f861f861f861f8, %mm3 /* 25080-> V154 */
+ psllw $2, %mm0 /* t311 */
+ pmulhw x5a825a825a825a82, %mm5 /* 23170-> V152 */
+ paddsw %mm2, %mm7 /* V149 ; free mm2 */
+ psllw $1, %mm1 /* t313 */
+ nop /* without the nop - freeze here for one clock */
+ movq %mm3, %mm2 /* duplicate V154 */
+ psubsw %mm0, %mm3 /* V155 ; free mm0 */
+ psubsw %mm2, %mm1 /* V156 ; free mm2 */
+/* moved from the next block */
+ movq %mm6, %mm2 /* duplicate V143 */
+/* moved from the next block */
+ movq 8*13(%esi), %mm0 /* V141 */
+ psllw $1, %mm1 /* t315 */
+ psubsw %mm7, %mm1 /* V157 (keep V149) */
+ psllw $2, %mm5 /* t317 */
+ psubsw %mm1, %mm5 /* V158 */
+ psllw $1, %mm3 /* t319 */
+ paddsw %mm5, %mm3 /* V159 */
+/* column 1: output butterfly (after transform)
+ * moved to the prev block
+ * movq %mm6, %mm2 duplicate V143
+ * movq 8*13(%esi), %mm0 V141
+ */
+ psubsw %mm3, %mm2 /* V163 */
+ paddsw %mm3, %mm6 /* V164 ; free mm3 */
+ movq %mm4, %mm3 /* duplicate V142 */
+ psubsw %mm5, %mm4 /* V165 ; free mm5 */
+ movq %mm2, (%esp) /* out7 */
+ psraw $4, %mm6
+ psraw $4, %mm4
+ paddsw %mm5, %mm3 /* V162 */
+ movq 8*9(%esi), %mm2 /* V140 */
+ movq %mm0, %mm5 /* duplicate V141 */
+/* in order not to perculate this line up,
+ * we read 72(%esi) very near to this location
+ */
+ movq %mm6, 8*9(%esi) /* out9 */
+ paddsw %mm1, %mm0 /* V161 */
+ movq %mm3, 8(%esp) /* out5 */
+ psubsw %mm1, %mm5 /* V166 ; free mm1 */
+ movq %mm4, 8*11(%esi) /* out11 */
+ psraw $4, %mm5
+ movq %mm0, 16(%esp) /* out3 */
+ movq %mm2, %mm4 /* duplicate V140 */
+ movq %mm5, 8*13(%esi) /* out13 */
+ paddsw %mm7, %mm2 /* V160 */
+/* moved from the next block */
+ movq 8(%esi), %mm0
+ psubsw %mm7, %mm4 /* V167 ; free mm7 */
+/* moved from the next block */
+ movq 8*3(%esi), %mm7
+ psraw $4, %mm4
+ movq %mm2, 24(%esp) /* out1 */
+/* moved from the next block */
+ movq %mm0, %mm1
+ movq %mm4, 8*15(%esi) /* out15 */
+/* moved from the next block */
+ punpcklwd %mm7, %mm0
+/* transpose - M2 parts
+ * moved up to the prev block
+ * movq 8(%esi), %mm0
+ * movq 8*3(%esi), %mm7
+ * movq %mm0, %mm1
+ * punpcklwd %mm7, %mm0
+ */
+ movq 8*5(%esi), %mm5
+ punpckhwd %mm7, %mm1
+ movq 8*7(%esi), %mm4
+ movq %mm5, %mm3
+/* shuffle the data and write the lower parts of the trasposed in 4 dwords */
+ movd %mm0, 8*8(%esi) /* LS part of tmt8 */
+ punpcklwd %mm4, %mm5
+ movd %mm1, 8*12(%esi) /* LS part of tmt12 */
+ punpckhwd %mm4, %mm3
+ movd %mm5, 8*8+4(%esi) /* MS part of tmt8 */
+ punpckhdq %mm5, %mm0 /* tmt10 */
+ movd %mm3, 8*12+4(%esi) /* MS part of tmt12 */
+ punpckhdq %mm3, %mm1 /* tmt14 */
+/* transpose - M1 parts */
+ movq (%esi), %mm7
+ movq 8*2(%esi), %mm2
+ movq %mm7, %mm6
+ movq 8*4(%esi), %mm5
+ punpcklwd %mm2, %mm7
+ movq 8*6(%esi), %mm4
+ punpckhwd %mm2, %mm6 /* free mm2 */
+ movq %mm5, %mm3
+ punpcklwd %mm4, %mm5
+ punpckhwd %mm4, %mm3 /* free mm4 */
+ movq %mm7, %mm2
+ movq %mm6, %mm4
+ punpckldq %mm5, %mm7 /* tmt0 */
+ punpckhdq %mm5, %mm2 /* tmt2 ; free mm5 */
+/* shuffle the rest of the data, and write it with 2 mmword writes */
+ punpckldq %mm3, %mm6 /* tmt4 */
+/* moved from next block */
+ movq %mm2, %mm5 /* duplicate tmt2 */
+ punpckhdq %mm3, %mm4 /* tmt6 ; free mm3 */
+/* moved from next block */
+ movq %mm0, %mm3 /* duplicate tmt10 */
+/* column 0: odd part (after transpose)
+ *moved up to prev block
+ * movq %mm0, %mm3 duplicate tmt10
+ * movq %mm2, %mm5 duplicate tmt2
+ */
+ psubsw %mm4, %mm0 /* V110 */
+ paddsw %mm4, %mm3 /* V113 ; free mm4 */
+ movq %mm0, %mm4 /* duplicate V110 */
+ paddsw %mm1, %mm2 /* V111 */
+ pmulhw x539f539f539f539f, %mm0 /* 21407-> V117 */
+ psubsw %mm1, %mm5 /* V112 ; free mm1 */
+ psubsw %mm5, %mm4 /* V116 */
+ movq %mm2, %mm1 /* duplicate V111 */
+ pmulhw x4546454645464546, %mm5 /* 17734-> V119 */
+ psubsw %mm3, %mm2 /* V114 */
+ pmulhw x61f861f861f861f8, %mm4 /* 25080-> V120 */
+ paddsw %mm3, %mm1 /* V115 ; free mm3 */
+ pmulhw x5a825a825a825a82, %mm2 /* 23170-> V118 */
+ psllw $2, %mm0 /* t266 */
+ movq %mm1, (%esi) /* save V115 */
+ psllw $1, %mm5 /* t268 */
+ psubsw %mm4, %mm5 /* V122 */
+ psubsw %mm0, %mm4 /* V121 ; free mm0 */
+ psllw $1, %mm5 /* t270 */
+ psubsw %mm1, %mm5 /* V123 ; free mm1 */
+ psllw $2, %mm2 /* t272 */
+ psubsw %mm5, %mm2 /* V124 (keep V123) */
+ psllw $1, %mm4 /* t274 */
+ movq %mm5, 8*2(%esi) /* save V123 ; free mm5 */
+ paddsw %mm2, %mm4 /* V125 (keep V124) */
+/* column 0: even part (after transpose) */
+ movq 8*12(%esi), %mm0 /* tmt12 */
+ movq %mm6, %mm3 /* duplicate tmt4 */
+ psubsw %mm0, %mm6 /* V100 */
+ paddsw %mm0, %mm3 /* V101 ; free mm0 */
+ pmulhw x5a825a825a825a82, %mm6 /* 23170 ->V102 */
+ movq %mm7, %mm5 /* duplicate tmt0 */
+ movq 8*8(%esi), %mm1 /* tmt8 */
+ paddsw %mm1, %mm7 /* V103 */
+ psubsw %mm1, %mm5 /* V104 ; free mm1 */
+ movq %mm7, %mm0 /* duplicate V103 */
+ psllw $2, %mm6 /* t245 */
+ paddsw %mm3, %mm7 /* V106 */
+ movq %mm5, %mm1 /* duplicate V104 */
+ psubsw %mm3, %mm6 /* V105 */
+ psubsw %mm3, %mm0 /* V109; free mm3 */
+ paddsw %mm6, %mm5 /* V107 */
+ psubsw %mm6, %mm1 /* V108 ; free mm6 */
+/* column 0: output butterfly (after transform) */
+ movq %mm1, %mm3 /* duplicate V108 */
+ paddsw %mm2, %mm1 /* out4 */
+ psraw $4, %mm1
+ psubsw %mm2, %mm3 /* out10 ; free mm2 */
+ psraw $4, %mm3
+ movq %mm0, %mm6 /* duplicate V109 */
+ movq %mm1, 8*4(%esi) /* out4 ; free mm1 */
+ psubsw %mm4, %mm0 /* out6 */
+ movq %mm3, 8*10(%esi) /* out10 ; free mm3 */
+ psraw $4, %mm0
+ paddsw %mm4, %mm6 /* out8 ; free mm4 */
+ movq %mm7, %mm1 /* duplicate V106 */
+ movq %mm0, 8*6(%esi) /* out6 ; free mm0 */
+ psraw $4, %mm6
+ movq (%esi), %mm4 /* V115 */
+ movq %mm6, 8*8(%esi) /* out8 ; free mm6 */
+ movq %mm5, %mm2 /* duplicate V107 */
+ movq 8*2(%esi), %mm3 /* V123 */
+ paddsw %mm4, %mm7 /* out0 */
+/* moved up from next block */
+ movq 16(%esp), %mm0
+ psraw $4, %mm7
+/* moved up from next block */
+ movq 8(%esp), %mm6
+ psubsw %mm4, %mm1 /* out14 ; free mm4 */
+ paddsw %mm3, %mm5 /* out2 */
+ psraw $4, %mm1
+ movq %mm7, (%esi) /* out0 ; free mm7 */
+ psraw $4, %mm5
+ movq %mm1, 8*14(%esi) /* out14 ; free mm1 */
+ psubsw %mm3, %mm2 /* out12 ; free mm3 */
+ movq %mm5, 8*2(%esi) /* out2 ; free mm5 */
+ psraw $4, %mm2
+/* moved up to the prev block */
+ movq (%esp), %mm4
+/* moved up to the prev block */
+ psraw $4, %mm0
+ movq %mm2, 8*12(%esi) /* out12 ; free mm2 */
+/* moved up to the prev block */
+ psraw $4, %mm6
+/* move back the data to its correct place
+* moved up to the prev block
+ * movq 16(%esp), %mm0
+ * movq 8(%esp), %mm6
+ * movq (%esp), %mm4
+ * psraw $4, %mm0
+ * psraw $4, %mm6
+*/
+ movq 24(%esp), %mm1
+ psraw $4, %mm4
+ movq %mm0, 8*3(%esi) /* out3 */
+ psraw $4, %mm1
+ movq %mm6, 8*5(%esi) /* out5 */
+ movq %mm4, 8*7(%esi) /* out7 */
+ movq %mm1, 8(%esi) /* out1 */
+
+ popl %edi /* Pop off the temp variables */
+ popl %edi
+ popl %edi
+ popl %edi
+ popl %edi
+ popl %edi
+ popl %edi
+ popl %edi
+
+ popl %edi /* Pop off the old variables */
+ popl %esi
+ popl %edx
+ popl %ecx
+ popl %ebx
+ movl %ebp, %esp
+ popl %ebp
+
+ ret
+.Lfe1:
+ .size IDCT_mmx,.Lfe1-IDCT_mmx
diff --git a/core/multimedia/opieplayer/libmpeg3/video/mmxtest.c b/core/multimedia/opieplayer/libmpeg3/video/mmxtest.c
new file mode 100644
index 0000000..567f139
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/mmxtest.c
@@ -0,0 +1,35 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+
+#include <stdio.h>
+#include <string.h>
+
+int mpeg3_mmx_test()
+{
+ int result = 0;
+ FILE *proc;
+ char string[MPEG3_STRLEN];
+
+
+#ifdef HAVE_MMX
+ if(!(proc = fopen(MPEG3_PROC_CPUINFO, "r")))
+ {
+ return 0;
+ }
+
+ while(!feof(proc))
+ {
+ fgets(string, MPEG3_STRLEN, proc);
+/* Got the flags line */
+ if(!strncmp(string, "flags", 5))
+ {
+ char *needle;
+ needle = strstr(string, "mmx");
+ if(!needle) return 0;
+ if(!strncmp(needle, "mmx", 3)) return 1;
+ }
+ }
+#endif
+
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/video/motion.c b/core/multimedia/opieplayer/libmpeg3/video/motion.c
new file mode 100644
index 0000000..4d2f681
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/motion.c
@@ -0,0 +1,230 @@
+#include "mpeg3video.h"
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "vlc.h"
+
+#include <stdio.h>
+
+
+/* calculate motion vector component */
+
+static inline void mpeg3video_calc_mv(int *pred, int r_size, int motion_code, int motion_r, int full_pel_vector)
+{
+ int lim = 16 << r_size;
+ int vec = full_pel_vector ? (*pred >> 1) : (*pred);
+
+ if(motion_code > 0)
+ {
+ vec += ((motion_code - 1) << r_size) + motion_r + 1;
+ if(vec >= lim) vec -= lim + lim;
+ }
+ else
+ if(motion_code < 0)
+ {
+ vec -= ((-motion_code - 1) << r_size) + motion_r + 1;
+ if(vec < -lim) vec += lim + lim;
+ }
+ *pred = full_pel_vector ? (vec << 1) : vec;
+}
+
+
+/*
+int *dmvector, * differential motion vector *
+int mvx, int mvy * decoded mv components (always in field format) *
+*/
+void mpeg3video_calc_dmv(mpeg3video_t *video,
+ int DMV[][2],
+ int *dmvector,
+ int mvx,
+ int mvy)
+{
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+ if(video->topfirst)
+ {
+/* vector for prediction of top field from bottom field */
+ DMV[0][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0];
+ DMV[0][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] - 1;
+
+/* vector for prediction of bottom field from top field */
+ DMV[1][0] = ((3 * mvx + (mvx > 0)) >> 1) + dmvector[0];
+ DMV[1][1] = ((3 * mvy + (mvy > 0)) >> 1) + dmvector[1] + 1;
+ }
+ else
+ {
+/* vector for prediction of top field from bottom field */
+ DMV[0][0] = ((3 * mvx + (mvx>0)) >> 1) + dmvector[0];
+ DMV[0][1] = ((3 * mvy + (mvy>0)) >> 1) + dmvector[1] - 1;
+
+/* vector for prediction of bottom field from top field */
+ DMV[1][0] = ((mvx + (mvx>0)) >> 1) + dmvector[0];
+ DMV[1][1] = ((mvy + (mvy>0)) >> 1) + dmvector[1] + 1;
+ }
+ }
+ else
+ {
+/* vector for prediction from field of opposite 'parity' */
+ DMV[0][0] = ((mvx + (mvx > 0)) >> 1) + dmvector[0];
+ DMV[0][1] = ((mvy + (mvy > 0)) >> 1) + dmvector[1];
+
+/* correct for vertical field shift */
+ if(video->pict_struct == TOP_FIELD)
+ DMV[0][1]--;
+ else
+ DMV[0][1]++;
+ }
+}
+
+static inline int mpeg3video_get_mv(mpeg3_slice_t *slice)
+{
+ int code;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+ if(mpeg3slice_getbit(slice_buffer))
+ {
+ return 0;
+ }
+
+ if((code = mpeg3slice_showbits9(slice_buffer)) >= 64)
+ {
+ code >>= 6;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab0[code].len);
+ return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab0[code].val : mpeg3_MVtab0[code].val;
+ }
+
+ if(code >= 24)
+ {
+ code >>= 3;
+ mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab1[code].len);
+ return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab1[code].val : mpeg3_MVtab1[code].val;
+ }
+
+ if((code -= 12) < 0)
+ {
+/* fprintf(stdout,"mpeg3video_get_mv: invalid motion_vector code\n"); */
+ slice->fault = 1;
+ return 1;
+ }
+
+ mpeg3slice_flushbits(slice_buffer, mpeg3_MVtab2[code].len);
+ return mpeg3slice_getbit(slice_buffer) ? -mpeg3_MVtab2[code].val : mpeg3_MVtab2[code].val;
+}
+
+/* get differential motion vector (for dual prime prediction) */
+
+static inline int mpeg3video_get_dmv(mpeg3_slice_t *slice)
+{
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ if(mpeg3slice_getbit(slice_buffer))
+ {
+ return mpeg3slice_getbit(slice_buffer) ? -1 : 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+
+/* get and decode motion vector and differential motion vector */
+
+void mpeg3video_motion_vector(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int *PMV,
+ int *dmvector,
+ int h_r_size,
+ int v_r_size,
+ int dmv,
+ int mvscale,
+ int full_pel_vector)
+{
+ int motion_r;
+ int motion_code = mpeg3video_get_mv(slice);
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+ if(slice->fault) return;
+ motion_r = (h_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, h_r_size) : 0;
+
+ mpeg3video_calc_mv(&PMV[0], h_r_size, motion_code, motion_r, full_pel_vector);
+
+ if(dmv) dmvector[0] = mpeg3video_get_dmv(slice);
+
+ motion_code = mpeg3video_get_mv(slice);
+ if(slice->fault) return;
+ motion_r = (v_r_size != 0 && motion_code != 0) ? mpeg3slice_getbits(slice_buffer, v_r_size) : 0;
+
+/* DIV 2 */
+ if(mvscale) PMV[1] >>= 1;
+
+ mpeg3video_calc_mv(&PMV[1], v_r_size, motion_code, motion_r, full_pel_vector);
+
+ if(mvscale) PMV[1] <<= 1;
+ if(dmv) dmvector[1] = mpeg3video_get_dmv(slice);
+}
+
+int mpeg3video_motion_vectors(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int PMV[2][2][2],
+ int dmvector[2],
+ int mv_field_sel[2][2],
+ int s,
+ int mv_count,
+ int mv_format,
+ int h_r_size,
+ int v_r_size,
+ int dmv,
+ int mvscale)
+{
+ int result = 0;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+ if(mv_count == 1)
+ {
+ if(mv_format == MV_FIELD && !dmv)
+ {
+ mv_field_sel[1][s] = mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer);
+ }
+
+ mpeg3video_motion_vector(slice,
+ video,
+ PMV[0][s],
+ dmvector,
+ h_r_size,
+ v_r_size,
+ dmv,
+ mvscale,
+ 0);
+ if(slice->fault) return 1;
+
+/* update other motion vector predictors */
+ PMV[1][s][0] = PMV[0][s][0];
+ PMV[1][s][1] = PMV[0][s][1];
+ }
+ else
+ {
+ mv_field_sel[0][s] = mpeg3slice_getbit(slice_buffer);
+ mpeg3video_motion_vector(slice,
+ video,
+ PMV[0][s],
+ dmvector,
+ h_r_size,
+ v_r_size,
+ dmv,
+ mvscale,
+ 0);
+ if(slice->fault) return 1;
+
+ mv_field_sel[1][s] = mpeg3slice_getbit(slice_buffer);
+ mpeg3video_motion_vector(slice,
+ video,
+ PMV[1][s],
+ dmvector,
+ h_r_size,
+ v_r_size,
+ dmv,
+ mvscale,
+ 0);
+ if(slice->fault) return 1;
+ }
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.c b/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.c
new file mode 100644
index 0000000..a9f113e
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.c
@@ -0,0 +1,597 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include "mpeg3videoprotos.h"
+#include <stdlib.h>
+
+unsigned char mpeg3_zig_zag_scan_mmx[64] =
+{
+ 0*8+0 /* 0*/, 1*8+0 /* 1*/, 0*8+1 /* 8*/, 0*8+2 /*16*/, 1*8+1 /* 9*/, 2*8+0 /* 2*/, 3*8+0 /* 3*/, 2*8+1 /*10*/,
+ 1*8+2 /*17*/, 0*8+3 /*24*/, 0*8+4 /*32*/, 1*8+3 /*25*/, 2*8+2 /*18*/, 3*8+1 /*11*/, 4*8+0 /* 4*/, 5*8+0 /* 5*/,
+ 4*8+1 /*12*/, 5*8+2 /*19*/, 2*8+3 /*26*/, 1*8+4 /*33*/, 0*8+5 /*40*/, 0*8+6 /*48*/, 1*8+5 /*41*/, 2*8+4 /*34*/,
+ 3*8+3 /*27*/, 4*8+2 /*20*/, 5*8+1 /*13*/, 6*8+0 /* 6*/, 7*8+0 /* 7*/, 6*8+1 /*14*/, 5*8+2 /*21*/, 4*8+3 /*28*/,
+ 3*8+4 /*35*/, 2*8+5 /*42*/, 1*8+6 /*49*/, 0*8+7 /*56*/, 1*8+7 /*57*/, 2*8+6 /*50*/, 3*8+5 /*43*/, 4*8+4 /*36*/,
+ 5*8+3 /*29*/, 6*8+2 /*22*/, 7*8+1 /*15*/, 7*8+2 /*23*/, 6*8+3 /*30*/, 5*8+4 /*37*/, 4*8+5 /*44*/, 3*8+6 /*51*/,
+ 2*8+7 /*58*/, 3*8+7 /*59*/, 4*8+6 /*52*/, 5*8+5 /*45*/, 6*8+4 /*38*/, 7*8+3 /*31*/, 7*8+4 /*39*/, 6*8+5 /*46*/,
+ 7*8+6 /*53*/, 4*8+7 /*60*/, 5*8+7 /*61*/, 6*8+6 /*54*/, 7*8+5 /*47*/, 7*8+6 /*55*/, 6*8+7 /*62*/, 7*8+7 /*63*/
+};
+
+/* alternate scan */
+unsigned char mpeg3_alternate_scan_mmx[64] =
+{
+ 0*8+0 /*0 */, 0*8+1 /* 8*/, 0*8+2 /*16*/, 0*8+3 /*24*/, 1*8+0 /* 1*/, 1*8+1 /* 9*/, 2*8+0 /* 2*/, 2*8+1 /*10*/,
+ 1*8+2 /*17*/, 1*8+3 /*25*/, 0*8+4 /*32*/, 0*8+5 /*40*/, 0*8+6 /*48*/, 0*8+7 /*56*/, 1*8+7 /*57*/, 1*8+6 /*49*/,
+ 1*8+5 /*41*/, 1*8+4 /*33*/, 2*8+3 /*26*/, 2*8+2 /*18*/, 3*8+0 /* 3*/, 3*8+1 /*11*/, 4*8+0 /* 4*/, 4*8+1 /*12*/,
+ 3*8+2 /*19*/, 3*8+3 /*27*/, 2*8+4 /*34*/, 2*8+5 /*42*/, 2*8+6 /*50*/, 2*8+7 /*58*/, 3*8+4 /*35*/, 3*8+5 /*43*/,
+ 3*8+6 /*51*/, 3*8+7 /*59*/, 4*8+2 /*20*/, 4*8+3 /*28*/, 5*8+0 /* 5*/, 5*8+1 /*13*/, 6*8+0 /* 6*/, 6*8+1 /*14*/,
+ 5*8+2 /*21*/, 5*8+3 /*29*/, 4*8+4 /*36*/, 4*8+5 /*44*/, 4*8+6 /*52*/, 4*8+7 /*60*/, 5*8+4 /*37*/, 5*8+5 /*45*/,
+ 5*8+6 /*53*/, 5*8+7 /*61*/, 6*8+2 /*22*/, 6*8+3 /*30*/, 7*8+0 /* 7*/, 7*8+1 /*15*/, 7*8+2 /*23*/, 7*8+3 /*31*/,
+ 6*8+4 /*38*/, 6*8+5 /*46*/, 6*8+6 /*54*/, 6*8+7 /*62*/, 7*8+4 /*39*/, 7*8+5 /*47*/, 7*8+6 /*55*/, 7*8+6 /*63*/
+};
+
+
+
+/* zig-zag scan */
+unsigned char mpeg3_zig_zag_scan_nommx[64] =
+{
+ 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
+};
+
+/* alternate scan */
+unsigned char mpeg3_alternate_scan_nommx[64] =
+{
+ 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
+};
+
+/* default intra quantization matrix */
+unsigned char mpeg3_default_intra_quantizer_matrix[64] =
+{
+ 8, 16, 19, 22, 26, 27, 29, 34,
+ 16, 16, 22, 24, 27, 29, 34, 37,
+ 19, 22, 26, 27, 29, 34, 34, 38,
+ 22, 22, 26, 27, 29, 34, 37, 40,
+ 22, 26, 27, 29, 32, 35, 40, 48,
+ 26, 27, 29, 32, 35, 40, 48, 58,
+ 26, 27, 29, 34, 38, 46, 56, 69,
+ 27, 29, 35, 38, 46, 56, 69, 83
+};
+
+unsigned char mpeg3_non_linear_mquant_table[32] =
+{
+ 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
+};
+
+double mpeg3_frame_rate_table[16] =
+{
+ 0.0, /* Pad */
+ 24000.0/1001.0, /* Official frame rates */
+ 24.0,
+ 25.0,
+ 30000.0/1001.0,
+ 30.0,
+ 50.0,
+ ((60.0*1000.0)/1001.0),
+ 60.0,
+
+ 1, /* Unofficial economy rates */
+ 5,
+ 10,
+ 12,
+ 15,
+ 0,
+ 0,
+};
+
+int mpeg3video_initdecoder(mpeg3video_t *video)
+{
+ int blk_cnt_tab[3] = {6, 8, 12};
+ int cc;
+ int i;
+ long size[4], padding[2]; /* Size of Y, U, and V buffers */
+
+ if(!video->mpeg2)
+ {
+/* force MPEG-1 parameters */
+ video->prog_seq = 1;
+ video->prog_frame = 1;
+ video->pict_struct = FRAME_PICTURE;
+ video->frame_pred_dct = 1;
+ video->chroma_format = CHROMA420;
+ video->matrix_coefficients = 5;
+ }
+
+/* Get dimensions rounded to nearest multiple of coded macroblocks */
+ video->mb_width = (video->horizontal_size + 15) / 16;
+ video->mb_height = (video->mpeg2 && !video->prog_seq) ?
+ (2 * ((video->vertical_size + 31) / 32)) :
+ ((video->vertical_size + 15) / 16);
+ video->coded_picture_width = 16 * video->mb_width;
+ video->coded_picture_height = 16 * video->mb_height;
+ video->chrom_width = (video->chroma_format == CHROMA444) ?
+ video->coded_picture_width :
+ (video->coded_picture_width >> 1);
+ video->chrom_height = (video->chroma_format != CHROMA420) ?
+ video->coded_picture_height :
+ (video->coded_picture_height >> 1);
+ video->blk_cnt = blk_cnt_tab[video->chroma_format - 1];
+
+/* Get sizes of YUV buffers */
+ padding[0] = 16 * video->coded_picture_width;
+ size[0] = video->coded_picture_width * video->coded_picture_height + padding[0] * 2;
+
+ padding[1] = 16 * video->chrom_width;
+ size[1] = video->chrom_width * video->chrom_height + 2 * padding[1];
+
+ size[2] = (video->llw * video->llh);
+ size[3] = (video->llw * video->llh) / 4;
+
+/* Allocate contiguous fragments for YUV buffers for hardware YUV decoding */
+ video->yuv_buffer[0] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
+ video->yuv_buffer[1] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
+ video->yuv_buffer[2] = (unsigned char*)calloc(1, (size[0] + padding[0]) + 2 * (size[1] + padding[1]));
+
+ if(video->scalable_mode == SC_SPAT)
+ {
+ video->yuv_buffer[3] = (unsigned char*)calloc(1, size[2] + 2 * size[3]);
+ video->yuv_buffer[4] = (unsigned char*)calloc(1, size[2] + 2 * size[3]);
+ }
+
+/* Direct pointers to areas of contiguous fragments in YVU order per Microsoft */
+ for(cc = 0; cc < 3; cc++)
+ {
+ video->llframe0[cc] = 0;
+ video->llframe1[cc] = 0;
+ video->newframe[cc] = 0;
+ }
+
+ video->refframe[0] = video->yuv_buffer[0];
+ video->oldrefframe[0] = video->yuv_buffer[1];
+ video->auxframe[0] = video->yuv_buffer[2];
+ video->refframe[2] = video->yuv_buffer[0] + size[0] + padding[0];
+ video->oldrefframe[2] = video->yuv_buffer[1] + size[0] + padding[0];
+ video->auxframe[2] = video->yuv_buffer[2] + size[0] + padding[0];
+ video->refframe[1] = video->yuv_buffer[0] + size[0] + padding[0] + size[1] + padding[1];
+ video->oldrefframe[1] = video->yuv_buffer[1] + size[0] + padding[0] + size[1] + padding[1];
+ video->auxframe[1] = video->yuv_buffer[2] + size[0] + padding[0] + size[1] + padding[1];
+
+ if(video->scalable_mode == SC_SPAT)
+ {
+/* this assumes lower layer is 4:2:0 */
+ video->llframe0[0] = video->yuv_buffer[3] + padding[0] ;
+ video->llframe1[0] = video->yuv_buffer[4] + padding[0] ;
+ video->llframe0[2] = video->yuv_buffer[3] + padding[1] + size[2] ;
+ video->llframe1[2] = video->yuv_buffer[4] + padding[1] + size[2] ;
+ video->llframe0[1] = video->yuv_buffer[3] + padding[1] + size[2] + size[3];
+ video->llframe1[1] = video->yuv_buffer[4] + padding[1] + size[2] + size[3];
+ }
+
+/* Initialize the YUV tables for software YUV decoding */
+ video->cr_to_r = (long*)malloc(sizeof(long) * 256);
+ video->cr_to_g = (long*)malloc(sizeof(long) * 256);
+ video->cb_to_g = (long*)malloc(sizeof(long) * 256);
+ video->cb_to_b = (long*)malloc(sizeof(long) * 256);
+ video->cr_to_r_ptr = video->cr_to_r + 128;
+ video->cr_to_g_ptr = video->cr_to_g + 128;
+ video->cb_to_g_ptr = video->cb_to_g + 128;
+ video->cb_to_b_ptr = video->cb_to_b + 128;
+
+ for(i = -128; i < 128; i++)
+ {
+ video->cr_to_r_ptr[i] = (long)( 1.371 * 65536 * i);
+ video->cr_to_g_ptr[i] = (long)(-0.698 * 65536 * i);
+ video->cb_to_g_ptr[i] = (long)(-0.336 * 65536 * i);
+ video->cb_to_b_ptr[i] = (long)( 1.732 * 65536 * i);
+ }
+
+ return 0;
+}
+
+int mpeg3video_deletedecoder(mpeg3video_t *video)
+{
+ int i, padding;
+
+ free(video->yuv_buffer[0]);
+ free(video->yuv_buffer[1]);
+ free(video->yuv_buffer[2]);
+
+ if(video->llframe0[0])
+ {
+ free(video->yuv_buffer[3]);
+ free(video->yuv_buffer[4]);
+ }
+
+ free(video->cr_to_r);
+ free(video->cr_to_g);
+ free(video->cb_to_g);
+ free(video->cb_to_b);
+ return 0;
+}
+
+void mpeg3video_init_scantables(mpeg3video_t *video)
+{
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ {
+ video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_mmx;
+ video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_mmx;
+ }
+ else
+#endif
+ {
+ video->mpeg3_zigzag_scan_table = mpeg3_zig_zag_scan_nommx;
+ video->mpeg3_alternate_scan_table = mpeg3_alternate_scan_nommx;
+ }
+}
+
+mpeg3video_t* mpeg3video_allocate_struct(mpeg3_t *file, mpeg3_vtrack_t *track)
+{
+ int i;
+ mpeg3video_t *video = (mpeg3video_t*)calloc(1, sizeof(mpeg3video_t));
+ pthread_mutexattr_t mutex_attr;
+
+ video->file = file;
+ video->track = track;
+ video->vstream = mpeg3bits_new_stream(file, track->demuxer);
+ video->last_number = -1;
+
+/* First frame is all green */
+ video->framenum = -1;
+ video->have_mmx = file->have_mmx;
+
+ video->percentage_seek = -1;
+ video->frame_seek = -1;
+
+ mpeg3video_init_scantables(video);
+ mpeg3video_init_output();
+
+ pthread_mutexattr_init(&mutex_attr);
+ pthread_mutex_init(&(video->test_lock), &mutex_attr);
+ pthread_mutex_init(&(video->slice_lock), &mutex_attr);
+ return video;
+}
+
+int mpeg3video_delete_struct(mpeg3video_t *video)
+{
+ int i;
+ mpeg3bits_delete_stream(video->vstream);
+ pthread_mutex_destroy(&(video->test_lock));
+ pthread_mutex_destroy(&(video->slice_lock));
+ if(video->x_table)
+ {
+ free(video->x_table);
+ free(video->y_table);
+ }
+ if(video->total_slice_decoders)
+ {
+ for(i = 0; i < video->total_slice_decoders; i++)
+ mpeg3_delete_slice_decoder(&video->slice_decoders[i]);
+ }
+ for(i = 0; i < video->slice_buffers_initialized; i++)
+ mpeg3_delete_slice_buffer(&(video->slice_buffers[i]));
+
+ free(video);
+}
+
+
+int mpeg3video_read_frame_backend(mpeg3video_t *video, int skip_bframes)
+{
+ int result = 0;
+
+ if(mpeg3bits_eof(video->vstream)) result = 1;
+
+ if(!result) result = mpeg3video_get_header(video, 0);
+
+//printf("frame type %d\n", video->pict_type);
+/* skip_bframes is the number of bframes we can skip successfully. */
+/* This is in case a skipped B-frame is repeated and the second repeat happens */
+/* to be a B frame we need. */
+ video->skip_bframes = skip_bframes;
+
+ if(!result)
+ result = mpeg3video_getpicture(video, video->framenum);
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ __asm__ __volatile__ ("emms");
+#endif
+
+ if(!result)
+ {
+ video->last_number = video->framenum;
+ video->framenum++;
+ }
+ return result;
+}
+
+int* mpeg3video_get_scaletable(int input_w, int output_w)
+{
+ int *result = (int*)malloc(sizeof(int) * output_w);
+ float i;
+ float scale = (float)input_w / output_w;
+ for(i = 0; i < output_w; i++)
+ {
+ result[(int)i] = (int)(scale * i);
+ }
+ return result;
+}
+
+/* Get the first frame read. */
+int mpeg3video_get_firstframe(mpeg3video_t *video)
+{
+ int result = 0;
+ if(video->framenum < 0)
+ {
+ video->repeat_count = video->current_repeat = 0;
+ result = mpeg3video_read_frame_backend(video, 0);
+ mpeg3bits_seek_byte(video->vstream, 0);
+ mpeg3video_match_refframes(video);
+ }
+ return result;
+}
+
+
+/* ======================================================================= */
+/* ENTRY POINTS */
+/* ======================================================================= */
+
+
+
+mpeg3video_t* mpeg3video_new(mpeg3_t *file, mpeg3_vtrack_t *track)
+{
+ mpeg3video_t *video;
+ int result = 0;
+
+ video = mpeg3video_allocate_struct(file, track);
+ result = mpeg3video_get_header(video, 1);
+
+ if(!result)
+ {
+ int hour, minute, second, frame;
+ int gop_found;
+
+ mpeg3video_initdecoder(video);
+ video->decoder_initted = 1;
+ track->width = video->horizontal_size;
+ track->height = video->vertical_size;
+ track->frame_rate = video->frame_rate;
+
+/* Get the length of the file from an elementary stream */
+ if(file->is_video_stream)
+ {
+/* Load the first GOP */
+ mpeg3bits_seek_start(video->vstream);
+ result = mpeg3video_next_code(video->vstream, MPEG3_GOP_START_CODE);
+ if(!result) mpeg3bits_getbits(video->vstream, 32);
+ if(!result) result = mpeg3video_getgophdr(video);
+
+ hour = video->gop_timecode.hour;
+ minute = video->gop_timecode.minute;
+ second = video->gop_timecode.second;
+ frame = video->gop_timecode.frame;
+ video->first_frame = (long)(hour * 3600 * video->frame_rate +
+ minute * 60 * video->frame_rate +
+ second * video->frame_rate +
+ frame);
+
+/* GOPs always have 16 frames */
+ video->frames_per_gop = 16;
+
+/* Read the last GOP in the file by seeking backward. */
+ mpeg3bits_seek_end(video->vstream);
+ mpeg3bits_start_reverse(video->vstream);
+ result = mpeg3video_prev_code(video->vstream, MPEG3_GOP_START_CODE);
+ mpeg3bits_start_forward(video->vstream);
+ mpeg3bits_getbits(video->vstream, 8);
+ if(!result) result = mpeg3video_getgophdr(video);
+
+ hour = video->gop_timecode.hour;
+ minute = video->gop_timecode.minute;
+ second = video->gop_timecode.second;
+ frame = video->gop_timecode.frame;
+
+ video->last_frame = (long)(hour * 3600 * video->frame_rate +
+ minute * 60 * video->frame_rate +
+ second * video->frame_rate +
+ frame);
+
+/* Count number of frames to end */
+ while(!result)
+ {
+ result = mpeg3video_next_code(video->vstream, MPEG3_PICTURE_START_CODE);
+ if(!result)
+ {
+ mpeg3bits_getbyte_noptr(video->vstream);
+ video->last_frame++;
+ }
+ }
+
+ track->total_frames = video->last_frame - video->first_frame + 1;
+ mpeg3bits_seek_start(video->vstream);
+ }
+ else
+ {
+/* Gross approximation from a multiplexed file. */
+ video->first_frame = 0;
+ track->total_frames = video->last_frame =
+ (long)(mpeg3demux_length(video->vstream->demuxer) *
+ video->frame_rate);
+ video->first_frame = 0;
+ }
+
+ video->maxframe = track->total_frames;
+ mpeg3bits_seek_start(video->vstream);
+ }
+ else
+ {
+ mpeg3video_delete(video);
+ video = 0;
+ }
+
+ return video;
+}
+
+int mpeg3video_delete(mpeg3video_t *video)
+{
+ if(video->decoder_initted)
+ {
+ mpeg3video_deletedecoder(video);
+ }
+ mpeg3video_delete_struct(video);
+ return 0;
+}
+
+int mpeg3video_set_cpus(mpeg3video_t *video, int cpus)
+{
+ return 0;
+}
+
+int mpeg3video_set_mmx(mpeg3video_t *video, int use_mmx)
+{
+ video->have_mmx = use_mmx;
+ mpeg3video_init_scantables(video);
+ return 0;
+}
+
+int mpeg3video_seek_percentage(mpeg3video_t *video, double percentage)
+{
+ video->percentage_seek = percentage;
+ return 0;
+}
+
+int mpeg3video_previous_frame(mpeg3video_t *video)
+{
+ if(mpeg3bits_tell_percentage(video->vstream) <= 0) return 1;
+ mpeg3bits_start_reverse(video->vstream);
+ mpeg3video_prev_code(video->vstream, MPEG3_PICTURE_START_CODE);
+ mpeg3bits_getbits_reverse(video->vstream, 32);
+
+ if(mpeg3bits_bof(video->vstream)) mpeg3bits_seek_percentage(video->vstream, 0);
+ mpeg3bits_start_forward(video->vstream);
+ video->repeat_count = 0;
+ return 0;
+}
+
+int mpeg3video_seek_frame(mpeg3video_t *video, long frame)
+{
+ video->frame_seek = frame;
+ return 0;
+}
+
+/* Read all the way up to and including the next picture start code */
+int mpeg3video_read_raw(mpeg3video_t *video, unsigned char *output, long *size, long max_size)
+{
+ unsigned MPEG3_INT32 code = 0;
+ mpeg3_bits_t *vstream = video->vstream;
+
+ *size = 0;
+ while(code != MPEG3_PICTURE_START_CODE &&
+ code != MPEG3_SEQUENCE_END_CODE &&
+ *size < max_size &&
+ !mpeg3bits_eof(vstream))
+ {
+ code <<= 8;
+ *output = mpeg3bits_getbyte_noptr(vstream);
+ code |= *output++;
+ (*size)++;
+ }
+ return mpeg3bits_eof(vstream);
+}
+
+int mpeg3video_read_frame(mpeg3video_t *video,
+ long frame_number,
+ unsigned char **output_rows,
+ int in_x,
+ int in_y,
+ int in_w,
+ int in_h,
+ int out_w,
+ int out_h,
+ int color_model)
+{
+ int result = 0;
+
+ video->want_yvu = 0;
+ video->output_rows = output_rows;
+ video->color_model = color_model;
+
+/* Get scaling tables */
+ if(video->out_w != out_w || video->out_h != out_h ||
+ video->in_w != in_w || video->in_h != in_h ||
+ video->in_x != in_x || video->in_y != in_y)
+ {
+ if(video->x_table)
+ {
+ free(video->x_table);
+ free(video->y_table);
+ video->x_table = 0;
+ video->y_table = 0;
+ }
+ }
+
+ video->out_w = out_w;
+ video->out_h = out_h;
+ video->in_w = in_w;
+ video->in_h = in_h;
+ video->in_x = in_x;
+ video->in_y = in_y;
+
+ if(!video->x_table)
+ {
+ video->x_table = mpeg3video_get_scaletable(video->in_w, video->out_w);
+ video->y_table = mpeg3video_get_scaletable(video->in_h, video->out_h);
+ }
+
+ mpeg3video_get_firstframe(video);
+
+ if(!result) result = mpeg3video_seek(video);
+
+ if(!result) result = mpeg3video_read_frame_backend(video, 0);
+
+ if(video->output_src) mpeg3video_present_frame(video);
+
+ video->percentage_seek = -1;
+ return result;
+}
+
+int mpeg3video_read_yuvframe(mpeg3video_t *video,
+ long frame_number,
+ char *y_output,
+ char *u_output,
+ char *v_output,
+ int in_x,
+ int in_y,
+ int in_w,
+ int in_h)
+{
+ int result = 0;
+
+ video->want_yvu = 1;
+ video->y_output = y_output;
+ video->u_output = u_output;
+ video->v_output = v_output;
+ video->in_x = in_x;
+ video->in_y = in_y;
+ video->in_w = in_w;
+ video->in_h = in_h;
+
+ mpeg3video_get_firstframe(video);
+
+ if(!result) result = mpeg3video_seek(video);
+
+ if(!result) result = mpeg3video_read_frame_backend(video, 0);
+
+ if(video->output_src) mpeg3video_present_frame(video);
+
+ video->want_yvu = 0;
+ video->percentage_seek = -1;
+ return result;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.h b/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.h
new file mode 100644
index 0000000..2db62b0
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/mpeg3video.h
@@ -0,0 +1,180 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEGVIDEO_H
+#define MPEGVIDEO_H
+
+#include "../bitstream.h"
+#include "../mpeg3private.inc"
+#include "idct.h"
+#include "slice.h"
+#include "../timecode.h"
+
+/* zig-zag scan */
+extern unsigned char mpeg3_zig_zag_scan_nommx[64];
+extern unsigned char mpeg3_zig_zag_scan_mmx[64];
+
+/* alternate scan */
+extern unsigned char mpeg3_alternate_scan_nommx[64];
+extern unsigned char mpeg3_alternate_scan_mmx[64];
+
+/* default intra quantization matrix */
+extern unsigned char mpeg3_default_intra_quantizer_matrix[64];
+
+/* Frame rate table must agree with the one in the encoder */
+extern double mpeg3_frame_rate_table[16];
+
+/* non-linear quantization coefficient table */
+extern unsigned char mpeg3_non_linear_mquant_table[32];
+
+#define CHROMA420 1 /* chroma_format */
+#define CHROMA422 2
+#define CHROMA444 3
+
+#define TOP_FIELD 1 /* picture structure */
+#define BOTTOM_FIELD 2
+#define FRAME_PICTURE 3
+
+#define SEQ_ID 1 /* extension start code IDs */
+#define DISP_ID 2
+#define QUANT_ID 3
+#define SEQSCAL_ID 5
+#define PANSCAN_ID 7
+#define CODING_ID 8
+#define SPATSCAL_ID 9
+#define TEMPSCAL_ID 10
+
+#define ERROR (-1)
+
+#define SC_NONE 0 /* scalable_mode */
+#define SC_DP 1
+#define SC_SPAT 2
+#define SC_SNR 3
+#define SC_TEMP 4
+
+#define I_TYPE 1 /* picture coding type */
+#define P_TYPE 2
+#define B_TYPE 3
+#define D_TYPE 4
+
+#define MB_INTRA 1 /* macroblock type */
+#define MB_PATTERN 2
+#define MB_BACKWARD 4
+#define MB_FORWARD 8
+#define MB_QUANT 16
+#define MB_WEIGHT 32
+#define MB_CLASS4 64
+
+#define MC_FIELD 1 /* motion_type */
+#define MC_FRAME 2
+#define MC_16X8 2
+#define MC_DMV 3
+
+#define MV_FIELD 0 /* mv_format */
+#define MV_FRAME 1
+
+#define CLIP(x) ((x) >= 0 ? ((x) < 255 ? (x) : 255) : 0)
+
+/* Statically allocate as little as possible so a fake video struct */
+/* can be used for reading the GOP headers. */
+
+struct mpeg3video_rec
+{
+ struct mpeg3_rec* file;
+ struct mpeg3_vtrack_rec* track;
+
+/* ================================= Seeking variables ========================= */
+ mpeg3_bits_t *vstream;
+ int decoder_initted;
+ unsigned char **output_rows; /* Output frame buffer supplied by user */
+ int in_x, in_y, in_w, in_h, out_w, out_h; /* Output dimensions */
+ int *x_table, *y_table; /* Location of every output pixel in the input */
+ int color_model;
+ int want_yvu; /* Want to return a YUV frame */
+ char *y_output, *u_output, *v_output; /* Output pointers for a YUV frame */
+
+ mpeg3_slice_t slice_decoders[MPEG3_MAX_CPUS]; /* One slice decoder for every CPU */
+ int total_slice_decoders; /* Total slice decoders in use */
+ mpeg3_slice_buffer_t slice_buffers[MPEG3_MAX_CPUS]; /* Buffers for holding the slice data */
+ int total_slice_buffers; /* Total buffers in the array to be decompressed */
+ int slice_buffers_initialized; /* Total buffers initialized in the array */
+ pthread_mutex_t slice_lock; /* Lock slice array while getting the next buffer */
+ pthread_mutex_t test_lock;
+
+ int blockreadsize;
+ long maxframe; /* Max value of frame num to read */
+ double percentage_seek; /* Perform a percentage seek before the next frame is read */
+ int frame_seek; /* Perform a frame seek before the next frame is read */
+ long framenum; /* Number of the next frame to be decoded */
+ long last_number; /* Last framenum rendered */
+ int found_seqhdr;
+ long bitrate;
+ mpeg3_timecode_t gop_timecode; /* Timecode for the last GOP header read. */
+
+/* These are only available from elementary streams. */
+ long frames_per_gop; /* Frames per GOP after the first GOP. */
+ long first_gop_frames; /* Frames in the first GOP. */
+ long first_frame; /* Number of first frame stored in timecode */
+ long last_frame; /* Last frame in file */
+
+/* ================================= Compression variables ===================== */
+/* Malloced frame buffers. 2 refframes are swapped in and out. */
+/* while only 1 auxframe is used. */
+ unsigned char *yuv_buffer[5]; /* Make YVU buffers contiguous for all frames */
+ unsigned char *oldrefframe[3], *refframe[3], *auxframe[3];
+ unsigned char *llframe0[3], *llframe1[3];
+ unsigned char *mpeg3_zigzag_scan_table;
+ unsigned char *mpeg3_alternate_scan_table;
+// Source for the next frame presentation
+ unsigned char **output_src;
+/* Pointers to frame buffers. */
+ unsigned char *newframe[3];
+ int horizontal_size, vertical_size, mb_width, mb_height;
+ int coded_picture_width, coded_picture_height;
+ int chroma_format, chrom_width, chrom_height, blk_cnt;
+ int pict_type;
+ int forw_r_size, back_r_size, full_forw, full_back;
+ int prog_seq, prog_frame;
+ int h_forw_r_size, v_forw_r_size, h_back_r_size, v_back_r_size;
+ int dc_prec, pict_struct, topfirst, frame_pred_dct, conceal_mv;
+ int intravlc;
+ int repeatfirst;
+ int repeat_count; /* Number of times to repeat the current frame * 100 since floating point is impossible in MMX */
+ int current_repeat; /* Number of times the current frame has been repeated * 100 */
+ int secondfield;
+ int skip_bframes;
+ int stwc_table_index, llw, llh, hm, hn, vm, vn;
+ int lltempref, llx0, lly0, llprog_frame, llfieldsel;
+ int matrix_coefficients;
+ int framerate_code;
+ float frame_rate;
+ long *cr_to_r, *cr_to_g, *cb_to_g, *cb_to_b;
+ long *cr_to_r_ptr, *cr_to_g_ptr, *cb_to_g_ptr, *cb_to_b_ptr;
+ int have_mmx;
+ int intra_quantizer_matrix[64], non_intra_quantizer_matrix[64];
+ int chroma_intra_quantizer_matrix[64], chroma_non_intra_quantizer_matrix[64];
+ int mpeg2;
+ int qscale_type, altscan; /* picture coding extension */
+ int pict_scal; /* picture spatial scalable extension */
+ int scalable_mode; /* sequence scalable extension */
+};
+
+typedef struct mpeg3video_rec mpeg3video_t;
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/video/mpeg3videoprotos.h b/core/multimedia/opieplayer/libmpeg3/video/mpeg3videoprotos.h
new file mode 100644
index 0000000..e48d6cd
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/mpeg3videoprotos.h
@@ -0,0 +1,26 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEG3VIDEOPROTOS_H
+#define MPEG3VIDEOPROTOS_H
+
+void mpeg3video_idct_conversion(short* block);
+unsigned int mpeg3slice_showbits(mpeg3_slice_buffer_t *slice_buffer, int bits);
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/video/output.c b/core/multimedia/opieplayer/libmpeg3/video/output.c
new file mode 100644
index 0000000..919a0ff
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/output.c
@@ -0,0 +1,993 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include <string.h>
+
+static LONGLONG mpeg3_MMX_0 = 0L;
+static unsigned long mpeg3_MMX_10w[] = {0x00100010, 0x00100010}; /*dd 00010 0010h, 000100010h */
+static unsigned long mpeg3_MMX_80w[] = {0x00800080, 0x00800080}; /*dd 00080 0080h, 000800080h */
+
+static unsigned long mpeg3_MMX_00FFw[] = {0x00ff00ff, 0x00ff00ff}; /*dd 000FF 00FFh, 000FF00FFh */
+
+static unsigned short mpeg3_MMX_Ublucoeff[] = {0x81, 0x81, 0x81, 0x81}; /*dd 00081 0081h, 000810081h */
+static unsigned short mpeg3_MMX_Vredcoeff[] = {0x66, 0x66, 0x66, 0x66}; /*dd 00066 0066h, 000660066h */
+
+static unsigned short mpeg3_MMX_Ugrncoeff[] = {0xffe8, 0xffe8, 0xffe8, 0xffe8}; /*dd 0FFE7 FFE7h, 0FFE7FFE7h */
+static unsigned short mpeg3_MMX_Vgrncoeff[] = {0xffcd, 0xffcd, 0xffcd, 0xffcd}; /*dd 0FFCC FFCCh, 0FFCCFFCCh */
+
+static unsigned short mpeg3_MMX_Ycoeff[] = {0x4a, 0x4a, 0x4a, 0x4a}; /*dd 0004A 004Ah, 0004A004Ah */
+
+static unsigned short mpeg3_MMX_redmask[] = {0xf800, 0xf800, 0xf800, 0xf800}; /*dd 07c00 7c00h, 07c007c00h */
+
+static unsigned short mpeg3_MMX_grnmask[] = {0x7e0, 0x7e0, 0x7e0, 0x7e0}; /*dd 003e0 03e0h, 003e003e0h */
+
+static unsigned char mpeg3_601_to_rgb[256];
+
+/* Algorithm */
+/* r = (int)(*y + 1.371 * (*cr - 128)); */
+/* g = (int)(*y - 0.698 * (*cr - 128) - 0.336 * (*cb - 128)); */
+/* b = (int)(*y + 1.732 * (*cb - 128)); */
+
+#ifdef HAVE_MMX
+inline void mpeg3video_rgb16_mmx(unsigned char *lum,
+ unsigned char *cr,
+ unsigned char *cb,
+ unsigned char *out,
+ int rows,
+ int cols,
+ int mod)
+{
+ unsigned short *row1;
+ int x;
+ unsigned char *y;
+ int col1;
+
+ row1 = (unsigned short *)out;
+ col1 = cols + mod;
+ mod += cols + mod;
+ mod *= 2;
+ y = lum + cols * rows;
+ x = 0;
+
+ __asm__ __volatile__(
+ ".align 8\n"
+ "1:\n"
+ "movd (%1), %%mm0\n" /* 4 Cb 0 0 0 0 u3 u2 u1 u0 */
+ "pxor %%mm7, %%mm7\n"
+ "movd (%0), %%mm1\n" /* 4 Cr 0 0 0 0 v3 v2 v1 v0 */
+ "punpcklbw %%mm7, %%mm0\n" /* 4 W cb 0 u3 0 u2 0 u1 0 u0 */
+ "punpcklbw %%mm7, %%mm1\n" /* 4 W cr 0 v3 0 v2 0 v1 0 v0 */
+
+ "psubw mpeg3_MMX_80w, %%mm0\n"
+ "psubw mpeg3_MMX_80w, %%mm1\n"
+ "movq %%mm0, %%mm2\n" /* Cb 0 u3 0 u2 0 u1 0 u0 */
+ "movq %%mm1, %%mm3\n" /* Cr */
+ "pmullw mpeg3_MMX_Ugrncoeff, %%mm2\n" /* Cb2green 0 R3 0 R2 0 R1 0 R0 */
+ "movq (%2), %%mm6\n" /* L1 l7 L6 L5 L4 L3 L2 L1 L0 */
+ "pmullw mpeg3_MMX_Ublucoeff, %%mm0\n" /* Cb2blue */
+ "pand mpeg3_MMX_00FFw, %%mm6\n" /* L1 00 L6 00 L4 00 L2 00 L0 */
+ "pmullw mpeg3_MMX_Vgrncoeff, %%mm3\n" /* Cr2green */
+ "movq (%2), %%mm7\n" /* L2 */
+ "pmullw mpeg3_MMX_Vredcoeff, %%mm1\n" /* Cr2red */
+ "psrlw $8, %%mm7\n" /* L2 00 L7 00 L5 00 L3 00 L1 */
+ "pmullw mpeg3_MMX_Ycoeff, %%mm6\n" /* lum1 */
+ "paddw %%mm3, %%mm2\n" /* Cb2green + Cr2green == green */
+ "pmullw mpeg3_MMX_Ycoeff, %%mm7\n" /* lum2 */
+
+ "movq %%mm6, %%mm4\n" /* lum1 */
+ "paddw %%mm0, %%mm6\n" /* lum1 +blue 00 B6 00 B4 00 B2 00 B0 */
+ "movq %%mm4, %%mm5\n" /* lum1 */
+ "paddw %%mm1, %%mm4\n" /* lum1 +red 00 R6 00 R4 00 R2 00 R0 */
+ "paddw %%mm2, %%mm5\n" /* lum1 +green 00 G6 00 G4 00 G2 00 G0 */
+ "psraw $6, %%mm4\n" /* R1 0 .. 64 */
+ "movq %%mm7, %%mm3\n" /* lum2 00 L7 00 L5 00 L3 00 L1 */
+ "psraw $6, %%mm5\n" /* G1 - .. + */
+ "paddw %%mm0, %%mm7\n" /* Lum2 +blue 00 B7 00 B5 00 B3 00 B1 */
+ "psraw $6, %%mm6\n" /* B1 0 .. 64 */
+ "packuswb %%mm4, %%mm4\n" /* R1 R1 */
+ "packuswb %%mm5, %%mm5\n" /* G1 G1 */
+ "packuswb %%mm6, %%mm6\n" /* B1 B1 */
+ "punpcklbw %%mm4, %%mm4\n"
+ "punpcklbw %%mm5, %%mm5\n"
+
+ "pand mpeg3_MMX_redmask, %%mm4\n"
+ "psllw $3, %%mm5\n" /* GREEN 1 */
+ "punpcklbw %%mm6, %%mm6\n"
+ "pand mpeg3_MMX_grnmask, %%mm5\n"
+ "pand mpeg3_MMX_redmask, %%mm6\n"
+ "por %%mm5, %%mm4\n" /* */
+ "psrlw $11, %%mm6\n" /* BLUE 1 */
+ "movq %%mm3, %%mm5\n" /* lum2 */
+ "paddw %%mm1, %%mm3\n" /* lum2 +red 00 R7 00 R5 00 R3 00 R1 */
+ "paddw %%mm2, %%mm5\n" /* lum2 +green 00 G7 00 G5 00 G3 00 G1 */
+ "psraw $6, %%mm3\n" /* R2 */
+ "por %%mm6, %%mm4\n" /* MM4 */
+ "psraw $6, %%mm5\n" /* G2 */
+ "movq (%2, %3), %%mm6\n" /* L3 */
+ "psraw $6, %%mm7\n"
+ "packuswb %%mm3, %%mm3\n"
+ "packuswb %%mm5, %%mm5\n"
+ "packuswb %%mm7, %%mm7\n"
+ "pand mpeg3_MMX_00FFw, %%mm6\n" /* L3 */
+ "punpcklbw %%mm3, %%mm3\n"
+ "punpcklbw %%mm5, %%mm5\n"
+ "pmullw mpeg3_MMX_Ycoeff, %%mm6\n" /* lum3 */
+ "punpcklbw %%mm7, %%mm7\n"
+ "psllw $3, %%mm5\n" /* GREEN 2 */
+ "pand mpeg3_MMX_redmask, %%mm7\n"
+ "pand mpeg3_MMX_redmask, %%mm3\n"
+ "psrlw $11, %%mm7\n" /* BLUE 2 */
+ "pand mpeg3_MMX_grnmask, %%mm5\n"
+ "por %%mm7, %%mm3\n"
+ "movq (%2,%3), %%mm7\n" /* L4 */
+ "por %%mm5, %%mm3\n" /* */
+ "psrlw $8, %%mm7\n" /* L4 */
+ "movq %%mm4, %%mm5\n"
+ "punpcklwd %%mm3, %%mm4\n"
+ "pmullw mpeg3_MMX_Ycoeff, %%mm7\n" /* lum4 */
+ "punpckhwd %%mm3, %%mm5\n"
+
+ "movq %%mm4, (%4)\n"
+ "movq %%mm5, 8(%4)\n"
+
+ "movq %%mm6, %%mm4\n" /* Lum3 */
+ "paddw %%mm0, %%mm6\n" /* Lum3 +blue */
+
+ "movq %%mm4, %%mm5\n" /* Lum3 */
+ "paddw %%mm1, %%mm4\n" /* Lum3 +red */
+ "paddw %%mm2, %%mm5\n" /* Lum3 +green */
+ "psraw $6, %%mm4\n"
+ "movq %%mm7, %%mm3\n" /* Lum4 */
+ "psraw $6, %%mm5\n"
+ "paddw %%mm0, %%mm7\n" /* Lum4 +blue */
+ "psraw $6, %%mm6\n" /* Lum3 +blue */
+ "movq %%mm3, %%mm0\n" /* Lum4 */
+ "packuswb %%mm4, %%mm4\n"
+ "paddw %%mm1, %%mm3\n" /* Lum4 +red */
+ "packuswb %%mm5, %%mm5\n"
+ "paddw %%mm2, %%mm0\n" /* Lum4 +green */
+ "packuswb %%mm6, %%mm6\n"
+ "punpcklbw %%mm4, %%mm4\n"
+ "punpcklbw %%mm5, %%mm5\n"
+ "punpcklbw %%mm6, %%mm6\n"
+ "psllw $3, %%mm5\n" /* GREEN 3 */
+ "pand mpeg3_MMX_redmask, %%mm4\n"
+ "psraw $6, %%mm3\n" /* psr 6 */
+ "psraw $6, %%mm0\n"
+ "pand mpeg3_MMX_redmask, %%mm6\n" /* BLUE */
+ "pand mpeg3_MMX_grnmask, %%mm5\n"
+ "psrlw $11, %%mm6\n" /* BLUE 3 */
+ "por %%mm5, %%mm4\n"
+ "psraw $6, %%mm7\n"
+ "por %%mm6, %%mm4\n"
+ "packuswb %%mm3, %%mm3\n"
+ "packuswb %%mm0, %%mm0\n"
+ "packuswb %%mm7, %%mm7\n"
+ "punpcklbw %%mm3, %%mm3\n"
+ "punpcklbw %%mm0, %%mm0\n"
+ "punpcklbw %%mm7, %%mm7\n"
+ "pand mpeg3_MMX_redmask, %%mm3\n"
+ "pand mpeg3_MMX_redmask, %%mm7\n" /* BLUE */
+ "psllw $3, %%mm0\n" /* GREEN 4 */
+ "psrlw $11, %%mm7\n"
+ "pand mpeg3_MMX_grnmask, %%mm0\n"
+ "por %%mm7, %%mm3\n"
+ "addl $8, %6\n"
+ "por %%mm0, %%mm3\n"
+
+ "movq %%mm4, %%mm5\n"
+
+ "punpcklwd %%mm3, %%mm4\n"
+ "punpckhwd %%mm3, %%mm5\n"
+
+ "movq %%mm4, (%4,%5,2)\n"
+ "movq %%mm5, 8(%4,%5,2)\n"
+
+ "addl $8, %2\n"
+ "addl $4, %0\n"
+ "addl $4, %1\n"
+ "cmpl %3, %6\n"
+ "leal 16(%4), %4\n"
+ "jl 1b\n"
+ "addl %3, %2\n" /* lum += cols */
+ "addl %7, %4\n" /* row1 += mod */
+ "movl $0, %6\n"
+ "cmpl %8, %2\n"
+ "jl 1b\n"
+ : : "r" (cr),
+ "r" (cb),
+ "r" (lum),
+ "r" (cols),
+ "r" (row1) ,
+ "r" (col1),
+ "m" (x),
+ "m" (mod),
+ "m" (y)
+ );
+}
+
+static unsigned LONGLONG mpeg3_MMX_U_80 = 0x0000008000800000LL;
+static unsigned LONGLONG mpeg3_MMX_V_80 = 0x0000000000800080LL;
+static LONGLONG mpeg3_MMX_U_COEF = 0x00000058ffd30000LL;
+static LONGLONG mpeg3_MMX_V_COEF = 0x00000000ffea006fLL;
+static LONGLONG mpeg3_MMX_601_Y_COEF = 0x0000004800480048LL;
+static LONGLONG mpeg3_MMX_601_Y_DIFF = 0x0000000000000010LL;
+
+inline void mpeg3_bgra32_mmx(unsigned long y,
+ unsigned long u,
+ unsigned long v,
+ unsigned long *output)
+{
+asm("
+/* Output will be 0x00rrggbb with the 00 trailing so this can also be used */
+/* for bgr24. */
+ movd (%0), %%mm0; /* Load y 0x00000000000000yy */
+ movd (%1), %%mm1; /* Load u 0x00000000000000cr */
+ movq %%mm0, %%mm3; /* Copy y to temp */
+ psllq $16, %%mm1; /* Shift u 0x0000000000cr0000 */
+ movd (%2), %%mm2; /* Load v 0x00000000000000cb */
+ psllq $16, %%mm3; /* Shift y */
+ movq %%mm1, %%mm4; /* Copy u to temp */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */
+ psllq $16, %%mm4; /* Shift u */
+ movq %%mm2, %%mm5; /* Copy v to temp */
+ psllq $16, %%mm3; /* Shift y */
+ por %%mm4, %%mm1; /* Overlay new u byte 0x000000cr00cr0000 */
+ psllq $16, %%mm5; /* Shift v */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */
+ por %%mm5, %%mm2; /* Overlay new v byte 0x0000000000cb00cb */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x000000uu00uu0000 mm2: 0x0000000000vv00vv */
+ psubw mpeg3_MMX_U_80, %%mm1; /* Subtract 128 from u 0x000000uu00uu0000 */
+ pmullw mpeg3_MMX_U_COEF, %%mm1; /* Multiply u coeffs 0x0000uuuuuuuu0000 */
+ psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */
+ psubw mpeg3_MMX_V_80, %%mm2; /* Subtract 128 from v 0x0000000000cb00cb */
+ pmullw mpeg3_MMX_V_COEF, %%mm2; /* Multiply v coeffs 0x0000crcrcrcrcrcr */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x0000uuuuuuuu0000 mm2: 0x00000000vvvvvvvv */
+ paddsw %%mm1, %%mm0; /* Add u to result */
+ paddsw %%mm2, %%mm0; /* Add v to result 0x0000rrrrggggbbbb */
+ psraw $6, %%mm0; /* Demote precision */
+ packuswb %%mm0, %%mm0; /* Pack into ARGB 0x0000000000rrggbb */
+ movd %%mm0, (%3); /* Store output */
+ "
+:
+: "r" (&y), "r" (&u), "r" (&v), "r" (output));
+}
+
+inline void mpeg3_601_bgra32_mmx(unsigned long y,
+ unsigned long u,
+ unsigned long v,
+ unsigned long *output)
+{
+asm("
+/* Output will be 0x00rrggbb with the 00 trailing so this can also be used */
+/* for bgr24. */
+ movd (%0), %%mm0; /* Load y 0x00000000000000yy */
+ psubsw mpeg3_MMX_601_Y_DIFF, %%mm0; /* Subtract 16 from y */
+ movd (%1), %%mm1; /* Load u 0x00000000000000cr */
+ movq %%mm0, %%mm3; /* Copy y to temp */
+ psllq $16, %%mm1; /* Shift u 0x0000000000cr0000 */
+ movd (%2), %%mm2; /* Load v 0x00000000000000cb */
+ psllq $16, %%mm3; /* Shift y */
+ movq %%mm1, %%mm4; /* Copy u to temp */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */
+ psllq $16, %%mm4; /* Shift u */
+ movq %%mm2, %%mm5; /* Copy v to temp */
+ psllq $16, %%mm3; /* Shift y */
+ por %%mm4, %%mm1; /* Overlay new u byte 0x000000cr00cr0000 */
+ psllq $16, %%mm5; /* Shift v */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */
+ por %%mm5, %%mm2; /* Overlay new v byte 0x0000000000cb00cb */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x000000uu00uu0000 mm2: 0x0000000000vv00vv */
+ pmullw mpeg3_MMX_601_Y_COEF, %%mm0; /* Scale and shift y coeffs */
+ psubw mpeg3_MMX_U_80, %%mm1; /* Subtract 128 from u 0x000000uu00uu0000 */
+ pmullw mpeg3_MMX_U_COEF, %%mm1; /* Multiply u coeffs 0x0000uuuuuuuu0000 */
+ psubw mpeg3_MMX_V_80, %%mm2; /* Subtract 128 from v 0x0000000000cb00cb */
+ pmullw mpeg3_MMX_V_COEF, %%mm2; /* Multiply v coeffs 0x0000crcrcrcrcrcr */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x0000uuuuuuuu0000 mm2: 0x00000000vvvvvvvv */
+ paddsw %%mm1, %%mm0; /* Add u to result */
+ paddsw %%mm2, %%mm0; /* Add v to result 0x0000rrrrggggbbbb */
+ psraw $6, %%mm0; /* Demote precision */
+ packuswb %%mm0, %%mm0; /* Pack into ARGB 0x0000000000rrggbb */
+ movd %%mm0, (%3); /* Store output */
+ "
+:
+: "r" (&y), "r" (&u), "r" (&v), "r" (output));
+}
+
+static unsigned LONGLONG mpeg3_MMX_U_80_RGB = 0x0000000000800080LL;
+static unsigned LONGLONG mpeg3_MMX_V_80_RGB = 0x0000008000800000LL;
+static LONGLONG mpeg3_MMX_U_COEF_RGB = 0x00000000ffd30058LL;
+static LONGLONG mpeg3_MMX_V_COEF_RGB = 0x0000006fffea0000LL;
+
+inline void mpeg3_rgba32_mmx(unsigned long y,
+ unsigned long u,
+ unsigned long v,
+ unsigned long *output)
+{
+asm("
+/* Output will be 0x00bbggrr with the 00 trailing so this can also be used */
+/* for rgb24. */
+ movd (%0), %%mm0; /* Load y 0x00000000000000yy */
+ movd (%1), %%mm1; /* Load v 0x00000000000000vv */
+ movq %%mm0, %%mm3; /* Copy y to temp */
+ psllq $16, %%mm1; /* Shift v 0x0000000000vv0000 */
+ movd (%2), %%mm2; /* Load u 0x00000000000000uu */
+ psllq $16, %%mm3; /* Shift y */
+ movq %%mm1, %%mm4; /* Copy v to temp */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */
+ psllq $16, %%mm4; /* Shift v */
+ movq %%mm2, %%mm5; /* Copy u to temp */
+ psllq $16, %%mm3; /* Shift y */
+ por %%mm4, %%mm1; /* Overlay new v byte 0x000000vv00vv0000 */
+ psllq $16, %%mm5; /* Shift u */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */
+ por %%mm5, %%mm2; /* Overlay new u byte 0x0000000000uu00uu */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x000000vv00vv0000 mm2: 0x0000000000uu00uu */
+ psubw mpeg3_MMX_V_80_RGB, %%mm1; /* Subtract 128 from v 0x000000vv00vv0000 */
+ pmullw mpeg3_MMX_V_COEF_RGB, %%mm1; /* Multiply v coeffs 0x0000vvvvvvvv0000 */
+ psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */
+ psubw mpeg3_MMX_U_80_RGB, %%mm2; /* Subtract 128 from u 0x0000000000uu00uu */
+ pmullw mpeg3_MMX_U_COEF_RGB, %%mm2; /* Multiply u coeffs 0x0000uuuuuuuuuuuu */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x0000vvvvvvvv0000 mm2: 0x00000000uuuuuuuu */
+ paddsw %%mm1, %%mm0; /* Add v to result */
+ paddsw %%mm2, %%mm0; /* Add u to result 0x0000bbbbggggrrrr */
+ psraw $6, %%mm0; /* Demote precision */
+ packuswb %%mm0, %%mm0; /* Pack into RGBA 0x0000000000bbggrr */
+ movd %%mm0, (%3); /* Store output */
+ "
+:
+: "r" (&y), "r" (&v), "r" (&u), "r" (output));
+}
+
+inline void mpeg3_601_rgba32_mmx(unsigned long y,
+ unsigned long u,
+ unsigned long v,
+ unsigned long *output)
+{
+asm("
+/* Output will be 0x00bbggrr with the 00 trailing so this can also be used */
+/* for rgb24. */
+ movd (%0), %%mm0; /* Load y 0x00000000000000yy */
+ psubsw mpeg3_MMX_601_Y_DIFF, %%mm0; /* Subtract 16 from y */
+ movd (%1), %%mm1; /* Load v 0x00000000000000vv */
+ movq %%mm0, %%mm3; /* Copy y to temp */
+ psllq $16, %%mm1; /* Shift v 0x0000000000vv0000 */
+ movd (%2), %%mm2; /* Load u 0x00000000000000uu */
+ psllq $16, %%mm3; /* Shift y */
+ movq %%mm1, %%mm4; /* Copy v to temp */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x0000000000yy00yy */
+ psllq $16, %%mm4; /* Shift v */
+ movq %%mm2, %%mm5; /* Copy u to temp */
+ psllq $16, %%mm3; /* Shift y */
+ por %%mm4, %%mm1; /* Overlay new v byte 0x000000vv00vv0000 */
+ psllq $16, %%mm5; /* Shift u */
+ por %%mm3, %%mm0; /* Overlay new y byte 0x000000yy00yy00yy */
+ por %%mm5, %%mm2; /* Overlay new u byte 0x0000000000uu00uu */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x000000vv00vv0000 mm2: 0x0000000000uu00uu */
+ pmullw mpeg3_MMX_601_Y_COEF, %%mm0; /* Scale y coeffs */
+ psubw mpeg3_MMX_V_80_RGB, %%mm1; /* Subtract 128 from v 0x000000vv00vv0000 */
+ pmullw mpeg3_MMX_V_COEF_RGB, %%mm1; /* Multiply v coeffs 0x0000vvvvvvvv0000 */
+ psubw mpeg3_MMX_U_80_RGB, %%mm2; /* Subtract 128 from u 0x0000000000uu00uu */
+ pmullw mpeg3_MMX_U_COEF_RGB, %%mm2; /* Multiply u coeffs 0x0000uuuuuuuuuuuu */
+
+/* mm0: 0x000000yy00yy00yy mm1: 0x0000vvvvvvvv0000 mm2: 0x00000000uuuuuuuu */
+ paddsw %%mm1, %%mm0; /* Add v to result */
+ paddsw %%mm2, %%mm0; /* Add u to result 0x0000bbbbggggrrrr */
+ psraw $6, %%mm0; /* Demote precision */
+ packuswb %%mm0, %%mm0; /* Pack into RGBA 0x0000000000bbggrr */
+ movd %%mm0, (%3); /* Store output */
+ "
+:
+: "r" (&y), "r" (&v), "r" (&u), "r" (output));
+}
+
+#endif
+
+#define DITHER_ROW_HEAD \
+ for(h = 0; h < video->out_h; h++) \
+ { \
+ y_in = &src[0][(video->y_table[h] + video->in_y) * video->coded_picture_width] + video->in_x; \
+ cb_in = &src[1][((video->y_table[h] + video->in_y) >> 1) * video->chrom_width] + (video->in_x >> 2); \
+ cr_in = &src[2][((video->y_table[h] + video->in_y) >> 1) * video->chrom_width] + (video->in_x >> 1); \
+ data = output_rows[h];
+
+#define DITHER_ROW_TAIL \
+ }
+
+#define DITHER_SCALE_HEAD \
+ for(w = 0; w < video->out_w; w++) \
+ { \
+ uv_subscript = video->x_table[w] / 2; \
+ y_l = y_in[video->x_table[w]]; \
+ y_l <<= 16; \
+ r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \
+ g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \
+ b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16;
+
+#define DITHER_SCALE_601_HEAD \
+ for(w = 0; w < video->out_w; w++) \
+ { \
+ uv_subscript = video->x_table[w] / 2; \
+ y_l = mpeg3_601_to_rgb[y_in[video->x_table[w]]]; \
+ y_l <<= 16; \
+ r_l = (y_l + video->cr_to_r[cr_in[uv_subscript]]) >> 16; \
+ g_l = (y_l + video->cr_to_g[cr_in[uv_subscript]] + video->cb_to_g[cb_in[uv_subscript]]) >> 16; \
+ b_l = (y_l + video->cb_to_b[cb_in[uv_subscript]]) >> 16;
+
+#define DITHER_SCALE_TAIL \
+ }
+
+#define DITHER_MMX_SCALE_HEAD \
+ for(w = 0; w < video->out_w; w++) \
+ { \
+ uv_subscript = video->x_table[w] / 2;
+
+#define DITHER_MMX_SCALE_TAIL \
+ data += step; \
+ }
+
+#define DITHER_MMX_HEAD \
+ for(w = 0; w < video->out_w; w += 2) \
+ {
+
+#define DITHER_MMX_TAIL \
+ data += step; \
+ cr_in++; \
+ cb_in++; \
+ }
+
+#define DITHER_HEAD \
+ for(w = 0; w < video->horizontal_size; w++) \
+ { \
+ y_l = *y_in++; \
+ y_l <<= 16; \
+ r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \
+ g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \
+ b_l = (y_l + video->cb_to_b[*cb_in]) >> 16;
+
+#define DITHER_601_HEAD \
+ for(w = 0; w < video->horizontal_size; w++) \
+ { \
+ y_l = mpeg3_601_to_rgb[*y_in++]; \
+ y_l <<= 16; \
+ r_l = (y_l + video->cr_to_r[*cr_in]) >> 16; \
+ g_l = (y_l + video->cr_to_g[*cr_in] + video->cb_to_g[*cb_in]) >> 16; \
+ b_l = (y_l + video->cb_to_b[*cb_in]) >> 16;
+
+#define DITHER_TAIL \
+ if(w & 1) \
+ { \
+ cr_in++; \
+ cb_in++; \
+ } \
+ }
+
+
+#define STORE_PIXEL_BGR888 \
+ *data++ = CLIP(b_l); \
+ *data++ = CLIP(g_l); \
+ *data++ = CLIP(r_l);
+
+#define STORE_PIXEL_BGRA8888 \
+ *data++ = CLIP(b_l); \
+ *data++ = CLIP(g_l); \
+ *data++ = CLIP(r_l); \
+ *data++ = 0;
+
+#define STORE_PIXEL_RGB565 \
+ *((unsigned short*)data)++ = \
+ ((CLIP(r_l) & 0xf8) << 8) | \
+ ((CLIP(g_l) & 0xfc) << 3) | \
+ ((CLIP(b_l) & 0xf8) >> 3);
+
+#define STORE_PIXEL_RGB888 \
+ *data++ = CLIP(r_l); \
+ *data++ = CLIP(g_l); \
+ *data++ = CLIP(b_l);
+
+#define STORE_PIXEL_RGBA8888 \
+ *data++ = CLIP(r_l); \
+ *data++ = CLIP(g_l); \
+ *data++ = CLIP(b_l); \
+ *data++ = 0;
+
+#define STORE_PIXEL_RGBA16161616 \
+ *data_s++ = CLIP(r_l); \
+ *data_s++ = CLIP(g_l); \
+ *data_s++ = CLIP(b_l); \
+ *data_s++ = 0;
+
+
+
+/* Only good for YUV 4:2:0 */
+int mpeg3video_ditherframe(mpeg3video_t *video, unsigned char **src, unsigned char **output_rows)
+{
+ int h = 0;
+ register unsigned char *y_in, *cb_in, *cr_in;
+ long y_l, r_l, b_l, g_l;
+ register unsigned char *data;
+ register int uv_subscript, step, w = -1;
+
+#ifdef HAVE_MMX
+/* =================================== MMX ===================================== */
+ if(video->have_mmx &&
+ video->out_w == video->horizontal_size &&
+ video->out_h == video->vertical_size &&
+ video->in_w == video->out_w &&
+ video->in_h == video->out_h &&
+ video->in_x == 0 &&
+ video->in_y == 0 &&
+ (video->color_model == MPEG3_RGB565 || video->color_model == MPEG3_601_RGB565))
+ {
+/* Unscaled 16 bit */
+ mpeg3video_rgb16_mmx(src[0],
+ src[2],
+ src[1],
+ output_rows[0],
+ video->out_h,
+ video->out_w,
+ (output_rows[1] - output_rows[0]) / 2 - video->out_w);
+ }
+ else
+ if(video->have_mmx &&
+ (video->color_model == MPEG3_BGRA8888 ||
+ video->color_model == MPEG3_BGR888 ||
+/* video->color_model == MPEG3_RGB888 || */
+ video->color_model == MPEG3_RGBA8888 ||
+ video->color_model == MPEG3_601_BGR888 ||
+ video->color_model == MPEG3_601_BGRA8888 ||
+ video->color_model == MPEG3_601_RGB888 ||
+ video->color_model == MPEG3_601_RGBA8888))
+ {
+/* Original MMX */
+ if(video->color_model == MPEG3_BGRA8888 ||
+ video->color_model == MPEG3_RGBA8888 ||
+ video->color_model == MPEG3_601_BGRA8888 ||
+ video->color_model == MPEG3_601_RGBA8888) step = 4;
+ else
+ if(video->color_model == MPEG3_BGR888 ||
+ video->color_model == MPEG3_RGB888 ||
+ video->color_model == MPEG3_601_BGR888 ||
+ video->color_model == MPEG3_601_RGB888) step = 3;
+
+ DITHER_ROW_HEAD
+/* Transfer row with scaling */
+ if(video->out_w != video->horizontal_size)
+ {
+ switch(video->color_model)
+ {
+ case MPEG3_BGRA8888:
+ case MPEG3_BGR888:
+ DITHER_MMX_SCALE_HEAD
+ mpeg3_bgra32_mmx(y_in[video->x_table[w]],
+ cr_in[uv_subscript],
+ cb_in[uv_subscript],
+ (unsigned long*)data);
+ DITHER_MMX_SCALE_TAIL
+ break;
+
+ case MPEG3_601_BGRA8888:
+ case MPEG3_601_BGR888:
+ DITHER_MMX_SCALE_HEAD
+ mpeg3_601_bgra32_mmx(y_in[video->x_table[w]],
+ cr_in[uv_subscript],
+ cb_in[uv_subscript],
+ (unsigned long*)data);
+ DITHER_MMX_SCALE_TAIL
+ break;
+
+ case MPEG3_RGBA8888:
+ case MPEG3_RGB888:
+ DITHER_MMX_SCALE_HEAD
+ mpeg3_rgba32_mmx(y_in[video->x_table[w]],
+ cr_in[uv_subscript],
+ cb_in[uv_subscript],
+ (unsigned long*)data);
+ DITHER_MMX_SCALE_TAIL
+ break;
+
+ case MPEG3_601_RGBA8888:
+ case MPEG3_601_RGB888:
+ DITHER_MMX_SCALE_HEAD
+ mpeg3_601_rgba32_mmx(y_in[video->x_table[w]],
+ cr_in[uv_subscript],
+ cb_in[uv_subscript],
+ (unsigned long*)data);
+ DITHER_MMX_SCALE_TAIL
+ break;
+ }
+ }
+ else
+/* Transfer row unscaled */
+ {
+ switch(video->color_model)
+ {
+/* MMX byte swap 24 and 32 bit */
+ case MPEG3_BGRA8888:
+ case MPEG3_BGR888:
+ DITHER_MMX_HEAD
+ mpeg3_bgra32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ data += step;
+ mpeg3_bgra32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ DITHER_MMX_TAIL
+ break;
+
+/* MMX 601 byte swap 24 and 32 bit */
+ case MPEG3_601_BGRA8888:
+ case MPEG3_601_BGR888:
+ DITHER_MMX_HEAD
+ mpeg3_601_bgra32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ data += step;
+ mpeg3_601_bgra32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ DITHER_MMX_TAIL
+ break;
+
+/* MMX 24 and 32 bit no byte swap */
+ case MPEG3_RGBA8888:
+ case MPEG3_RGB888:
+ DITHER_MMX_HEAD
+ mpeg3_rgba32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ data += step;
+ mpeg3_rgba32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ DITHER_MMX_TAIL
+ break;
+
+/* MMX 601 24 and 32 bit no byte swap */
+ case MPEG3_601_RGBA8888:
+ case MPEG3_601_RGB888:
+ DITHER_MMX_HEAD
+ mpeg3_601_rgba32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ data += step;
+ mpeg3_601_rgba32_mmx(*y_in++,
+ *cr_in,
+ *cb_in,
+ (unsigned long*)data);
+ DITHER_MMX_TAIL
+ break;
+ }
+ }
+ DITHER_ROW_TAIL
+ }
+ else
+#endif
+/* ================================== NO MMX ==================================== */
+ {
+ DITHER_ROW_HEAD
+/* Transfer row with scaling */
+ if(video->out_w != video->horizontal_size)
+ {
+ switch(video->color_model)
+ {
+ case MPEG3_BGR888:
+ DITHER_SCALE_HEAD
+ STORE_PIXEL_BGR888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_BGRA8888:
+ DITHER_SCALE_HEAD
+ STORE_PIXEL_BGRA8888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_RGB565:
+ DITHER_SCALE_HEAD
+ STORE_PIXEL_RGB565
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_RGB888:
+ DITHER_SCALE_HEAD
+ STORE_PIXEL_RGB888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_RGBA8888:
+ DITHER_SCALE_HEAD
+ STORE_PIXEL_RGBA8888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_601_BGR888:
+ DITHER_SCALE_601_HEAD
+ STORE_PIXEL_BGR888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_601_BGRA8888:
+ DITHER_SCALE_601_HEAD
+ STORE_PIXEL_BGRA8888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_601_RGB565:
+ DITHER_SCALE_601_HEAD
+ STORE_PIXEL_RGB565
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_601_RGB888:
+ DITHER_SCALE_601_HEAD
+ STORE_PIXEL_RGB888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_601_RGBA8888:
+ DITHER_SCALE_601_HEAD
+ STORE_PIXEL_RGBA8888
+ DITHER_SCALE_TAIL
+ break;
+ case MPEG3_RGBA16161616:
+ {
+ register unsigned short *data_s = (unsigned short*)data;
+ DITHER_SCALE_HEAD
+ STORE_PIXEL_RGBA16161616
+ DITHER_SCALE_TAIL
+ }
+ break;
+ }
+ }
+ else
+ {
+/* Transfer row unscaled */
+ switch(video->color_model)
+ {
+ case MPEG3_BGR888:
+ DITHER_HEAD
+ STORE_PIXEL_BGR888
+ DITHER_TAIL
+ break;
+ case MPEG3_BGRA8888:
+ DITHER_HEAD
+ STORE_PIXEL_BGRA8888
+ DITHER_TAIL
+ break;
+ case MPEG3_RGB565:
+ DITHER_HEAD
+ STORE_PIXEL_RGB565
+ DITHER_TAIL
+ break;
+ case MPEG3_RGB888:
+ DITHER_HEAD
+ STORE_PIXEL_RGB888
+ DITHER_TAIL
+ break;
+ case MPEG3_RGBA8888:
+ DITHER_HEAD
+ STORE_PIXEL_RGBA8888
+ DITHER_TAIL
+ break;
+ case MPEG3_601_BGR888:
+ DITHER_601_HEAD
+ STORE_PIXEL_BGR888
+ DITHER_TAIL
+ break;
+ case MPEG3_601_BGRA8888:
+ DITHER_601_HEAD
+ STORE_PIXEL_RGB565
+ DITHER_TAIL
+ break;
+ case MPEG3_601_RGB565:
+ DITHER_601_HEAD
+ STORE_PIXEL_RGB565
+ DITHER_TAIL
+ break;
+ case MPEG3_601_RGB888:
+ DITHER_601_HEAD
+ STORE_PIXEL_RGB888
+ DITHER_TAIL
+ break;
+ case MPEG3_601_RGBA8888:
+ DITHER_601_HEAD
+ STORE_PIXEL_RGBA8888
+ DITHER_TAIL
+ break;
+ case MPEG3_RGBA16161616:
+ {
+ register unsigned short *data_s = (unsigned short*)data;
+ DITHER_HEAD
+ STORE_PIXEL_RGBA16161616
+ DITHER_TAIL
+ }
+ break;
+ }
+ }
+ DITHER_ROW_TAIL
+ } /* End of non-MMX */
+
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ __asm__ __volatile__ ("emms");
+#endif
+ return 0;
+}
+
+int mpeg3video_ditherframe444(mpeg3video_t *video, unsigned char *src[])
+{
+ return 0;
+}
+
+int mpeg3video_dithertop(mpeg3video_t *video, unsigned char *src[])
+{
+ return mpeg3video_ditherframe(video, src, video->output_rows);
+}
+
+int mpeg3video_dithertop444(mpeg3video_t *video, unsigned char *src[])
+{
+ return 0;
+}
+
+int mpeg3video_ditherbot(mpeg3video_t *video, unsigned char *src[])
+{
+ return 0;
+}
+
+int mpeg3video_ditherbot444(mpeg3video_t *video, unsigned char *src[])
+{
+ return 0;
+}
+
+void memcpy_fast(unsigned char *output, unsigned char *input, long len)
+{
+ int i, len2;
+/* 8 byte alignment */
+/*
+ * if(!((long)input & 0x7))
+ * {
+ * len2 = len >> 4;
+ * for(i = 0; i < len2; )
+ * {
+ * ((MPEG3_INT64*)output)[i] = ((MPEG3_INT64*)input)[i];
+ * i++;
+ * ((MPEG3_INT64*)output)[i] = ((MPEG3_INT64*)input)[i];
+ * i++;
+ * }
+ *
+ * for(i *= 16; i < len; i++)
+ * {
+ * output[i] = input[i];
+ * }
+ * }
+ * else
+ */
+ memcpy(output, input, len);
+}
+
+int mpeg3video_init_output()
+{
+ int i, value;
+ for(i = 0; i < 256; i++)
+ {
+ value = (int)(1.1644 * i - 255 * 0.0627 + 0.5);
+ if(value < 0) value = 0;
+ else
+ if(value > 255) value = 255;
+ mpeg3_601_to_rgb[i] = value;
+ }
+ return 0;
+}
+
+int mpeg3video_present_frame(mpeg3video_t *video)
+{
+ int i, j, k, l;
+ unsigned char **src = video->output_src;
+
+/* Copy YUV buffers */
+ if(video->want_yvu)
+ {
+ long size[2];
+ long offset[2];
+
+/* Drop a frame */
+ if(!video->y_output) return 0;
+
+/* Copy a frame */
+ if(video->in_x == 0 &&
+ video->in_w >= video->coded_picture_width)
+ {
+ size[0] = video->coded_picture_width * video->in_h;
+ size[1] = video->chrom_width * (int)((float)video->in_h / 2 + 0.5);
+ offset[0] = video->coded_picture_width * video->in_y;
+ offset[1] = video->chrom_width * (int)((float)video->in_y / 2 + 0.5);
+
+/*
+ * if(video->in_y > 0)
+ * {
+ * offset[1] += video->chrom_width / 2;
+ * size[1] += video->chrom_width / 2;
+ * }
+ */
+
+ memcpy(video->y_output, src[0] + offset[0], size[0]);
+ memcpy(video->u_output, src[1] + offset[1], size[1]);
+ memcpy(video->v_output, src[2] + offset[1], size[1]);
+ }
+ else
+ {
+ for(i = 0, j = video->in_y; i < video->in_h; i++, j++)
+ {
+ memcpy(video->y_output + i * video->in_w,
+ src[0] + j * video->coded_picture_width + video->in_x,
+ video->in_w);
+ memcpy(video->u_output + i * video->in_w / 4,
+ src[1] + j * video->chrom_width / 2 + video->in_x / 4,
+ video->in_w / 4);
+ memcpy(video->v_output + i * video->in_w / 4,
+ src[2] + j * video->chrom_width / 2 + video->in_x / 4,
+ video->in_w / 4);
+ }
+ }
+
+ return 0;
+ }
+
+/* Want RGB buffer */
+/* Copy the frame to the output with YUV to RGB conversion */
+ if(video->prog_seq)
+ {
+ if(video->chroma_format != CHROMA444)
+ {
+ mpeg3video_ditherframe(video, src, video->output_rows);
+ }
+ else
+ mpeg3video_ditherframe444(video, src);
+ }
+ else
+ {
+ if((video->pict_struct == FRAME_PICTURE && video->topfirst) ||
+ video->pict_struct == BOTTOM_FIELD)
+ {
+/* top field first */
+ if(video->chroma_format != CHROMA444)
+ {
+ mpeg3video_dithertop(video, src);
+ mpeg3video_ditherbot(video, src);
+ }
+ else
+ {
+ mpeg3video_dithertop444(video, src);
+ mpeg3video_ditherbot444(video, src);
+ }
+ }
+ else
+ {
+/* bottom field first */
+ if(video->chroma_format != CHROMA444)
+ {
+ mpeg3video_ditherbot(video, src);
+ mpeg3video_dithertop(video, src);
+ }
+ else
+ {
+ mpeg3video_ditherbot444(video, src);
+ mpeg3video_dithertop444(video, src);
+ }
+ }
+ }
+ return 0;
+}
+
+int mpeg3video_display_second_field(mpeg3video_t *video)
+{
+/* Not used */
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/video/reconmmx.s b/core/multimedia/opieplayer/libmpeg3/video/reconmmx.s
new file mode 100644
index 0000000..1bb98ef
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/reconmmx.s
@@ -0,0 +1,301 @@
+ADD_1: dd 01010101h, 01010101h
+MASK_AND: dd 7f7f7f7fh, 7f7f7f7fh
+PLUS_384: dd 01800180h, 01800180h
+PLUS_128: dd 00800080h, 00800080h
+
+%assign LocalFrameSize 0
+%assign RegisterStorageSize 16
+
+; Arguments:
+%assign source LocalFrameSize + RegisterStorageSize + 4
+%assign dest LocalFrameSize + RegisterStorageSize + 8
+%assign lx2 LocalFrameSize + RegisterStorageSize + 12
+%assign h LocalFrameSize + RegisterStorageSize + 16
+
+; Locals (on local stack frame)
+
+
+; extern void C rec_mmx (
+; unsigned char *source,
+; unsigned char *dest,
+; int lx2,
+; int h
+;
+; The local variables are on the stack,
+;
+
+global recva_mmx
+global recvac_mmx
+global rech_mmx
+global rechc_mmx
+global add_block_mmx
+global set_block_mmx
+
+
+ align 16
+rech_mmx:
+ push esi
+ push edi
+ push ecx
+ push ebx
+ mov esi, [esp+source]
+ mov edi, [esp+dest]
+ mov ecx, [esp+h]
+ mov ebx, [esp+lx2]
+ movq mm5, [MASK_AND]
+ movq mm6, [ADD_1]
+.rech1:
+ movq mm0,[esi]
+ movq mm1,[esi+1]
+ movq mm2,[esi+8]
+ movq mm3,[esi+9]
+ psrlw mm0,1
+ psrlw mm1,1
+ psrlw mm2,1
+ psrlw mm3,1
+ pand mm0,mm5
+ pand mm1,mm5
+ pand mm2,mm5
+ pand mm3,mm5
+ paddusb mm0,mm1
+ paddusb mm2,mm3
+ paddusb mm0,mm6
+ paddusb mm2,mm6
+ movq [edi],mm0
+ add esi,ebx
+ movq [edi+8],mm2
+ add edi,ebx
+ dec ecx
+ jnz .rech1
+ emms
+ pop ebx
+ pop ecx
+ pop edi
+ pop esi
+ ret
+
+ align 16
+rechc_mmx:
+ push esi
+ push edi
+ push ecx
+ push ebx
+; sub esp, LocalFrameSize
+ mov esi, [esp+source]
+ mov edi, [esp+dest]
+ mov ecx, [esp+h]
+ mov ebx, [esp+lx2]
+ movq mm5, [MASK_AND]
+ movq mm6, [ADD_1]
+.rechc1:
+ movq mm0,[esi]
+ movq mm1,[esi+1]
+ psrlw mm0,1
+ psrlw mm1,1
+ pand mm0,mm5
+ pand mm1,mm5
+ paddusb mm0,mm1
+ paddusb mm0,mm6
+ movq [edi],mm0
+ add edi,ebx
+ add esi,ebx
+ dec ecx
+ jnz .rechc1
+ emms
+; add esp, LocalFrameSize
+ pop ebx
+ pop ecx
+ pop edi
+ pop esi
+ ret
+
+
+
+%assign RegisterStorageSize 20
+%assign source LocalFrameSize + RegisterStorageSize + 4
+%assign dest LocalFrameSize + RegisterStorageSize + 8
+%assign lx LocalFrameSize + RegisterStorageSize + 12
+%assign lx2 LocalFrameSize + RegisterStorageSize + 16
+%assign h LocalFrameSize + RegisterStorageSize + 20
+
+ align 16
+recva_mmx:
+ push esi
+ push edi
+ push ecx
+ push ebx
+ push edx
+ mov esi, [esp+source]
+ mov edi, [esp+dest]
+ mov ecx, [esp+h]
+ mov ebx, [esp+lx2]
+ mov edx, [esp+lx]
+ movq mm7, [MASK_AND]
+ movq mm6, [ADD_1]
+.recva1:
+ movq mm0,[esi]
+ movq mm1,[esi+edx]
+ movq mm2,[esi+8]
+ movq mm3,[esi+edx+8]
+ movq mm4,[edi]
+ movq mm5,[edi+8]
+ psrlw mm0,1
+ psrlw mm1,1
+ psrlw mm2,1
+ psrlw mm3,1
+ psrlw mm4,1
+ psrlw mm5,1
+ pand mm0,mm7
+ pand mm1,mm7
+ pand mm2,mm7
+ pand mm3,mm7
+ pand mm4,mm7
+ pand mm5,mm7
+ paddusb mm0,mm1
+ paddusb mm2,mm3
+ paddusb mm0,mm6
+ paddusb mm2,mm6
+ psrlw mm0,1
+ psrlw mm2,1
+ pand mm0,mm7
+ pand mm2,mm7
+ paddusb mm4,mm0
+ paddusb mm5,mm2
+ paddusb mm4,mm6
+ paddusb mm5,mm6
+ movq [edi],mm4
+ movq [edi+8],mm5
+ add edi,ebx
+ add esi,ebx
+ dec ecx
+ jnz near .recva1
+ emms
+ pop edx
+ pop ebx
+ pop ecx
+ pop edi
+ pop esi
+ ret
+
+ align 16
+recvac_mmx:
+ push esi
+ push edi
+ push ecx
+ push ebx
+ push edx
+ mov esi, [esp+source]
+ mov edi, [esp+dest]
+ mov ecx, [esp+h]
+ mov ebx, [esp+lx2]
+ mov edx, [esp+lx]
+ movq mm5, [MASK_AND]
+ movq mm6, [ADD_1]
+.recvac1:
+ movq mm0,[esi]
+ movq mm1,[esi+edx]
+ movq mm4,[edi]
+ psrlw mm0,1
+ psrlw mm1,1
+ psrlw mm4,1
+ pand mm0,mm5
+ pand mm1,mm5
+ pand mm4,mm5
+ paddusb mm0,mm1
+ paddusb mm0,mm6
+ psrlw mm0,1
+ pand mm0,mm5
+ paddusb mm4,mm0
+ paddusb mm4,mm6
+ movq [edi],mm4
+ add edi,ebx
+ add esi,ebx
+ dec ecx
+ jnz .recvac1
+ emms
+ pop edx
+ pop ebx
+ pop ecx
+ pop edi
+ pop esi
+ ret
+
+%assign RegisterStorageSize 20
+%assign rfp LocalFrameSize + RegisterStorageSize + 4
+%assign bp LocalFrameSize + RegisterStorageSize + 8
+%assign iincr LocalFrameSize + RegisterStorageSize + 12
+
+; FIXME clipping needs to be done
+
+ align 16
+add_block_mmx:
+ push esi
+ push edi
+ push ecx
+ push ebx
+ push edx
+ mov esi, [esp+bp]
+ mov edi, [esp+rfp]
+ mov ebx, [esp+iincr]
+; movq mm7, [PLUS_384]
+ mov ecx,8
+ pxor mm2,mm2 ; clear
+%rep 8
+ movq mm0, [edi] ; get dest
+ movq mm1,mm0
+ punpcklbw mm0,mm2
+ punpckhbw mm1,mm2
+ paddsw mm0, [esi]
+ paddsw mm1, [esi+8]
+; paddsw mm0, mm7
+; paddsw mm1, mm7
+ packuswb mm0,mm1
+ movq [edi], mm0
+ add edi,ebx
+ add esi,16
+%endrep
+ emms
+ pop edx
+ pop ebx
+ pop ecx
+ pop edi
+ pop esi
+ ret
+
+ align 16
+set_block_mmx:
+ push esi
+ push edi
+ push ecx
+ push ebx
+ push edx
+ mov esi, [esp+bp]
+ mov edi, [esp+rfp]
+ mov ebx, [esp+iincr]
+ movq mm7, [PLUS_128]
+%rep 4
+ movq mm0, [esi]
+ movq mm1, [esi+8]
+ paddsw mm0, mm7
+ movq mm2, [esi+16]
+ paddsw mm1, mm7
+ movq mm3, [esi+24]
+ paddsw mm2, mm7
+ packuswb mm0, mm1
+ paddsw mm3, mm7
+ movq [edi], mm0
+ packuswb mm2, mm3
+ add edi, ebx
+ add esi, 32
+ movq [edi], mm2
+ add edi, ebx
+%endrep
+ emms
+ pop edx
+ pop ebx
+ pop ecx
+ pop edi
+ pop esi
+ ret
+
+
diff --git a/core/multimedia/opieplayer/libmpeg3/video/reconstruct.c b/core/multimedia/opieplayer/libmpeg3/video/reconstruct.c
new file mode 100644
index 0000000..531f9c0
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/reconstruct.c
@@ -0,0 +1,1290 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include <stdio.h>
+
+#ifdef HAVE_MMX
+
+#ifdef HAVE_3Dnow
+static inline void recva_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ __asm__(
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq (%4), %%mm2\n" /* 8 s +lx */
+ "movq 8(%4), %%mm3\n" /* 8 s +lx **/
+
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %1\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq (%2), %%mm2\n" /* 8 d */
+ "movq 8(%2), %%mm3\n" /* 8 d */
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %4\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq %%mm0, (%2)\n"
+ "movq %%mm1, 8(%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+}
+
+static inline void recvac_mmx(unsigned char *s, unsigned char *d, int lx,int lx2, int h)
+{
+ __asm__(
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%4), %%mm2\n" /* 8 s +lx */
+ "addl %3, %1\n"
+ "pavgusb %%mm2, %%mm0\n"
+ "movq (%2), %%mm3\n" /* 8 d */
+ "addl %3, %4\n"
+ "pavgusb %%mm3, %%mm0\n"
+ "movq %%mm0, (%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+}
+
+static inline void rech_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ __asm__ (
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s */
+ "movq 9(%1), %%mm3\n" /* 8 s */
+
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %1\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq %%mm0, (%2)\n"
+ "movq %%mm1, 8(%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+}
+
+static inline void rechc_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ __asm__ (
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s +1 */
+ "addl %3, %1\n"
+ "pavgusb %%mm2, %%mm0\n"
+ "movq %%mm0, (%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+}
+
+static inline void recha_mmx(unsigned char *s, unsigned char *d,int lx2, int h)
+{
+ __asm__ (
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s */
+ "movq 9(%1), %%mm3\n" /* 8 s */
+
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %1\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq (%2), %%mm2\n" /* 8 d */
+ "movq 8(%2), %%mm3\n" /* 8 d */
+ "pavgusb %%mm2, %%mm0\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq %%mm0, (%2)\n"
+ "movq %%mm1, 8(%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+}
+
+static inline void rechac_mmx(unsigned char *s,unsigned char *d, int lx2, int h)
+{
+ __asm__ (
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s */
+
+ "addl %3, %1\n"
+ "pavgusb %%mm2, %%mm0\n"
+
+ "movq (%2), %%mm1\n" /* 8 d */
+ "pavgusb %%mm1, %%mm0\n"
+
+ "movq %%mm0, (%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+}
+
+static inline void rec4_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ __asm__ __volatile__(
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s +1*/
+ "movq 9(%1), %%mm3\n" /* 8 s +1*/
+ ".align 8\n"
+ "1:"
+ "movq (%4), %%mm4\n" /* 8 s+lx */
+ "pavgusb %%mm2, %%mm0\n"
+ "movq 8(%4), %%mm5\n" /* 8 s+lx */
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq 1(%4), %%mm6\n" /* 8 s+lx +1*/
+ "pavgusb %%mm4, %%mm0\n"
+ "movq 9(%4), %%mm7\n" /* 8 s+lx +1*/
+ "pavgusb %%mm5, %%mm1\n"
+
+ "pavgusb %%mm6, %%mm0\n"
+ "addl %3, %4\n"
+ "pavgusb %%mm7, %%mm1\n"
+ "movq %%mm0, (%2)\n"
+ "movq %%mm6, %%mm2\n"
+ "movq %%mm7, %%mm3\n"
+ "movq %%mm1, 8(%2)\n"
+ "movq %%mm4, %%mm0\n"
+ "movq %%mm5, %%mm1\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+}
+
+static inline void rec4c_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ __asm__ __volatile__(
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s +1*/
+ ".align 8\n"
+ "1:"
+ "movq (%4), %%mm4\n" /* 8 s+lx */
+ "pavgusb %%mm2, %%mm0\n"
+
+ "movq 1(%4), %%mm6\n" /* 8 s+lx +1*/
+ "pavgusb %%mm4, %%mm0\n"
+
+ "addl %3, %4\n"
+ "pavgusb %%mm6, %%mm0\n"
+ "movq %%mm0, (%2)\n"
+ "movq %%mm6, %%mm2\n"
+ "movq %%mm4, %%mm0\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+}
+
+static inline void rec4a_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ __asm__ __volatile__(
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s +1*/
+ "movq 9(%1), %%mm3\n" /* 8 s +1*/
+ ".align 8\n"
+ "1:"
+ "movq (%4), %%mm4\n" /* 8 s+lx */
+ "pavgusb %%mm2, %%mm0\n"
+ "movq 8(%4), %%mm5\n" /* 8 s+lx */
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq 1(%4), %%mm6\n" /* 8 s+lx +1*/
+ "pavgusb %%mm4, %%mm0\n"
+ "movq 9(%4), %%mm7\n" /* 8 s+lx +1*/
+ "pavgusb %%mm5, %%mm1\n"
+ "movq (%2), %%mm2\n"
+ "pavgusb %%mm6, %%mm0\n"
+ "movq 8(%2), %%mm3\n"
+
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %4\n"
+ "pavgusb %%mm3, %%mm1\n"
+ "movq %%mm0, (%2)\n"
+
+ "pavgusb %%mm7, %%mm1\n"
+ "movq %%mm6, %%mm2\n"
+ "movq %%mm7, %%mm3\n"
+ "movq %%mm1, 8(%2)\n"
+ "movq %%mm4, %%mm0\n"
+ "movq %%mm5, %%mm1\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+}
+
+static inline void rec4ac_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ __asm__ __volatile__(
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq 1(%1), %%mm2\n" /* 8 s +1*/
+ ".align 8\n"
+ "1:"
+ "movq (%4), %%mm4\n" /* 8 s+lx */
+ "pavgusb %%mm2, %%mm0\n"
+
+ "movq 1(%4), %%mm6\n" /* 8 s+lx +1*/
+ "pavgusb %%mm4, %%mm0\n"
+ "movq (%2), %%mm1\n" /* 8 d */
+ "pavgusb %%mm6, %%mm0\n"
+ "addl %3, %4\n"
+ "pavgusb %%mm1, %%mm0\n"
+ "movq %%mm6, %%mm2\n"
+ "movq %%mm0, (%2)\n"
+ "movq %%mm4, %%mm0\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+}
+
+#else // HAVE_3DNOW
+ static LONGLONG ADD_1 = 0x0101010101010101LL;
+ static LONGLONG MASK_AND = 0x7f7f7f7f7f7f7f7fLL;
+#endif
+
+static inline void rec_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ __asm__ __volatile__(
+ ".align 8\n"
+ "1:\t"
+ "movq ( %1 ), %%mm0\n" /* 8 s */
+ "movq 8( %1 ), %%mm2\n" /* 16 s */
+ "movq %%mm0, ( %2 )\n"
+ "addl %3, %1\n"
+ "movq %%mm2, 8( %2 )\n"
+ "decl %0\n"
+ "leal (%2, %3), %2\n"
+ "jnz 1b"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+}
+
+
+static inline void recc_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ __asm__ __volatile__(
+ ".align 8\n"
+ "1:\t"
+ "movq ( %1 ), %%mm0\n"
+ "addl %3, %1\n"
+ "movq %%mm0, ( %2 )\n"
+ "decl %0\n"
+ "leal (%2, %3), %2\n"
+ "jnz 1b"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+}
+
+
+static inline void reca_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+#ifdef HAVE_3Dnow
+ __asm__ (
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%2), %%mm2\n" /* 8 d */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq 8(%2), %%mm3\n" /* 8 d */
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %1\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq %%mm0, (%2)\n"
+ "movq %%mm1, 8(%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+#else /* No 3dnow */
+ __asm__ (
+ "movq MASK_AND, %%mm5\n"
+ "movq ADD_1, %%mm6\n"
+ "1:\t"
+ "movq (%1),%%mm0\n" /* Load 16 pixels from each row */
+ "movq (%2),%%mm1\n"
+ "movq 8(%1),%%mm2\n"
+ "movq 8(%2),%%mm3\n"
+ "psrlw $1,%%mm0\n" /* Shift pixels down */
+ "psrlw $1,%%mm1\n"
+ "pand %%mm5,%%mm0\n" /* Zero out significant bit */
+ "psrlw $1,%%mm2\n"
+ "pand %%mm5,%%mm1\n"
+ "psrlw $1,%%mm3\n"
+ "pand %%mm5,%%mm2\n"
+ "paddusb %%mm1,%%mm0\n" /* Add pixels */
+ "pand %%mm5,%%mm3\n"
+ "paddusb %%mm3,%%mm2\n"
+ "paddusb %%mm6,%%mm0\n" /* Add 1 to results */
+ "paddusb %%mm6,%%mm2\n"
+ "movq %%mm0,(%2)\n"
+ "addl %3,%1\n"
+ "movq %%mm2, 8(%2)\n"
+ "decl %0\n"
+ "leal (%2, %3), %2\n"
+ "jnz 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+#endif
+}
+
+
+static inline void recac_mmx(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+#ifdef HAVE_3Dnow
+ __asm__ (
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%2), %%mm2\n" /* 8 d */
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %1\n"
+ "movq %%mm0, (%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+#else /* No 3dnow */
+ __asm__ (
+ "movq MASK_AND, %%mm5\n"
+ "movq ADD_1, %%mm6\n"
+ "1:\t"
+ "movq (%1),%%mm0\n"
+ "movq (%2),%%mm1\n"
+ "psrlw $1,%%mm0\n"
+ "psrlw $1,%%mm1\n"
+ "pand %%mm5,%%mm0\n"
+ "pand %%mm5,%%mm1\n"
+ "paddusb %%mm1,%%mm0\n"
+ "paddusb %%mm6,%%mm0\n"
+ "addl %3,%1\n"
+ "movq %%mm0,(%2)\n"
+ "decl %0\n"
+ "leal (%2, %3), %2\n"
+ "jnz 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2)
+ );
+#endif
+}
+
+
+static inline void recv_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+#ifdef HAVE_3Dnow
+ __asm__(
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%4), %%mm2\n" /* 8 s +lx */
+ "movq 8(%1), %%mm1\n" /* 8 s */
+ "movq 8(%4), %%mm3\n" /* 8 s +lx **/
+
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %1\n"
+ "pavgusb %%mm3, %%mm1\n"
+
+ "movq %%mm0, (%2)\n"
+ "addl %3, %4\n"
+ "movq %%mm1, 8(%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+#else
+ __asm__ (
+ "movq MASK_AND, %%mm5\n"
+ "movq ADD_1, %%mm6\n"
+ "1:\t"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%4), %%mm1\n" /* 8 s +lx */
+ "movq 8(%1), %%mm2\n" /* 8 s */
+ "movq 8(%4), %%mm3\n" /* 8 s +lx **/
+ "psrlw $1,%%mm0\n"
+ "psrlw $1,%%mm1\n"
+ "pand %%mm5,%%mm0\n"
+ "psrlw $1,%%mm2\n"
+ "pand %%mm5,%%mm1\n"
+ "psrlw $1,%%mm3\n"
+ "pand %%mm5,%%mm2\n"
+ "paddusb %%mm1,%%mm0\n"
+ "pand %%mm5,%%mm3\n"
+ "paddusb %%mm3,%%mm2\n"
+ "paddusb %%mm6,%%mm0\n"
+ "paddusb %%mm6,%%mm2\n"
+ "movq %%mm0,(%2)\n"
+ "addl %3,%1\n"
+ "movq %%mm2, 8(%2)\n"
+ "addl %3,%4\n"
+ "decl %0\n"
+ "leal (%2, %3), %2\n"
+ "jnz 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+#endif
+}
+
+
+static inline void recvc_mmx(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+#ifdef HAVE_3Dnow
+ __asm__(
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%4), %%mm2\n" /* 8 s +lx */
+ "addl %3, %1\n"
+ "pavgusb %%mm2, %%mm0\n"
+ "addl %3, %4\n"
+ "movq %%mm0, (%2)\n"
+ "addl %3, %2\n"
+ "loop 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+#else
+ __asm__ (
+ "movq MASK_AND, %%mm5\n"
+ "movq ADD_1, %%mm6\n"
+ "1:\t"
+ "movq (%1), %%mm0\n" /* 8 s */
+ "movq (%4), %%mm1\n" /* 8 s +lx */
+ "psrlw $1,%%mm0\n"
+ "psrlw $1,%%mm1\n"
+ "pand %%mm5,%%mm0\n"
+ "pand %%mm5,%%mm1\n"
+ "paddusb %%mm1,%%mm0\n"
+ "addl %3,%1\n"
+ "paddusb %%mm6,%%mm0\n"
+ "addl %3,%4\n"
+ "movq %%mm0,(%2)\n"
+ "decl %0\n"
+ "leal (%2, %3), %2\n"
+ "jnz 1b\n"
+ :
+ : "c" (h), "r" (s), "r" (d), "r" (lx2), "r" (s +lx)
+ );
+#endif
+}
+
+#endif // HAVE_MMX
+
+static inline void rec(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ int j;
+ for(j = 0; j < h; j++, s += lx2, d += lx2)
+ {
+ d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; d[3] = s[3];
+ d[4] = s[4]; d[5] = s[5]; d[6] = s[6]; d[7] = s[7];
+ d[8] = s[8]; d[9] = s[9]; d[10] = s[10]; d[11] = s[11];
+ d[12] = s[12]; d[13] = s[13]; d[14] = s[14]; d[15] = s[15];
+ }
+}
+
+
+
+static inline void recc(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ int j;
+ for(j = 0; j < h; j++, s += lx2, d += lx2)
+ {
+ d[0] = s[0]; d[1] = s[1]; d[2] = s[2]; d[3] = s[3];
+ d[4] = s[4]; d[5] = s[5]; d[6] = s[6]; d[7] = s[7];
+ }
+}
+
+static inline void reca(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ int j;
+ for(j = 0; j < h; j++, s +=lx2, d +=lx2)
+ {
+ d[0] = (unsigned int)(d[0] + s[0] + 1) >> 1;
+ d[1] = (unsigned int)(d[1] + s[1] + 1) >> 1;
+ d[2] = (unsigned int)(d[2] + s[2] + 1) >> 1;
+ d[3] = (unsigned int)(d[3] + s[3] + 1) >> 1;
+ d[4] = (unsigned int)(d[4] + s[4] + 1) >> 1;
+ d[5] = (unsigned int)(d[5] + s[5] + 1) >> 1;
+ d[6] = (unsigned int)(d[6] + s[6] + 1) >> 1;
+ d[7] = (unsigned int)(d[7] + s[7] + 1) >> 1;
+ d[8] = (unsigned int)(d[8] + s[8] + 1) >> 1;
+ d[9] = (unsigned int)(d[9] + s[9] + 1) >> 1;
+ d[10] = (unsigned int)(d[10] + s[10] + 1) >> 1;
+ d[11] = (unsigned int)(d[11] + s[11] + 1) >> 1;
+ d[12] = (unsigned int)(d[12] + s[12] + 1) >> 1;
+ d[13] = (unsigned int)(d[13] + s[13] + 1) >> 1;
+ d[14] = (unsigned int)(d[14] + s[14] + 1) >> 1;
+ d[15] = (unsigned int)(d[15] + s[15] + 1) >> 1;
+ }
+}
+
+static inline void recac(unsigned char *s, unsigned char *d, int lx2, int h)
+{
+ int j;
+ for(j = 0; j < h; j++, s += lx2, d += lx2)
+ {
+ d[0] = (unsigned int)(d[0] + s[0] + 1)>>1;
+ d[1] = (unsigned int)(d[1] + s[1] + 1)>>1;
+ d[2] = (unsigned int)(d[2] + s[2] + 1)>>1;
+ d[3] = (unsigned int)(d[3] + s[3] + 1)>>1;
+ d[4] = (unsigned int)(d[4] + s[4] + 1)>>1;
+ d[5] = (unsigned int)(d[5] + s[5] + 1)>>1;
+ d[6] = (unsigned int)(d[6] + s[6] + 1)>>1;
+ d[7] = (unsigned int)(d[7] + s[7] + 1)>>1;
+ }
+}
+
+static inline void recv_(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp,*sp,*sp2;
+ int j;
+ sp = s;
+ sp2 = s + lx;
+ dp = d;
+ for(j = 0; j < h; j++)
+ {
+ dp[0] = (unsigned int)(sp[0] + sp2[0] + 1) >> 1;
+ dp[1] = (unsigned int)(sp[1] + sp2[1] + 1) >> 1;
+ dp[2] = (unsigned int)(sp[2] + sp2[2] + 1) >> 1;
+ dp[3] = (unsigned int)(sp[3] + sp2[3] + 1) >> 1;
+ dp[4] = (unsigned int)(sp[4] + sp2[4] + 1) >> 1;
+ dp[5] = (unsigned int)(sp[5] + sp2[5] + 1) >> 1;
+ dp[6] = (unsigned int)(sp[6] + sp2[6] + 1) >> 1;
+ dp[7] = (unsigned int)(sp[7] + sp2[7] + 1) >> 1;
+ dp[8] = (unsigned int)(sp[8] + sp2[8] + 1) >> 1;
+ dp[9] = (unsigned int)(sp[9] + sp2[9] + 1) >> 1;
+ dp[10] = (unsigned int)(sp[10] + sp2[10] + 1) >> 1;
+ dp[11] = (unsigned int)(sp[11] + sp2[11] + 1) >> 1;
+ dp[12] = (unsigned int)(sp[12] + sp2[12] + 1) >> 1;
+ dp[13] = (unsigned int)(sp[13] + sp2[13] + 1) >> 1;
+ dp[14] = (unsigned int)(sp[14] + sp2[14] + 1) >> 1;
+ dp[15] = (unsigned int)(sp[15] + sp2[15] + 1) >> 1;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+static inline void recvc(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp,*sp,*sp2;
+ int j;
+
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+ for(j = 0; j < h; j++)
+ {
+ dp[0] = (unsigned int)(sp[0]+sp2[0]+1)>>1;
+ dp[1] = (unsigned int)(sp[1]+sp2[1]+1)>>1;
+ dp[2] = (unsigned int)(sp[2]+sp2[2]+1)>>1;
+ dp[3] = (unsigned int)(sp[3]+sp2[3]+1)>>1;
+ dp[4] = (unsigned int)(sp[4]+sp2[4]+1)>>1;
+ dp[5] = (unsigned int)(sp[5]+sp2[5]+1)>>1;
+ dp[6] = (unsigned int)(sp[6]+sp2[6]+1)>>1;
+ dp[7] = (unsigned int)(sp[7]+sp2[7]+1)>>1;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void recva(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp,*sp,*sp2;
+ int j;
+
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+ for (j=0; j<h; j++){
+ dp[0] = (dp[0] + ((unsigned int)(sp[0]+sp2[0]+1)>>1) + 1)>>1;
+ dp[1] = (dp[1] + ((unsigned int)(sp[1]+sp2[1]+1)>>1) + 1)>>1;
+ dp[2] = (dp[2] + ((unsigned int)(sp[2]+sp2[2]+1)>>1) + 1)>>1;
+ dp[3] = (dp[3] + ((unsigned int)(sp[3]+sp2[3]+1)>>1) + 1)>>1;
+ dp[4] = (dp[4] + ((unsigned int)(sp[4]+sp2[4]+1)>>1) + 1)>>1;
+ dp[5] = (dp[5] + ((unsigned int)(sp[5]+sp2[5]+1)>>1) + 1)>>1;
+ dp[6] = (dp[6] + ((unsigned int)(sp[6]+sp2[6]+1)>>1) + 1)>>1;
+ dp[7] = (dp[7] + ((unsigned int)(sp[7]+sp2[7]+1)>>1) + 1)>>1;
+ dp[8] = (dp[8] + ((unsigned int)(sp[8]+sp2[8]+1)>>1) + 1)>>1;
+ dp[9] = (dp[9] + ((unsigned int)(sp[9]+sp2[9]+1)>>1) + 1)>>1;
+ dp[10] = (dp[10] + ((unsigned int)(sp[10]+sp2[10]+1)>>1) + 1)>>1;
+ dp[11] = (dp[11] + ((unsigned int)(sp[11]+sp2[11]+1)>>1) + 1)>>1;
+ dp[12] = (dp[12] + ((unsigned int)(sp[12]+sp2[12]+1)>>1) + 1)>>1;
+ dp[13] = (dp[13] + ((unsigned int)(sp[13]+sp2[13]+1)>>1) + 1)>>1;
+ dp[14] = (dp[14] + ((unsigned int)(sp[14]+sp2[14]+1)>>1) + 1)>>1;
+ dp[15] = (dp[15] + ((unsigned int)(sp[15]+sp2[15]+1)>>1) + 1)>>1;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void recvac(unsigned char *s, unsigned char *d, int lx,int lx2, int h){
+ unsigned char *dp,*sp,*sp2;
+ int j;
+
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+ for (j=0; j<h; j++){
+ dp[0] = (dp[0] + ((unsigned int)(sp[0]+sp2[0]+1)>>1) + 1)>>1;
+ dp[1] = (dp[1] + ((unsigned int)(sp[1]+sp2[1]+1)>>1) + 1)>>1;
+ dp[2] = (dp[2] + ((unsigned int)(sp[2]+sp2[2]+1)>>1) + 1)>>1;
+ dp[3] = (dp[3] + ((unsigned int)(sp[3]+sp2[3]+1)>>1) + 1)>>1;
+ dp[4] = (dp[4] + ((unsigned int)(sp[4]+sp2[4]+1)>>1) + 1)>>1;
+ dp[5] = (dp[5] + ((unsigned int)(sp[5]+sp2[5]+1)>>1) + 1)>>1;
+ dp[6] = (dp[6] + ((unsigned int)(sp[6]+sp2[6]+1)>>1) + 1)>>1;
+ dp[7] = (dp[7] + ((unsigned int)(sp[7]+sp2[7]+1)>>1) + 1)>>1;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void rech(unsigned char *s, unsigned char *d, int lx2, int h){
+ unsigned char *dp,*sp;
+ unsigned int s1,s2;
+ int j;
+
+ sp = s;
+ dp = d;
+ for (j=0; j<h; j++){
+ s1=sp[0];
+ dp[0] = (unsigned int)(s1+(s2=sp[1])+1)>>1;
+ dp[1] = (unsigned int)(s2+(s1=sp[2])+1)>>1;
+ dp[2] = (unsigned int)(s1+(s2=sp[3])+1)>>1;
+ dp[3] = (unsigned int)(s2+(s1=sp[4])+1)>>1;
+ dp[4] = (unsigned int)(s1+(s2=sp[5])+1)>>1;
+ dp[5] = (unsigned int)(s2+(s1=sp[6])+1)>>1;
+ dp[6] = (unsigned int)(s1+(s2=sp[7])+1)>>1;
+ dp[7] = (unsigned int)(s2+(s1=sp[8])+1)>>1;
+ dp[8] = (unsigned int)(s1+(s2=sp[9])+1)>>1;
+ dp[9] = (unsigned int)(s2+(s1=sp[10])+1)>>1;
+ dp[10] = (unsigned int)(s1+(s2=sp[11])+1)>>1;
+ dp[11] = (unsigned int)(s2+(s1=sp[12])+1)>>1;
+ dp[12] = (unsigned int)(s1+(s2=sp[13])+1)>>1;
+ dp[13] = (unsigned int)(s2+(s1=sp[14])+1)>>1;
+ dp[14] = (unsigned int)(s1+(s2=sp[15])+1)>>1;
+ dp[15] = (unsigned int)(s2+sp[16]+1)>>1;
+ sp+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void rechc(unsigned char *s,unsigned char *d, int lx2, int h){
+ unsigned char *dp,*sp;
+ unsigned int s1,s2;
+ int j;
+
+ sp = s;
+ dp = d;
+ for (j=0; j<h; j++){
+ s1=sp[0];
+ dp[0] = (unsigned int)(s1+(s2=sp[1])+1)>>1;
+ dp[1] = (unsigned int)(s2+(s1=sp[2])+1)>>1;
+ dp[2] = (unsigned int)(s1+(s2=sp[3])+1)>>1;
+ dp[3] = (unsigned int)(s2+(s1=sp[4])+1)>>1;
+ dp[4] = (unsigned int)(s1+(s2=sp[5])+1)>>1;
+ dp[5] = (unsigned int)(s2+(s1=sp[6])+1)>>1;
+ dp[6] = (unsigned int)(s1+(s2=sp[7])+1)>>1;
+ dp[7] = (unsigned int)(s2+sp[8]+1)>>1;
+ sp+= lx2;
+ dp+= lx2;
+ }
+}
+
+static inline void recha(unsigned char *s, unsigned char *d,int lx2, int h)
+{
+ unsigned char *dp,*sp;
+ unsigned int s1,s2;
+ int j;
+
+ sp = s;
+ dp = d;
+ for (j = 0; j < h; j++)
+ {
+ s1 = sp[0];
+ dp[0] = (dp[0] + ((unsigned int)(s1 + (s2 = sp[1]) + 1) >> 1) + 1) >> 1;
+ dp[1] = (dp[1] + ((unsigned int)(s2 + (s1 = sp[2]) + 1) >> 1) + 1) >> 1;
+ dp[2] = (dp[2] + ((unsigned int)(s1 + (s2 = sp[3]) + 1) >> 1) + 1) >> 1;
+ dp[3] = (dp[3] + ((unsigned int)(s2 + (s1 = sp[4]) + 1) >> 1) + 1) >> 1;
+ dp[4] = (dp[4] + ((unsigned int)(s1 + (s2 = sp[5]) + 1) >> 1) + 1) >> 1;
+ dp[5] = (dp[5] + ((unsigned int)(s2 + (s1 = sp[6]) + 1) >> 1) + 1) >> 1;
+ dp[6] = (dp[6] + ((unsigned int)(s1 + (s2 = sp[7]) + 1) >> 1) + 1) >> 1;
+ dp[7] = (dp[7] + ((unsigned int)(s2 + (s1 = sp[8]) + 1) >> 1) + 1) >> 1;
+ dp[8] = (dp[8] + ((unsigned int)(s1 + (s2 = sp[9]) + 1) >> 1) + 1) >> 1;
+ dp[9] = (dp[9] + ((unsigned int)(s2 + (s1 = sp[10]) + 1) >> 1) + 1) >> 1;
+ dp[10] = (dp[10] + ((unsigned int)(s1 + (s2 = sp[11]) + 1) >> 1) + 1) >> 1;
+ dp[11] = (dp[11] + ((unsigned int)(s2 + (s1 = sp[12]) + 1) >> 1) + 1) >> 1;
+ dp[12] = (dp[12] + ((unsigned int)(s1 + (s2 = sp[13]) + 1) >> 1) + 1) >> 1;
+ dp[13] = (dp[13] + ((unsigned int)(s2 + (s1 = sp[14]) + 1) >> 1) + 1) >> 1;
+ dp[14] = (dp[14] + ((unsigned int)(s1 + (s2 = sp[15]) + 1) >> 1) + 1) >> 1;
+ dp[15] = (dp[15] + ((unsigned int)(s2 + sp[16] + 1) >> 1) + 1) >> 1;
+ sp += lx2;
+ dp += lx2;
+ }
+}
+
+
+static inline void rechac(unsigned char *s,unsigned char *d, int lx2, int h)
+{
+ unsigned char *dp,*sp;
+ unsigned int s1,s2;
+ int j;
+
+ sp = s;
+ dp = d;
+ for(j = 0; j < h; j++)
+ {
+ s1 = sp[0];
+ dp[0] = (dp[0] + ((unsigned int)(s1 + (s2 = sp[1]) + 1) >> 1) + 1) >> 1;
+ dp[1] = (dp[1] + ((unsigned int)(s2 + (s1 = sp[2]) + 1) >> 1) + 1) >> 1;
+ dp[2] = (dp[2] + ((unsigned int)(s1 + (s2 = sp[3]) + 1) >> 1) + 1) >> 1;
+ dp[3] = (dp[3] + ((unsigned int)(s2 + (s1 = sp[4]) + 1) >> 1) + 1) >> 1;
+ dp[4] = (dp[4] + ((unsigned int)(s1 + (s2 = sp[5]) + 1) >> 1) + 1) >> 1;
+ dp[5] = (dp[5] + ((unsigned int)(s2 + (s1 = sp[6]) + 1) >> 1) + 1) >> 1;
+ dp[6] = (dp[6] + ((unsigned int)(s1 + (s2 = sp[7]) + 1) >> 1) + 1) >> 1;
+ dp[7] = (dp[7] + ((unsigned int)(s2 + sp[8] + 1) >> 1) + 1) >> 1;
+ sp += lx2;
+ dp += lx2;
+ }
+}
+
+
+static inline void rec4(unsigned char *s, unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp,*sp,*sp2;
+ unsigned int s1,s2,s3,s4;
+ int j;
+
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+ for (j=0; j<h; j++){
+ s1=sp[0]; s3=sp2[0];
+ dp[0] = (unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2;
+ dp[1] = (unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2;
+ dp[2] = (unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2;
+ dp[3] = (unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2;
+ dp[4] = (unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2;
+ dp[5] = (unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2;
+ dp[6] = (unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2;
+ dp[7] = (unsigned int)(s2+(s1=sp[8])+s4+(s3=sp2[8])+2)>>2;
+ dp[8] = (unsigned int)(s1+(s2=sp[9])+s3+(s4=sp2[9])+2)>>2;
+ dp[9] = (unsigned int)(s2+(s1=sp[10])+s4+(s3=sp2[10])+2)>>2;
+ dp[10] = (unsigned int)(s1+(s2=sp[11])+s3+(s4=sp2[11])+2)>>2;
+ dp[11] = (unsigned int)(s2+(s1=sp[12])+s4+(s3=sp2[12])+2)>>2;
+ dp[12] = (unsigned int)(s1+(s2=sp[13])+s3+(s4=sp2[13])+2)>>2;
+ dp[13] = (unsigned int)(s2+(s1=sp[14])+s4+(s3=sp2[14])+2)>>2;
+ dp[14] = (unsigned int)(s1+(s2=sp[15])+s3+(s4=sp2[15])+2)>>2;
+ dp[15] = (unsigned int)(s2+sp[16]+s4+sp2[16]+2)>>2;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void rec4c(unsigned char *s,unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp,*sp,*sp2;
+ unsigned int s1,s2,s3,s4;
+ int j;
+
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+ for (j=0; j<h; j++){
+ s1=sp[0]; s3=sp2[0];
+ dp[0] = (unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2;
+ dp[1] = (unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2;
+ dp[2] = (unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2;
+ dp[3] = (unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2;
+ dp[4] = (unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2;
+ dp[5] = (unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2;
+ dp[6] = (unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2;
+ dp[7] = (unsigned int)(s2+sp[8]+s4+sp2[8]+2)>>2;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void rec4a(unsigned char *s,unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp=d, *sp=s, *sp2=s+lx;
+ unsigned int s1, s2, s3, s4;
+ int j;
+
+/*
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+*/
+ for (j=0; j<h; j++){
+ s1=sp[0]; s3=sp2[0];
+ dp[0] = (dp[0] + ((unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2) + 1)>>1;
+ dp[1] = (dp[1] + ((unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2) + 1)>>1;
+ dp[2] = (dp[2] + ((unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2) + 1)>>1;
+ dp[3] = (dp[3] + ((unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2) + 1)>>1;
+ dp[4] = (dp[4] + ((unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2) + 1)>>1;
+ dp[5] = (dp[5] + ((unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2) + 1)>>1;
+ dp[6] = (dp[6] + ((unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2) + 1)>>1;
+ dp[7] = (dp[7] + ((unsigned int)(s2+(s1=sp[8])+s4+(s3=sp2[8])+2)>>2) + 1)>>1;
+ dp[8] = (dp[8] + ((unsigned int)(s1+(s2=sp[9])+s3+(s4=sp2[9])+2)>>2) + 1)>>1;
+ dp[9] = (dp[9] + ((unsigned int)(s2+(s1=sp[10])+s4+(s3=sp2[10])+2)>>2) + 1)>>1;
+ dp[10] = (dp[10] + ((unsigned int)(s1+(s2=sp[11])+s3+(s4=sp2[11])+2)>>2) + 1)>>1;
+ dp[11] = (dp[11] + ((unsigned int)(s2+(s1=sp[12])+s4+(s3=sp2[12])+2)>>2) + 1)>>1;
+ dp[12] = (dp[12] + ((unsigned int)(s1+(s2=sp[13])+s3+(s4=sp2[13])+2)>>2) + 1)>>1;
+ dp[13] = (dp[13] + ((unsigned int)(s2+(s1=sp[14])+s4+(s3=sp2[14])+2)>>2) + 1)>>1;
+ dp[14] = (dp[14] + ((unsigned int)(s1+(s2=sp[15])+s3+(s4=sp2[15])+2)>>2) + 1)>>1;
+ dp[15] = (dp[15] + ((unsigned int)(s2+sp[16]+s4+sp2[16]+2)>>2) + 1)>>1;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+
+static inline void rec4ac(unsigned char *s,unsigned char *d, int lx, int lx2, int h)
+{
+ unsigned char *dp=d, *sp=s, *sp2=s+lx;
+ unsigned int s1,s2,s3,s4;
+ int j;
+
+/*
+ sp = s;
+ sp2 = s+lx;
+ dp = d;
+*/
+ for (j=0; j<h; j++)
+ {
+ s1=sp[0]; s3=sp2[0];
+ dp[0] = (dp[0] + ((unsigned int)(s1+(s2=sp[1])+s3+(s4=sp2[1])+2)>>2) + 1)>>1;
+ dp[1] = (dp[1] + ((unsigned int)(s2+(s1=sp[2])+s4+(s3=sp2[2])+2)>>2) + 1)>>1;
+ dp[2] = (dp[2] + ((unsigned int)(s1+(s2=sp[3])+s3+(s4=sp2[3])+2)>>2) + 1)>>1;
+ dp[3] = (dp[3] + ((unsigned int)(s2+(s1=sp[4])+s4+(s3=sp2[4])+2)>>2) + 1)>>1;
+ dp[4] = (dp[4] + ((unsigned int)(s1+(s2=sp[5])+s3+(s4=sp2[5])+2)>>2) + 1)>>1;
+ dp[5] = (dp[5] + ((unsigned int)(s2+(s1=sp[6])+s4+(s3=sp2[6])+2)>>2) + 1)>>1;
+ dp[6] = (dp[6] + ((unsigned int)(s1+(s2=sp[7])+s3+(s4=sp2[7])+2)>>2) + 1)>>1;
+ dp[7] = (dp[7] + ((unsigned int)(s2+sp[8]+s4+sp2[8]+2)>>2) + 1)>>1;
+ sp+= lx2;
+ sp2+= lx2;
+ dp+= lx2;
+ }
+}
+
+static inline
+void recon_comp(mpeg3video_t *video,
+ unsigned char *src,
+ unsigned char *dst,
+ int lx,
+ int lx2,
+ int w,
+ int h,
+ int x,
+ int y,
+ int dx,
+ int dy,
+ int addflag)
+{
+ int switcher;
+ unsigned char *s, *d;
+
+/* half pel scaling */
+ switcher = (dx & 1) << 3 | (dy & 1) << 2 | w;
+ if(addflag) switcher |= 2;
+/* origins */
+ s = src + lx * (y + (dy >> 1)) + x + (dx >> 1);
+ d = dst + lx * y + x;
+
+// Accelerated functions
+#ifdef HAVE_3Dnow
+ if(video->have_mmx)
+ {
+ switch(switcher)
+ {
+ case 0x3: reca_mmx(s, d, lx2, h); break;
+ case 0x2: recac_mmx(s, d, lx2, h); break;
+ case 0x1: rec_mmx(s, d, lx2, h); break;
+ case 0x0: recc_mmx(s, d, lx2, h); break;
+ case 0x7: recva_mmx(s, d, lx, lx2, h); break;
+ case 0x6: recvac_mmx(s, d, lx, lx2, h); break;
+ case 0x5: recv_mmx(s, d, lx, lx2, h); break;
+ case 0x4: recvc_mmx(s, d, lx, lx2, h); break;
+ case 0x9: rech_mmx(s, d, lx2, h); break;
+ case 0x8: rechc_mmx(s, d, lx2, h); break;
+ }
+ }
+ else
+#endif
+ {
+ switch(switcher)
+ {
+ case 0x3: reca(s, d, lx2, h); break;
+ case 0x2: recac(s, d, lx2, h); break;
+ case 0x1: rec(s, d, lx2, h); break;
+ case 0x0: recc(s, d, lx2, h); break;
+ case 0x7: recva(s, d, lx, lx2, h); break;
+ case 0x6: recvac(s, d, lx, lx2, h); break;
+ case 0x5: recv_(s, d, lx, lx2, h); break;
+ case 0x4: recvc(s, d, lx, lx2, h); break;
+ case 0x9: rech(s, d, lx2, h); break;
+ case 0x8: rechc(s, d, lx2, h); break;
+ }
+ }
+
+// Unaccelerated functions
+ switch(switcher)
+ {
+ case 0xb: recha(s, d, lx2, h); break;
+ case 0xa: rechac(s, d, lx2, h); break;
+ case 0xf: rec4a(s, d, lx, lx2, h); break;
+ case 0xe: rec4ac(s, d, lx, lx2, h); break;
+ case 0xd: rec4(s, d, lx, lx2, h); break;
+ case 0xc: rec4c(s, d, lx, lx2, h); break;
+ }
+}
+
+/*
+ unsigned char *src[]; * prediction source buffer *
+ int sfield; * prediction source field number (0 or 1) *
+ unsigned char *dst[]; * prediction destination buffer *
+ int dfield; * prediction destination field number (0 or 1)*
+ int lx,lx2; * horizontal offsets *
+ int w,h; * prediction block/sub-block width, height *
+ int x,y; * pixel co-ordinates of top-left sample in current MB *
+ int dx,dy; * horizontal, vertical motion vector *
+ int addflag; * add prediction error to prediction ? *
+*/
+static void recon(mpeg3video_t *video,
+ unsigned char *src[],
+ int sfield,
+ unsigned char *dst[],
+ int dfield,
+ int lx,
+ int lx2,
+ int w,
+ int h,
+ int x,
+ int y,
+ int dx,
+ int dy,
+ int addflag)
+{
+
+/* Y */
+ recon_comp(video, (src[0] + (sfield ? (lx2 >> 1) : 0)),
+ dst[0] + (dfield ? (lx2 >> 1) : 0),
+ lx, lx2, w, h, x, y, dx, dy, addflag);
+
+ if(video->chroma_format != CHROMA444)
+ {
+ lx >>= 1;
+ dx /= 2;
+ lx2 >>= 1;
+ w = 0;
+ x >>= 1;
+ }
+
+ if(video->chroma_format == CHROMA420)
+ {
+ h >>= 1;
+ dy /= 2;
+ y >>= 1;
+ }
+
+/* Cb */
+ recon_comp(video, (src[1] + (sfield ? (lx2 >> 1) : 0)),
+ dst[1] + (dfield ? (lx2 >> 1) : 0),
+ lx, lx2, w, h, x, y, dx, dy, addflag);
+
+/* Cr */
+ recon_comp(video, (src[2] + (sfield ? (lx2 >> 1) : 0)),
+ dst[2] + (dfield ? (lx2 >> 1) : 0),
+ lx, lx2, w, h, x, y, dx, dy, addflag);
+}
+
+#define WIDTH 1
+
+int mpeg3video_reconstruct(mpeg3video_t *video,
+ int bx,
+ int by,
+ int mb_type,
+ int motion_type,
+ int PMV[2][2][2],
+ int mv_field_sel[2][2],
+ int dmvector[2],
+ int stwtype)
+{
+ int currentfield;
+ unsigned char **predframe;
+ int DMV[2][2];
+ int stwtop, stwbot;
+
+ stwtop = stwtype % 3; /* 0:temporal, 1 : (spat+temp) / 2, 2 : spatial */
+ stwbot = stwtype / 3;
+
+ if((mb_type & MB_FORWARD) || (video->pict_type == P_TYPE))
+ {
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+ if((motion_type == MC_FRAME) || !(mb_type & MB_FORWARD))
+ {
+/* frame-based prediction */
+ {
+ if(stwtop < 2)
+ recon(video, video->oldrefframe, 0, video->newframe, 0,
+ video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by,
+ PMV[0][0][0], PMV[0][0][1], stwtop);
+
+ if(stwbot < 2)
+ recon(video, video->oldrefframe, 1, video->newframe, 1,
+ video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by,
+ PMV[0][0][0], PMV[0][0][1], stwbot);
+ }
+ }
+ else if(motion_type == MC_FIELD) /* field-based prediction */
+ {
+/* top field prediction */
+ if(stwtop < 2)
+ recon(video, video->oldrefframe, mv_field_sel[0][0], video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by >> 1,
+ PMV[0][0][0], PMV[0][0][1] >> 1, stwtop);
+
+/* bottom field prediction */
+ if(stwbot < 2)
+ recon(video, video->oldrefframe, mv_field_sel[1][0], video->newframe, 1,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by >> 1,
+ PMV[1][0][0], PMV[1][0][1] >> 1, stwbot);
+ }
+ else if(motion_type == MC_DMV)
+ {
+/* dual prime prediction */
+/* calculate derived motion vectors */
+ mpeg3video_calc_dmv(video,
+ DMV,
+ dmvector,
+ PMV[0][0][0],
+ PMV[0][0][1] >> 1);
+
+ if(stwtop < 2)
+ {
+/* predict top field from top field */
+ recon(video, video->oldrefframe, 0, video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1,
+ PMV[0][0][0], PMV[0][0][1] >> 1, 0);
+
+/* predict and add to top field from bottom field */
+ recon(video, video->oldrefframe, 1, video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1,
+ DMV[0][0], DMV[0][1], 1);
+ }
+
+ if(stwbot < 2)
+ {
+/* predict bottom field from bottom field */
+ recon(video, video->oldrefframe, 1, video->newframe, 1,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by>>1,
+ PMV[0][0][0], PMV[0][0][1]>>1, 0);
+
+/* predict and add to bottom field from top field */
+ recon(video, video->oldrefframe, 0, video->newframe, 1,
+ video->coded_picture_width << 1, video->coded_picture_width<<1, WIDTH, 8, bx, by>>1,
+ DMV[1][0], DMV[1][1], 1);
+ }
+ }
+ else
+/* invalid motion_type */
+/* fprintf(stderr, "reconstruct: invalid motion_type\n"); */
+ ;
+ }
+ else
+ {
+/* TOP_FIELD or BOTTOM_FIELD */
+/* field picture */
+ currentfield = (video->pict_struct == BOTTOM_FIELD);
+
+/* determine which frame to use for prediction */
+ if((video->pict_type == P_TYPE) && video->secondfield
+ && (currentfield != mv_field_sel[0][0]))
+ predframe = video->refframe; /* same frame */
+ else
+ predframe = video->oldrefframe; /* previous frame */
+
+ if((motion_type == MC_FIELD) || !(mb_type & MB_FORWARD))
+ {
+/* field-based prediction */
+ if(stwtop < 2)
+ recon(video, predframe,mv_field_sel[0][0],video->newframe,0,
+ video->coded_picture_width << 1,video->coded_picture_width << 1,WIDTH,16,bx,by,
+ PMV[0][0][0],PMV[0][0][1],stwtop);
+ }
+ else
+ if(motion_type == MC_16X8)
+ {
+ if(stwtop < 2)
+ {
+ recon(video, predframe, mv_field_sel[0][0], video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by,
+ PMV[0][0][0], PMV[0][0][1], stwtop);
+
+ /* determine which frame to use for lower half prediction */
+ if((video->pict_type==P_TYPE) && video->secondfield
+ && (currentfield!=mv_field_sel[1][0]))
+ predframe = video->refframe; /* same frame */
+ else
+ predframe = video->oldrefframe; /* previous frame */
+
+ recon(video, predframe, mv_field_sel[1][0], video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by+8,
+ PMV[1][0][0], PMV[1][0][1], stwtop);
+ }
+ }
+ else
+ if(motion_type == MC_DMV) /* dual prime prediction */
+ {
+ if(video->secondfield)
+ predframe = video->refframe; /* same frame */
+ else
+ predframe = video->oldrefframe; /* previous frame */
+
+/* calculate derived motion vectors */
+ mpeg3video_calc_dmv(video,
+ DMV,
+ dmvector,
+ PMV[0][0][0],
+ PMV[0][0][1]);
+
+/* predict from field of same parity */
+ recon(video, video->oldrefframe, currentfield, video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by,
+ PMV[0][0][0], PMV[0][0][1], 0);
+
+/* predict from field of opposite parity */
+ recon(video, predframe, !currentfield, video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by,
+ DMV[0][0], DMV[0][1], 1);
+ }
+ else
+/* invalid motion_type */
+/* fprintf(stderr, "reconstruct: invalid motion_type\n"); */
+ ;
+ }
+ stwtop = stwbot = 1;
+ }
+
+ if(mb_type & MB_BACKWARD)
+ {
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+ if(motion_type == MC_FRAME)
+ {
+/* frame-based prediction */
+ if(stwtop < 2)
+ recon(video, video->refframe, 0, video->newframe, 0,
+ video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by,
+ PMV[0][1][0], PMV[0][1][1], stwtop);
+
+ if(stwbot < 2)
+ recon(video, video->refframe, 1, video->newframe, 1,
+ video->coded_picture_width, video->coded_picture_width << 1, WIDTH, 8, bx, by,
+ PMV[0][1][0], PMV[0][1][1], stwbot);
+ }
+ else
+ {
+/* field-based prediction */
+/* top field prediction */
+ if(stwtop < 2)
+ {
+ recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0,
+ (video->coded_picture_width << 1), (video->coded_picture_width<<1), WIDTH, 8, bx, (by >> 1),
+ PMV[0][1][0], (PMV[0][1][1] >> 1), stwtop);
+ }
+
+/* bottom field prediction */
+ if(stwbot < 2)
+ {
+ recon(video, video->refframe, mv_field_sel[1][1], video->newframe, 1, (video->coded_picture_width << 1),
+ (video->coded_picture_width << 1), WIDTH, 8, bx, (by>>1),
+ PMV[1][1][0], (PMV[1][1][1]>>1), stwbot);
+ }
+ }
+ }
+ else
+ {
+/* TOP_FIELD or BOTTOM_FIELD */
+/* field picture */
+ if(motion_type == MC_FIELD)
+ {
+/* field-based prediction */
+ recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 16, bx, by,
+ PMV[0][1][0], PMV[0][1][1], stwtop);
+ }
+ else if(motion_type==MC_16X8)
+ {
+ recon(video, video->refframe, mv_field_sel[0][1], video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by,
+ PMV[0][1][0], PMV[0][1][1], stwtop);
+
+ recon(video, video->refframe, mv_field_sel[1][1], video->newframe, 0,
+ video->coded_picture_width << 1, video->coded_picture_width << 1, WIDTH, 8, bx, by+8,
+ PMV[1][1][0], PMV[1][1][1], stwtop);
+ }
+ else
+/* invalid motion_type */
+/* fprintf(stderr, "reconstruct: invalid motion_type\n"); */
+ ;
+ }
+ } /* mb_type & MB_BACKWARD */
+ return 0;
+}
+
+
diff --git a/core/multimedia/opieplayer/libmpeg3/video/seek.c b/core/multimedia/opieplayer/libmpeg3/video/seek.c
new file mode 100644
index 0000000..04faba4
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/seek.c
@@ -0,0 +1,233 @@
+#include "../mpeg3private.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include <stdlib.h>
+#include <string.h>
+
+unsigned int mpeg3bits_next_startcode(mpeg3_bits_t* stream)
+{
+/* Perform forwards search */
+ mpeg3bits_byte_align(stream);
+
+/* Perform search */
+ while((mpeg3bits_showbits32_noptr(stream) >> 8) != MPEG3_PACKET_START_CODE_PREFIX &&
+ !mpeg3bits_eof(stream))
+ {
+ mpeg3bits_getbyte_noptr(stream);
+ }
+ return mpeg3bits_showbits32_noptr(stream);
+}
+
+/* Line up on the beginning of the next code. */
+int mpeg3video_next_code(mpeg3_bits_t* stream, unsigned int code)
+{
+ while(!mpeg3bits_eof(stream) &&
+ mpeg3bits_showbits32_noptr(stream) != code)
+ {
+ mpeg3bits_getbyte_noptr(stream);
+ }
+ return mpeg3bits_eof(stream);
+}
+
+/* Line up on the beginning of the previous code. */
+int mpeg3video_prev_code(mpeg3_bits_t* stream, unsigned int code)
+{
+ while(!mpeg3bits_bof(stream) &&
+ mpeg3bits_showbits_reverse(stream, 32) != code)
+ {
+ mpeg3bits_getbits_reverse(stream, 8);
+ }
+ return mpeg3bits_bof(stream);
+}
+
+long mpeg3video_goptimecode_to_frame(mpeg3video_t *video)
+{
+/* printf("mpeg3video_goptimecode_to_frame %d %d %d %d %f\n", */
+/* video->gop_timecode.hour, video->gop_timecode.minute, video->gop_timecode.second, video->gop_timecode.frame, video->frame_rate); */
+ return (long)(video->gop_timecode.hour * 3600 * video->frame_rate +
+ video->gop_timecode.minute * 60 * video->frame_rate +
+ video->gop_timecode.second * video->frame_rate +
+ video->gop_timecode.frame) - 1 - video->first_frame;
+}
+
+int mpeg3video_match_refframes(mpeg3video_t *video)
+{
+ unsigned char *dst, *src;
+ int i, j, size;
+
+ for(i = 0; i < 3; i++)
+ {
+ if(video->newframe[i])
+ {
+ if(video->newframe[i] == video->refframe[i])
+ {
+ src = video->refframe[i];
+ dst = video->oldrefframe[i];
+ }
+ else
+ {
+ src = video->oldrefframe[i];
+ dst = video->refframe[i];
+ }
+
+ if(i == 0)
+ size = video->coded_picture_width * video->coded_picture_height + 32 * video->coded_picture_width;
+ else
+ size = video->chrom_width * video->chrom_height + 32 * video->chrom_width;
+
+ memcpy(dst, src, size);
+ }
+ }
+ return 0;
+}
+
+int mpeg3video_seek(mpeg3video_t *video)
+{
+ long this_gop_start;
+ int result = 0;
+ int back_step;
+ int attempts;
+ mpeg3_t *file = video->file;
+ mpeg3_bits_t *vstream = video->vstream;
+ double percentage;
+ long frame_number;
+ int match_refframes = 1;
+
+/* Seek to a percentage */
+ if(video->percentage_seek >= 0)
+ {
+ percentage = video->percentage_seek;
+ video->percentage_seek = -1;
+ mpeg3bits_seek_percentage(vstream, percentage);
+// Go to previous I-frame
+ mpeg3bits_start_reverse(vstream);
+ result = mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE);
+ if(!result) mpeg3bits_getbits_reverse(vstream, 32);
+ mpeg3bits_start_forward(vstream);
+
+ if(mpeg3bits_tell_percentage(vstream) < 0) mpeg3bits_seek_percentage(vstream, 0);
+
+// Read up to the correct percentage
+ result = 0;
+ while(!result && mpeg3bits_tell_percentage(vstream) < percentage)
+ {
+ result = mpeg3video_read_frame_backend(video, 0);
+ if(match_refframes)
+ mpeg3video_match_refframes(video);
+ match_refframes = 0;
+ }
+ }
+ else
+/* Seek to a frame */
+ if(video->frame_seek >= 0)
+ {
+ frame_number = video->frame_seek;
+ video->frame_seek = -1;
+ if(frame_number < 0) frame_number = 0;
+ if(frame_number > video->maxframe) frame_number = video->maxframe;
+
+/* Seek to start of file */
+ if(frame_number < 16)
+ {
+ video->repeat_count = video->current_repeat = 0;
+ mpeg3bits_seek_start(vstream);
+ video->framenum = 0;
+ result = mpeg3video_drop_frames(video, frame_number - video->framenum);
+ }
+ else
+ {
+/* Seek to an I frame. */
+ if((frame_number < video->framenum || frame_number - video->framenum > MPEG3_SEEK_THRESHOLD))
+ {
+/* Elementary stream */
+ if(file->is_video_stream)
+ {
+ mpeg3_t *file = video->file;
+ mpeg3_vtrack_t *track = video->track;
+ long byte = (long)((float)(mpeg3demuxer_total_bytes(vstream->demuxer) /
+ track->total_frames) *
+ frame_number);
+ long minimum = 65535;
+ int done = 0;
+
+//printf("seek elementary %d\n", frame_number);
+/* Get GOP just before frame */
+ do
+ {
+ result = mpeg3bits_seek_byte(vstream, byte);
+ mpeg3bits_start_reverse(vstream);
+ if(!result) result = mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE);
+ mpeg3bits_start_forward(vstream);
+ mpeg3bits_getbits(vstream, 8);
+ if(!result) result = mpeg3video_getgophdr(video);
+ this_gop_start = mpeg3video_goptimecode_to_frame(video);
+
+//printf("wanted %ld guessed %ld byte %ld result %d\n", frame_number, this_gop_start, byte, result);
+ if(labs(this_gop_start - frame_number) >= labs(minimum))
+ done = 1;
+ else
+ {
+ minimum = this_gop_start - frame_number;
+ byte += (long)((float)(frame_number - this_gop_start) *
+ (float)(mpeg3demuxer_total_bytes(vstream->demuxer) /
+ track->total_frames));
+ if(byte < 0) byte = 0;
+ }
+ }while(!result && !done);
+
+//printf("wanted %d guessed %d\n", frame_number, this_gop_start);
+ if(!result)
+ {
+ video->framenum = this_gop_start;
+ result = mpeg3video_drop_frames(video, frame_number - video->framenum);
+ }
+ }
+ else
+/* System stream */
+ {
+ mpeg3bits_seek_time(vstream, (double)frame_number / video->frame_rate);
+ percentage = mpeg3bits_tell_percentage(vstream);
+//printf("seek frame %ld percentage %f byte %ld\n", frame_number, percentage, mpeg3bits_tell(vstream));
+ mpeg3bits_start_reverse(vstream);
+ mpeg3video_prev_code(vstream, MPEG3_GOP_START_CODE);
+ mpeg3bits_getbits_reverse(vstream, 32);
+ mpeg3bits_start_forward(vstream);
+//printf("seek system 1 %f\n", (double)frame_number / video->frame_rate);
+
+ while(!result && mpeg3bits_tell_percentage(vstream) < percentage)
+ {
+ result = mpeg3video_read_frame_backend(video, 0);
+ if(match_refframes)
+ mpeg3video_match_refframes(video);
+
+//printf("seek system 2 %f %f\n", mpeg3bits_tell_percentage(vstream) / percentage);
+ match_refframes = 0;
+ }
+//printf("seek system 3 %f\n", (double)frame_number / video->frame_rate);
+ }
+
+ video->framenum = frame_number;
+ }
+ else
+// Drop frames
+ {
+ mpeg3video_drop_frames(video, frame_number - video->framenum);
+ }
+ }
+ }
+
+ return result;
+}
+
+int mpeg3video_drop_frames(mpeg3video_t *video, long frames)
+{
+ int result = 0;
+ long frame_number = video->framenum + frames;
+
+/* Read the selected number of frames and skip b-frames */
+ while(!result && frame_number > video->framenum)
+ {
+ result = mpeg3video_read_frame_backend(video, frame_number - video->framenum);
+ }
+ return result;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/video/slice.c b/core/multimedia/opieplayer/libmpeg3/video/slice.c
new file mode 100644
index 0000000..90891b0
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/slice.c
@@ -0,0 +1,702 @@
+#include "../libmpeg3.h"
+#include "../mpeg3protos.h"
+#include "mpeg3video.h"
+#include "mpeg3videoprotos.h"
+#include "slice.h"
+
+#include <stdlib.h>
+
+static ULONGLONG MMX_128 = 0x80008000800080LL;
+
+int mpeg3_new_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
+{
+ pthread_mutexattr_t mutex_attr;
+ slice_buffer->data = (unsigned char*)malloc(1024);
+ slice_buffer->buffer_size = 0;
+ slice_buffer->buffer_allocation = 1024;
+ slice_buffer->current_position = 0;
+ slice_buffer->bits_size = 0;
+ slice_buffer->bits = 0;
+ slice_buffer->done = 0;
+ pthread_mutexattr_init(&mutex_attr);
+ pthread_mutex_init(&(slice_buffer->completion_lock), &mutex_attr);
+ return 0;
+}
+
+int mpeg3_delete_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
+{
+ free(slice_buffer->data);
+ pthread_mutex_destroy(&(slice_buffer->completion_lock));
+ return 0;
+}
+
+int mpeg3_expand_slice_buffer(mpeg3_slice_buffer_t *slice_buffer)
+{
+ int i;
+ unsigned char *new_buffer =
+ (unsigned char*)malloc(slice_buffer->buffer_allocation * 2);
+ for(i = 0; i < slice_buffer->buffer_size; i++)
+ new_buffer[i] = slice_buffer->data[i];
+ free(slice_buffer->data);
+ slice_buffer->data = new_buffer;
+ slice_buffer->buffer_allocation *= 2;
+ return 0;
+}
+
+/* limit coefficients to -2048..2047 */
+
+/* move/add 8x8-Block from block[comp] to refframe */
+
+static inline int mpeg3video_addblock(mpeg3_slice_t *slice,
+ mpeg3video_t *video,
+ int comp,
+ int bx,
+ int by,
+ int dct_type,
+ int addflag)
+{
+ int cc, i, iincr;
+ unsigned char *rfp;
+ short *bp;
+ int spar = slice->sparse[comp];
+/* color component index */
+ cc = (comp < 4) ? 0 : (comp & 1) + 1;
+
+ if(cc == 0)
+ {
+/* luminance */
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+ if(dct_type)
+ {
+/* field DCT coding */
+ rfp = video->newframe[0] +
+ video->coded_picture_width * (by + ((comp & 2) >> 1)) + bx + ((comp & 1) << 3);
+ iincr = (video->coded_picture_width << 1);
+ }
+ else
+ {
+/* frame DCT coding */
+ rfp = video->newframe[0] +
+ video->coded_picture_width * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
+ iincr = video->coded_picture_width;
+ }
+ }
+ else
+ {
+/* field picture */
+ rfp = video->newframe[0] +
+ (video->coded_picture_width << 1) * (by + ((comp & 2) << 2)) + bx + ((comp & 1) << 3);
+ iincr = (video->coded_picture_width << 1);
+ }
+ }
+ else
+ {
+/* chrominance */
+
+/* scale coordinates */
+ if(video->chroma_format != CHROMA444) bx >>= 1;
+ if(video->chroma_format == CHROMA420) by >>= 1;
+ if(video->pict_struct == FRAME_PICTURE)
+ {
+ if(dct_type && (video->chroma_format != CHROMA420))
+ {
+/* field DCT coding */
+ rfp = video->newframe[cc]
+ + video->chrom_width * (by + ((comp & 2) >> 1)) + bx + (comp & 8);
+ iincr = (video->chrom_width << 1);
+ }
+ else
+ {
+/* frame DCT coding */
+ rfp = video->newframe[cc]
+ + video->chrom_width * (by + ((comp & 2) << 2)) + bx + (comp & 8);
+ iincr = video->chrom_width;
+ }
+ }
+ else
+ {
+/* field picture */
+ rfp = video->newframe[cc]
+ + (video->chrom_width << 1) * (by + ((comp & 2) << 2)) + bx + (comp & 8);
+ iincr = (video->chrom_width << 1);
+ }
+ }
+
+ bp = slice->block[comp];
+
+ if(addflag)
+ {
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ {
+ if(spar)
+ {
+ __asm__ __volatile__(
+ "movq (%2), %%mm6\n" /* 4 blockvals */
+ "pxor %%mm4, %%mm4\n"
+ "punpcklwd %%mm6, %%mm6\n"
+ "punpcklwd %%mm6, %%mm6\n"
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n" /* 8 rindex1 */
+ "movq %%mm0, %%mm2\n"
+ "punpcklbw %%mm4, %%mm0\n"
+ "punpckhbw %%mm4, %%mm2\n"
+ "paddw %%mm6, %%mm0\n"
+ "paddw %%mm6, %%mm2\n"
+
+ "packuswb %%mm2, %%mm0\n"
+ "movq %%mm0, (%1)\n"
+
+ "leal (%1, %3), %1\n"
+ "loop 1b\n"
+ : /* scr dest */
+ : "c" (8),"r" (rfp), "r" (bp), "r" (iincr)
+ );
+ }
+ else
+ {
+ __asm__ __volatile__(
+ "pxor %%mm4, %%mm4\n"
+
+ ".align 8\n"
+ "1:"
+ "movq (%2), %%mm0\n" /* 8 rfp 0 1 2 3 4 5 6 7*/
+ "movq (%1), %%mm6\n" /* 4 blockvals 0 1 2 3 */
+
+ "movq %%mm0, %%mm2\n"
+ "movq 8(%1), %%mm5\n" /* 4 blockvals 0 1 2 3 */
+ "punpcklbw %%mm4, %%mm0\n" /* 0 2 4 6 */
+ "punpckhbw %%mm4, %%mm2\n" /* 1 3 5 7 */
+
+ "paddw %%mm6, %%mm0\n"
+ "paddw %%mm5, %%mm2\n"
+ "packuswb %%mm2, %%mm0\n"
+
+ "addl $16, %1\n"
+ "movq %%mm0, (%2)\n"
+
+ "leal (%2,%3), %2\n"
+ "loop 1b\n"
+ : /* scr dest */
+ : "c" (8),"r" (bp), "r" (rfp), "r" (iincr)
+ );
+ }
+ }
+ else
+#endif
+ for(i = 0; i < 8; i++)
+ {
+ rfp[0] = CLIP(bp[0] + rfp[0]);
+ rfp[1] = CLIP(bp[1] + rfp[1]);
+ rfp[2] = CLIP(bp[2] + rfp[2]);
+ rfp[3] = CLIP(bp[3] + rfp[3]);
+ rfp[4] = CLIP(bp[4] + rfp[4]);
+ rfp[5] = CLIP(bp[5] + rfp[5]);
+ rfp[6] = CLIP(bp[6] + rfp[6]);
+ rfp[7] = CLIP(bp[7] + rfp[7]);
+ rfp += iincr;
+ bp += 8;
+ }
+ }
+ else
+ {
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ {
+ if(spar)
+ {
+ __asm__ __volatile__(
+ "movd (%2), %%mm0\n" /* " 0 0 0 v1" */
+ "punpcklwd %%mm0, %%mm0\n" /* " 0 0 v1 v1" */
+ "punpcklwd %%mm0, %%mm0\n"
+ "paddw MMX_128, %%mm0\n"
+ "packuswb %%mm0, %%mm0\n"
+ "leal (%0,%1,2), %%eax\n"
+
+ "movq %%mm0, (%0, %1)\n"
+ "movq %%mm0, (%%eax)\n"
+ "leal (%%eax,%1,2), %0\n"
+ "movq %%mm0, (%%eax, %1)\n"
+
+ "movq %%mm0, (%0)\n"
+ "leal (%0,%1,2), %%eax\n"
+ "movq %%mm0, (%0, %1)\n"
+
+ "movq %%mm0, (%%eax)\n"
+ "movq %%mm0, (%%eax, %1)\n"
+ :
+ : "D" (rfp), "c" (iincr), "b" (bp)
+ : "eax");
+ }
+ else
+ {
+ __asm__ __volatile__(
+ "movq MMX_128,%%mm4\n"
+ ".align 8\n"
+ "1:"
+ "movq (%1), %%mm0\n"
+ "movq 8(%1), %%mm1\n"
+ "paddw %%mm4, %%mm0\n"
+
+ "movq 16(%1), %%mm2\n"
+ "paddw %%mm4, %%mm1\n"
+
+ "movq 24(%1), %%mm3\n"
+ "paddw %%mm4, %%mm2\n"
+
+ "packuswb %%mm1, %%mm0\n"
+ "paddw %%mm4, %%mm3\n"
+
+ "addl $32, %1\n"
+ "packuswb %%mm3, %%mm2\n"
+
+ "movq %%mm0, (%2)\n"
+
+ "movq %%mm2, (%2,%3)\n"
+
+ "leal (%2,%3,2), %2\n"
+ "loop 1b\n"
+ :
+ : "c" (4), "r" (bp), "r" (rfp), "r" (iincr)
+ );
+ }
+ }
+ else
+#endif
+ for(i = 0; i < 8; i++)
+ {
+ rfp[0] = CLIP(bp[0] + 128);
+ rfp[1] = CLIP(bp[1] + 128);
+ rfp[2] = CLIP(bp[2] + 128);
+ rfp[3] = CLIP(bp[3] + 128);
+ rfp[4] = CLIP(bp[4] + 128);
+ rfp[5] = CLIP(bp[5] + 128);
+ rfp[6] = CLIP(bp[6] + 128);
+ rfp[7] = CLIP(bp[7] + 128);
+ rfp+= iincr;
+ bp += 8;
+ }
+ }
+ return 0;
+}
+
+int mpeg3_decode_slice(mpeg3_slice_t *slice)
+{
+ mpeg3video_t *video = slice->video;
+ int comp;
+ int mb_type, cbp, motion_type = 0, dct_type;
+ int macroblock_address, mba_inc, mba_max;
+ int slice_vert_pos_ext;
+ unsigned int code;
+ int bx, by;
+ int dc_dct_pred[3];
+ int mv_count, mv_format, mvscale;
+ int pmv[2][2][2], mv_field_sel[2][2];
+ int dmv, dmvector[2];
+ int qs;
+ int stwtype, stwclass;
+ int snr_cbp;
+ int i;
+ mpeg3_slice_buffer_t *slice_buffer = slice->slice_buffer;
+
+/* number of macroblocks per picture */
+ mba_max = video->mb_width * video->mb_height;
+
+/* field picture has half as many macroblocks as frame */
+ if(video->pict_struct != FRAME_PICTURE)
+ mba_max >>= 1;
+
+/* macroblock address */
+ macroblock_address = 0;
+/* first macroblock in slice is not skipped */
+ mba_inc = 0;
+ slice->fault = 0;
+
+ code = mpeg3slice_getbits(slice_buffer, 32);
+/* decode slice header (may change quant_scale) */
+ slice_vert_pos_ext = mpeg3video_getslicehdr(slice, video);
+
+/* reset all DC coefficient and motion vector predictors */
+ dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
+ pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
+ pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
+
+ for(i = 0;
+ slice_buffer->current_position < slice_buffer->buffer_size;
+ i++)
+ {
+ if(mba_inc == 0)
+ {
+/* Done */
+ if(!mpeg3slice_showbits(slice_buffer, 23)) return 0;
+/* decode macroblock address increment */
+ mba_inc = mpeg3video_get_macroblock_address(slice);
+
+ if(slice->fault) return 1;
+
+ if(i == 0)
+ {
+/* Get the macroblock_address */
+ macroblock_address = ((slice_vert_pos_ext << 7) + (code & 255) - 1) * video->mb_width + mba_inc - 1;
+/* first macroblock in slice: not skipped */
+ mba_inc = 1;
+ }
+ }
+
+ if(slice->fault) return 1;
+
+ if(macroblock_address >= mba_max)
+ {
+/* mba_inc points beyond picture dimensions */
+ /*fprintf(stderr, "mpeg3_decode_slice: too many macroblocks in picture\n"); */
+ return 1;
+ }
+
+/* not skipped */
+ if(mba_inc == 1)
+ {
+ mpeg3video_macroblock_modes(slice,
+ video,
+ &mb_type,
+ &stwtype,
+ &stwclass,
+ &motion_type,
+ &mv_count,
+ &mv_format,
+ &dmv,
+ &mvscale,
+ &dct_type);
+
+ if(slice->fault) return 1;
+
+ if(mb_type & MB_QUANT)
+ {
+ qs = mpeg3slice_getbits(slice_buffer, 5);
+
+ if(video->mpeg2)
+ slice->quant_scale = video->qscale_type ? mpeg3_non_linear_mquant_table[qs] : (qs << 1);
+ else
+ slice->quant_scale = qs;
+
+ if(video->scalable_mode == SC_DP)
+/* make sure quant_scale is valid */
+ slice->quant_scale = slice->quant_scale;
+ }
+
+/* motion vectors */
+
+
+/* decode forward motion vectors */
+ if((mb_type & MB_FORWARD) || ((mb_type & MB_INTRA) && video->conceal_mv))
+ {
+ if(video->mpeg2)
+ mpeg3video_motion_vectors(slice,
+ video,
+ pmv,
+ dmvector,
+ mv_field_sel,
+ 0,
+ mv_count,
+ mv_format,
+ video->h_forw_r_size,
+ video->v_forw_r_size,
+ dmv,
+ mvscale);
+ else
+ mpeg3video_motion_vector(slice,
+ video,
+ pmv[0][0],
+ dmvector,
+ video->forw_r_size,
+ video->forw_r_size,
+ 0,
+ 0,
+ video->full_forw);
+ }
+ if(slice->fault) return 1;
+
+/* decode backward motion vectors */
+ if(mb_type & MB_BACKWARD)
+ {
+ if(video->mpeg2)
+ mpeg3video_motion_vectors(slice,
+ video,
+ pmv,
+ dmvector,
+ mv_field_sel,
+ 1,
+ mv_count,
+ mv_format,
+ video->h_back_r_size,
+ video->v_back_r_size,
+ 0,
+ mvscale);
+ else
+ mpeg3video_motion_vector(slice,
+ video,
+ pmv[0][1],
+ dmvector,
+ video->back_r_size,
+ video->back_r_size,
+ 0,
+ 0,
+ video->full_back);
+ }
+
+ if(slice->fault) return 1;
+
+/* remove marker_bit */
+ if((mb_type & MB_INTRA) && video->conceal_mv)
+ mpeg3slice_flushbit(slice_buffer);
+
+/* macroblock_pattern */
+ if(mb_type & MB_PATTERN)
+ {
+ cbp = mpeg3video_get_cbp(slice);
+ if(video->chroma_format == CHROMA422)
+ {
+/* coded_block_pattern_1 */
+ cbp = (cbp << 2) | mpeg3slice_getbits2(slice_buffer);
+ }
+ else
+ if(video->chroma_format == CHROMA444)
+ {
+/* coded_block_pattern_2 */
+ cbp = (cbp << 6) | mpeg3slice_getbits(slice_buffer, 6);
+ }
+ }
+ else
+ cbp = (mb_type & MB_INTRA) ? ((1 << video->blk_cnt) - 1) : 0;
+
+ if(slice->fault) return 1;
+/* decode blocks */
+ mpeg3video_clearblock(slice, 0, video->blk_cnt);
+ for(comp = 0; comp < video->blk_cnt; comp++)
+ {
+ if(cbp & (1 << (video->blk_cnt - comp - 1)))
+ {
+ if(mb_type & MB_INTRA)
+ {
+ if(video->mpeg2)
+ mpeg3video_getmpg2intrablock(slice, video, comp, dc_dct_pred);
+ else
+ mpeg3video_getintrablock(slice, video, comp, dc_dct_pred);
+ }
+ else
+ {
+ if(video->mpeg2)
+ mpeg3video_getmpg2interblock(slice, video, comp);
+ else
+ mpeg3video_getinterblock(slice, video, comp);
+ }
+ if(slice->fault) return 1;
+ }
+ }
+
+/* reset intra_dc predictors */
+ if(!(mb_type & MB_INTRA))
+ dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
+
+/* reset motion vector predictors */
+ if((mb_type & MB_INTRA) && !video->conceal_mv)
+ {
+/* intra mb without concealment motion vectors */
+ pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
+ pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
+ }
+
+ if((video->pict_type == P_TYPE) && !(mb_type & (MB_FORWARD | MB_INTRA)))
+ {
+/* non-intra mb without forward mv in a P picture */
+ pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
+
+/* derive motion_type */
+ if(video->pict_struct == FRAME_PICTURE)
+ motion_type = MC_FRAME;
+ else
+ {
+ motion_type = MC_FIELD;
+/* predict from field of same parity */
+ mv_field_sel[0][0] = (video->pict_struct == BOTTOM_FIELD);
+ }
+ }
+
+ if(stwclass == 4)
+ {
+/* purely spatially predicted macroblock */
+ pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
+ pmv[0][1][0] = pmv[0][1][1] = pmv[1][1][0] = pmv[1][1][1] = 0;
+ }
+ }
+ else
+ {
+/* mba_inc!=1: skipped macroblock */
+ mpeg3video_clearblock(slice, 0, video->blk_cnt);
+
+/* reset intra_dc predictors */
+ dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
+
+/* reset motion vector predictors */
+ if(video->pict_type == P_TYPE)
+ pmv[0][0][0] = pmv[0][0][1] = pmv[1][0][0] = pmv[1][0][1] = 0;
+
+/* derive motion_type */
+ if(video->pict_struct == FRAME_PICTURE)
+ motion_type = MC_FRAME;
+ else
+ {
+ motion_type = MC_FIELD;
+/* predict from field of same parity */
+ mv_field_sel[0][0] = mv_field_sel[0][1] = (video->pict_struct == BOTTOM_FIELD);
+ }
+
+/* skipped I are spatial-only predicted, */
+/* skipped P and B are temporal-only predicted */
+ stwtype = (video->pict_type == I_TYPE) ? 8 : 0;
+
+/* clear MB_INTRA */
+ mb_type &= ~MB_INTRA;
+
+/* no block data */
+ cbp = 0;
+ }
+
+ snr_cbp = 0;
+
+/* pixel coordinates of top left corner of current macroblock */
+ bx = 16 * (macroblock_address % video->mb_width);
+ by = 16 * (macroblock_address / video->mb_width);
+
+/* motion compensation */
+ if(!(mb_type & MB_INTRA))
+ mpeg3video_reconstruct(video,
+ bx,
+ by,
+ mb_type,
+ motion_type,
+ pmv,
+ mv_field_sel,
+ dmvector,
+ stwtype);
+
+/* copy or add block data into picture */
+ for(comp = 0; comp < video->blk_cnt; comp++)
+ {
+ if((cbp | snr_cbp) & (1 << (video->blk_cnt - 1 - comp)))
+ {
+#ifdef HAVE_MMX
+ if(video->have_mmx)
+ IDCT_mmx(slice->block[comp]);
+ else
+#endif
+ mpeg3video_idct_conversion(slice->block[comp]);
+
+ mpeg3video_addblock(slice,
+ video,
+ comp,
+ bx,
+ by,
+ dct_type,
+ (mb_type & MB_INTRA) == 0);
+ }
+ }
+
+/* advance to next macroblock */
+ macroblock_address++;
+ mba_inc--;
+ }
+
+ return 0;
+}
+
+void mpeg3_slice_loop(mpeg3_slice_t *slice)
+{
+ mpeg3video_t *video = slice->video;
+ int result = 1;
+
+ while(!slice->done)
+ {
+ pthread_mutex_lock(&(slice->input_lock));
+
+ if(!slice->done)
+ {
+/* Get a buffer to decode */
+ result = 1;
+ pthread_mutex_lock(&(video->slice_lock));
+ if(slice->buffer_step > 0)
+ {
+ while(slice->current_buffer <= slice->last_buffer)
+ {
+ if(!video->slice_buffers[slice->current_buffer].done &&
+ slice->current_buffer <= slice->last_buffer)
+ {
+ result = 0;
+ break;
+ }
+ slice->current_buffer += slice->buffer_step;
+ }
+ }
+ else
+ {
+ while(slice->current_buffer >= slice->last_buffer)
+ {
+ if(!video->slice_buffers[slice->current_buffer].done &&
+ slice->current_buffer >= slice->last_buffer)
+ {
+ result = 0;
+ break;
+ }
+ slice->current_buffer += slice->buffer_step;
+ }
+ }
+
+/* Got one */
+ if(!result && slice->current_buffer >= 0 && slice->current_buffer < video->total_slice_buffers)
+ {
+ slice->slice_buffer = &(video->slice_buffers[slice->current_buffer]);
+ slice->slice_buffer->done = 1;
+ pthread_mutex_unlock(&(video->slice_lock));
+ pthread_mutex_unlock(&(slice->input_lock));
+ mpeg3_decode_slice(slice);
+ pthread_mutex_unlock(&(slice->slice_buffer->completion_lock));
+ }
+ else
+ pthread_mutex_unlock(&(video->slice_lock));
+ }
+
+ pthread_mutex_unlock(&(slice->output_lock));
+ }
+}
+
+int mpeg3_new_slice_decoder(mpeg3video_t *video, mpeg3_slice_t *slice)
+{
+ pthread_attr_t attr;
+ //struct sched_param param;
+ pthread_mutexattr_t mutex_attr;
+
+ slice->video = video;
+ slice->done = 0;
+ pthread_mutexattr_init(&mutex_attr);
+ pthread_mutex_init(&(slice->input_lock), &mutex_attr);
+ pthread_mutex_lock(&(slice->input_lock));
+ pthread_mutex_init(&(slice->output_lock), &mutex_attr);
+ pthread_mutex_lock(&(slice->output_lock));
+
+ pthread_attr_init(&attr);
+ pthread_create(&(slice->tid), &attr,
+ (void * (*)(void *))mpeg3_slice_loop, slice);
+
+ return 0;
+}
+
+int mpeg3_delete_slice_decoder(mpeg3_slice_t *slice)
+{
+ slice->done = 1;
+ pthread_mutex_unlock(&(slice->input_lock));
+ pthread_join(slice->tid, 0);
+ pthread_mutex_destroy(&(slice->input_lock));
+ pthread_mutex_destroy(&(slice->output_lock));
+ return 0;
+}
diff --git a/core/multimedia/opieplayer/libmpeg3/video/slice.h b/core/multimedia/opieplayer/libmpeg3/video/slice.h
new file mode 100644
index 0000000..e36ffef
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/slice.h
@@ -0,0 +1,194 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef SLICE_H
+#define SLICE_H
+
+#ifndef _WIN32
+#include <pthread.h>
+#endif
+
+/* Array of these feeds the slice decoders */
+typedef struct
+{
+ unsigned char *data; /* Buffer for holding the slice data */
+ int buffer_size; /* Size of buffer */
+ int buffer_allocation; /* Space allocated for buffer */
+ int current_position; /* Position in buffer */
+ unsigned MPEG3_INT32 bits;
+ int bits_size;
+ pthread_mutex_t completion_lock; /* Lock slice until completion */
+ int done; /* Signal for slice decoder to skip */
+} mpeg3_slice_buffer_t;
+
+/* Each slice decoder */
+typedef struct
+{
+ struct mpeg3video_rec *video;
+ mpeg3_slice_buffer_t *slice_buffer;
+
+ int thread_number; /* Number of this thread */
+ int current_buffer; /* Buffer this slice decoder is on */
+ int buffer_step; /* Number of buffers to skip */
+ int last_buffer; /* Last buffer this decoder should process */
+ int fault;
+ int done;
+ int quant_scale;
+ int pri_brk; /* slice/macroblock */
+ short block[12][64];
+ int sparse[12];
+ pthread_t tid; /* ID of thread */
+ pthread_mutex_t input_lock, output_lock;
+} mpeg3_slice_t;
+
+#define mpeg3slice_fillbits(buffer, nbits) \
+ while(((mpeg3_slice_buffer_t*)(buffer))->bits_size < (nbits)) \
+ { \
+ if(((mpeg3_slice_buffer_t*)(buffer))->current_position < ((mpeg3_slice_buffer_t*)(buffer))->buffer_size) \
+ { \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits <<= 8; \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits |= ((mpeg3_slice_buffer_t*)(buffer))->data[((mpeg3_slice_buffer_t*)(buffer))->current_position++]; \
+ } \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits_size += 8; \
+ }
+
+#define mpeg3slice_flushbits(buffer, nbits) \
+ { \
+ mpeg3slice_fillbits((buffer), (nbits)); \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits_size -= (nbits); \
+ }
+
+#define mpeg3slice_flushbit(buffer) \
+{ \
+ if(((mpeg3_slice_buffer_t*)(buffer))->bits_size) \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits_size--; \
+ else \
+ if(((mpeg3_slice_buffer_t*)(buffer))->current_position < ((mpeg3_slice_buffer_t*)(buffer))->buffer_size) \
+ { \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits = \
+ ((mpeg3_slice_buffer_t*)(buffer))->data[((mpeg3_slice_buffer_t*)(buffer))->current_position++]; \
+ ((mpeg3_slice_buffer_t*)(buffer))->bits_size = 7; \
+ } \
+}
+
+extern inline unsigned int mpeg3slice_getbit(mpeg3_slice_buffer_t *buffer)
+{
+ if(buffer->bits_size)
+ return (buffer->bits >> (--buffer->bits_size)) & 0x1;
+ else
+ if(buffer->current_position < buffer->buffer_size)
+ {
+ buffer->bits = buffer->data[buffer->current_position++];
+ buffer->bits_size = 7;
+ return (buffer->bits >> 7) & 0x1;
+ }
+ return 0; // WWA - stop warn
+}
+
+extern inline unsigned int mpeg3slice_getbits2(mpeg3_slice_buffer_t *buffer)
+{
+ if(buffer->bits_size >= 2)
+ return (buffer->bits >> (buffer->bits_size -= 2)) & 0x3;
+ else
+ if(buffer->current_position < buffer->buffer_size)
+ {
+ buffer->bits <<= 8;
+ buffer->bits |= buffer->data[buffer->current_position++];
+ buffer->bits_size += 6;
+ return (buffer->bits >> buffer->bits_size) & 0x3;
+ }
+ return 0; // WWA - stop warn
+}
+
+extern inline unsigned int mpeg3slice_getbyte(mpeg3_slice_buffer_t *buffer)
+{
+ if(buffer->bits_size >= 8)
+ return (buffer->bits >> (buffer->bits_size -= 8)) & 0xff;
+ else
+ if(buffer->current_position < buffer->buffer_size)
+ {
+ buffer->bits <<= 8;
+ buffer->bits |= buffer->data[buffer->current_position++];
+ return (buffer->bits >> buffer->bits_size) & 0xff;
+ }
+ return 0; // WWA - stop warn
+}
+
+
+extern inline unsigned int mpeg3slice_getbits(mpeg3_slice_buffer_t *slice_buffer, int bits)
+{
+ if(bits == 1) return mpeg3slice_getbit(slice_buffer);
+ mpeg3slice_fillbits(slice_buffer, bits);
+ return (slice_buffer->bits >> (slice_buffer->bits_size -= bits)) & (0xffffffff >> (32 - bits));
+}
+
+extern inline unsigned int mpeg3slice_showbits16(mpeg3_slice_buffer_t *buffer)
+{
+ if(buffer->bits_size >= 16)
+ return (buffer->bits >> (buffer->bits_size - 16)) & 0xffff;
+ else
+ if(buffer->current_position < buffer->buffer_size)
+ {
+ buffer->bits <<= 16;
+ buffer->bits_size += 16;
+ buffer->bits |= (unsigned int)buffer->data[buffer->current_position++] << 8;
+ buffer->bits |= buffer->data[buffer->current_position++];
+ return (buffer->bits >> (buffer->bits_size - 16)) & 0xffff;
+ }
+ return 0; // WWA - stop warn
+}
+
+extern inline unsigned int mpeg3slice_showbits9(mpeg3_slice_buffer_t *buffer)
+{
+ if(buffer->bits_size >= 9)
+ return (buffer->bits >> (buffer->bits_size - 9)) & 0x1ff;
+ else
+ if(buffer->current_position < buffer->buffer_size)
+ {
+ buffer->bits <<= 16;
+ buffer->bits_size += 16;
+ buffer->bits |= (unsigned int)buffer->data[buffer->current_position++] << 8;
+ buffer->bits |= buffer->data[buffer->current_position++];
+ return (buffer->bits >> (buffer->bits_size - 9)) & 0x1ff;
+ }
+ return 0; // WWA - stop warn
+}
+
+extern inline unsigned int mpeg3slice_showbits5(mpeg3_slice_buffer_t *buffer)
+{
+ if(buffer->bits_size >= 5)
+ return (buffer->bits >> (buffer->bits_size - 5)) & 0x1f;
+ else
+ if(buffer->current_position < buffer->buffer_size)
+ {
+ buffer->bits <<= 8;
+ buffer->bits_size += 8;
+ buffer->bits |= buffer->data[buffer->current_position++];
+ return (buffer->bits >> (buffer->bits_size - 5)) & 0x1f;
+ }
+ return 0; // WWA - stop warn
+}
+
+extern inline unsigned int mpeg3slice_showbits(mpeg3_slice_buffer_t *slice_buffer, int bits)
+{
+ mpeg3slice_fillbits(slice_buffer, bits);
+ return (slice_buffer->bits >> (slice_buffer->bits_size - bits)) & (0xffffffff >> (32 - bits));
+}
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/video/vlc.c b/core/multimedia/opieplayer/libmpeg3/video/vlc.c
new file mode 100644
index 0000000..4328d8a
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/vlc.c
@@ -0,0 +1,421 @@
+#include "mpeg3video.h"
+#include "vlc.h"
+
+/* variable length code tables */
+
+/* Table B-3, mb_type in P-pictures, codes 001..1xx */
+mpeg3_VLCtab_t mpeg3_PMBtab0[8] = {
+ {ERROR,0},
+ {MB_FORWARD,3},
+ {MB_PATTERN,2}, {MB_PATTERN,2},
+ {MB_FORWARD|MB_PATTERN,1}, {MB_FORWARD|MB_PATTERN,1},
+ {MB_FORWARD|MB_PATTERN,1}, {MB_FORWARD|MB_PATTERN,1}
+};
+
+/* Table B-3, mb_type in P-pictures, codes 000001..00011x */
+mpeg3_VLCtab_t mpeg3_PMBtab1[8] = {
+ {ERROR,0},
+ {MB_QUANT|MB_INTRA,6},
+ {MB_QUANT|MB_PATTERN,5}, {MB_QUANT|MB_PATTERN,5},
+ {MB_QUANT|MB_FORWARD|MB_PATTERN,5}, {MB_QUANT|MB_FORWARD|MB_PATTERN,5},
+ {MB_INTRA,5}, {MB_INTRA,5}
+};
+
+/* Table B-4, mb_type in B-pictures, codes 0010..11xx */
+mpeg3_VLCtab_t mpeg3_BMBtab0[16] = {
+ {ERROR,0}, {ERROR,0},
+ {MB_FORWARD,4},
+ {MB_FORWARD|MB_PATTERN,4},
+ {MB_BACKWARD,3}, {MB_BACKWARD,3},
+ {MB_BACKWARD|MB_PATTERN,3}, {MB_BACKWARD|MB_PATTERN,3},
+ {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2},
+ {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}
+};
+
+/* Table B-4, mb_type in B-pictures, codes 000001..00011x */
+mpeg3_VLCtab_t mpeg3_BMBtab1[8] = {
+ {ERROR,0},
+ {MB_QUANT|MB_INTRA,6},
+ {MB_QUANT|MB_BACKWARD|MB_PATTERN,6},
+ {MB_QUANT|MB_FORWARD|MB_PATTERN,6},
+ {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,5},
+ {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,5},
+ {MB_INTRA,5}, {MB_INTRA,5}
+};
+
+/* Table B-5, mb_type in spat. scal. I-pictures, codes 0001..1xxx */
+mpeg3_VLCtab_t mpeg3_spIMBtab[16] = {
+ {ERROR,0},
+ {MB_CLASS4,4},
+ {MB_QUANT|MB_INTRA,4},
+ {MB_INTRA,4},
+ {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2},
+ {MB_CLASS4|MB_QUANT|MB_PATTERN,2}, {MB_CLASS4|MB_QUANT|MB_PATTERN,2},
+ {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1},
+ {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1},
+ {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1},
+ {MB_CLASS4|MB_PATTERN,1}, {MB_CLASS4|MB_PATTERN,1}
+};
+
+/* Table B-6, mb_type in spat. scal. P-pictures, codes 0010..11xx */
+mpeg3_VLCtab_t mpeg3_spPMBtab0[16] =
+{
+ {ERROR,0},{ERROR,0},
+ {MB_FORWARD,4},
+ {MB_WEIGHT|MB_FORWARD,4},
+ {MB_QUANT|MB_FORWARD|MB_PATTERN,3}, {MB_QUANT|MB_FORWARD|MB_PATTERN,3},
+ {MB_WEIGHT|MB_FORWARD|MB_PATTERN,3}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,3},
+ {MB_FORWARD|MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_PATTERN,2}, {MB_FORWARD|MB_PATTERN,2},
+ {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2},
+ {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2},
+ {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2},
+ {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,2}
+};
+
+/* Table B-6, mb_type in spat. scal. P-pictures, codes 0000010..000111x */
+mpeg3_VLCtab_t mpeg3_spPMBtab1[16] = {
+ {ERROR,0},{ERROR,0},
+ {MB_CLASS4|MB_QUANT|MB_PATTERN,7},
+ {MB_CLASS4,7},
+ {MB_PATTERN,7},
+ {MB_CLASS4|MB_PATTERN,7},
+ {MB_QUANT|MB_INTRA,7},
+ {MB_INTRA,7},
+ {MB_QUANT|MB_PATTERN,6}, {MB_QUANT|MB_PATTERN,6},
+ {MB_WEIGHT|MB_QUANT|MB_PATTERN,6}, {MB_WEIGHT|MB_QUANT|MB_PATTERN,6},
+ {MB_WEIGHT,6}, {MB_WEIGHT,6},
+ {MB_WEIGHT|MB_PATTERN,6}, {MB_WEIGHT|MB_PATTERN,6}
+};
+
+/* Table B-7, mb_type in spat. scal. B-pictures, codes 0010..11xx */
+mpeg3_VLCtab_t mpeg3_spBMBtab0[14] = {
+ {MB_FORWARD,4},
+ {MB_FORWARD|MB_PATTERN,4},
+ {MB_BACKWARD,3}, {MB_BACKWARD,3},
+ {MB_BACKWARD|MB_PATTERN,3}, {MB_BACKWARD|MB_PATTERN,3},
+ {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2},
+ {MB_FORWARD|MB_BACKWARD,2}, {MB_FORWARD|MB_BACKWARD,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2},
+ {MB_FORWARD|MB_BACKWARD|MB_PATTERN,2}
+};
+
+/* Table B-7, mb_type in spat. scal. B-pictures, codes 0000100..000111x */
+mpeg3_VLCtab_t mpeg3_spBMBtab1[12] = {
+ {MB_QUANT|MB_FORWARD|MB_PATTERN,7},
+ {MB_QUANT|MB_BACKWARD|MB_PATTERN,7},
+ {MB_INTRA,7},
+ {MB_QUANT|MB_FORWARD|MB_BACKWARD|MB_PATTERN,7},
+ {MB_WEIGHT|MB_FORWARD,6}, {MB_WEIGHT|MB_FORWARD,6},
+ {MB_WEIGHT|MB_FORWARD|MB_PATTERN,6}, {MB_WEIGHT|MB_FORWARD|MB_PATTERN,6},
+ {MB_WEIGHT|MB_BACKWARD,6}, {MB_WEIGHT|MB_BACKWARD,6},
+ {MB_WEIGHT|MB_BACKWARD|MB_PATTERN,6}, {MB_WEIGHT|MB_BACKWARD|MB_PATTERN,6}
+};
+
+/* Table B-7, mb_type in spat. scal. B-pictures, codes 00000100x..000001111 */
+mpeg3_VLCtab_t mpeg3_spBMBtab2[8] = {
+ {MB_QUANT|MB_INTRA,8}, {MB_QUANT|MB_INTRA,8},
+ {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,8},
+ {MB_WEIGHT|MB_QUANT|MB_FORWARD|MB_PATTERN,8},
+ {MB_WEIGHT|MB_QUANT|MB_BACKWARD|MB_PATTERN,9},
+ {MB_CLASS4|MB_QUANT|MB_PATTERN,9},
+ {MB_CLASS4,9},
+ {MB_CLASS4|MB_PATTERN,9}
+};
+
+/* Table B-8, mb_type in spat. scal. B-pictures, codes 001..1xx */
+mpeg3_VLCtab_t mpeg3_SNRMBtab[8] = {
+ {ERROR,0},
+ {0,3},
+ {MB_QUANT|MB_PATTERN,2}, {MB_QUANT|MB_PATTERN,2},
+ {MB_PATTERN,1}, {MB_PATTERN,1}, {MB_PATTERN,1}, {MB_PATTERN,1}
+};
+
+/* Table B-10, motion_code, codes 0001 ... 01xx */
+mpeg3_VLCtab_t mpeg3_MVtab0[8] =
+{ {ERROR,0}, {3,3}, {2,2}, {2,2}, {1,1}, {1,1}, {1,1}, {1,1}
+};
+
+/* Table B-10, motion_code, codes 0000011 ... 000011x */
+mpeg3_VLCtab_t mpeg3_MVtab1[8] =
+{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {7,6}, {6,6}, {5,6}, {4,5}, {4,5}
+};
+
+/* Table B-10, motion_code, codes 0000001100 ... 000001011x */
+mpeg3_VLCtab_t mpeg3_MVtab2[12] =
+{ {16,9}, {15,9}, {14,9}, {13,9},
+ {12,9}, {11,9}, {10,8}, {10,8},
+ {9,8}, {9,8}, {8,8}, {8,8}
+};
+
+/* Table B-9, coded_block_pattern, codes 01000 ... 111xx */
+mpeg3_VLCtab_t mpeg3_CBPtab0[32] =
+{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0},
+ {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0},
+ {62,5}, {2,5}, {61,5}, {1,5}, {56,5}, {52,5}, {44,5}, {28,5},
+ {40,5}, {20,5}, {48,5}, {12,5}, {32,4}, {32,4}, {16,4}, {16,4},
+ {8,4}, {8,4}, {4,4}, {4,4}, {60,3}, {60,3}, {60,3}, {60,3}
+};
+
+/* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */
+mpeg3_VLCtab_t mpeg3_CBPtab1[64] =
+{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0},
+ {58,8}, {54,8}, {46,8}, {30,8},
+ {57,8}, {53,8}, {45,8}, {29,8}, {38,8}, {26,8}, {37,8}, {25,8},
+ {43,8}, {23,8}, {51,8}, {15,8}, {42,8}, {22,8}, {50,8}, {14,8},
+ {41,8}, {21,8}, {49,8}, {13,8}, {35,8}, {19,8}, {11,8}, {7,8},
+ {34,7}, {34,7}, {18,7}, {18,7}, {10,7}, {10,7}, {6,7}, {6,7},
+ {33,7}, {33,7}, {17,7}, {17,7}, {9,7}, {9,7}, {5,7}, {5,7},
+ {63,6}, {63,6}, {63,6}, {63,6}, {3,6}, {3,6}, {3,6}, {3,6},
+ {36,6}, {36,6}, {36,6}, {36,6}, {24,6}, {24,6}, {24,6}, {24,6}
+};
+
+/* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */
+mpeg3_VLCtab_t mpeg3_CBPtab2[8] =
+{ {ERROR,0}, {0,9}, {39,9}, {27,9}, {59,9}, {55,9}, {47,9}, {31,9}
+};
+
+/* Table B-1, macroblock_address_increment, codes 00010 ... 011xx */
+mpeg3_VLCtab_t mpeg3_MBAtab1[16] =
+{ {ERROR,0}, {ERROR,0}, {7,5}, {6,5}, {5,4}, {5,4}, {4,4}, {4,4},
+ {3,3}, {3,3}, {3,3}, {3,3}, {2,3}, {2,3}, {2,3}, {2,3}
+};
+
+/* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */
+mpeg3_VLCtab_t mpeg3_MBAtab2[104] =
+{
+ {33,11}, {32,11}, {31,11}, {30,11}, {29,11}, {28,11}, {27,11}, {26,11},
+ {25,11}, {24,11}, {23,11}, {22,11}, {21,10}, {21,10}, {20,10}, {20,10},
+ {19,10}, {19,10}, {18,10}, {18,10}, {17,10}, {17,10}, {16,10}, {16,10},
+ {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8},
+ {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,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7},
+ {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,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}, {8,7}
+};
+
+/* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */
+mpeg3_VLCtab_t mpeg3_DClumtab0[32] =
+{ {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}, {ERROR, 0}
+};
+
+/* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */
+mpeg3_VLCtab_t mpeg3_DClumtab1[16] =
+{ {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}
+};
+
+/* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */
+mpeg3_VLCtab_t mpeg3_DCchromtab0[32] =
+{ {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}, {ERROR, 0}
+};
+
+/* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */
+mpeg3_VLCtab_t mpeg3_DCchromtab1[32] =
+{ {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6},
+ {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6},
+ {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7},
+ {8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10}
+};
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 0100 ... 1xxx (used for first (DC) coefficient)
+ */
+mpeg3_DCTtab_t mpeg3_DCTtabfirst[12] =
+{
+ {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3},
+ {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1},
+ {0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}
+};
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 0100 ... 1xxx (used for all other coefficients)
+ */
+mpeg3_DCTtab_t mpeg3_DCTtabnext[12] =
+{
+ {0,2,4}, {2,1,4}, {1,1,3}, {1,1,3},
+ {64,0,2}, {64,0,2}, {64,0,2}, {64,0,2}, /* EOB */
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}
+};
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 000001xx ... 00111xxx
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab0[60] =
+{
+ {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */
+ {2,2,7}, {2,2,7}, {9,1,7}, {9,1,7},
+ {0,4,7}, {0,4,7}, {8,1,7}, {8,1,7},
+ {7,1,6}, {7,1,6}, {7,1,6}, {7,1,6},
+ {6,1,6}, {6,1,6}, {6,1,6}, {6,1,6},
+ {1,2,6}, {1,2,6}, {1,2,6}, {1,2,6},
+ {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6},
+ {13,1,8}, {0,6,8}, {12,1,8}, {11,1,8},
+ {3,2,8}, {1,3,8}, {0,5,8}, {10,1,8},
+ {0,3,5}, {0,3,5}, {0,3,5}, {0,3,5},
+ {0,3,5}, {0,3,5}, {0,3,5}, {0,3,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},
+ {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
+ {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}
+};
+
+/* Table B-15, DCT coefficients table one,
+ * codes 000001xx ... 11111111
+*/
+mpeg3_DCTtab_t mpeg3_DCTtab0a[252] =
+{
+ {65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */
+ {7,1,7}, {7,1,7}, {8,1,7}, {8,1,7},
+ {6,1,7}, {6,1,7}, {2,2,7}, {2,2,7},
+ {0,7,6}, {0,7,6}, {0,7,6}, {0,7,6},
+ {0,6,6}, {0,6,6}, {0,6,6}, {0,6,6},
+ {4,1,6}, {4,1,6}, {4,1,6}, {4,1,6},
+ {5,1,6}, {5,1,6}, {5,1,6}, {5,1,6},
+ {1,5,8}, {11,1,8}, {0,11,8}, {0,10,8},
+ {13,1,8}, {12,1,8}, {3,2,8}, {1,4,8},
+ {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5},
+ {2,1,5}, {2,1,5}, {2,1,5}, {2,1,5},
+ {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5},
+ {1,2,5}, {1,2,5}, {1,2,5}, {1,2,5},
+ {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
+ {3,1,5}, {3,1,5}, {3,1,5}, {3,1,5},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {1,1,3}, {1,1,3}, {1,1,3}, {1,1,3},
+ {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, /* EOB */
+ {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
+ {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
+ {64,0,4}, {64,0,4}, {64,0,4}, {64,0,4},
+ {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
+ {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
+ {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
+ {0,3,4}, {0,3,4}, {0,3,4}, {0,3,4},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,1,2}, {0,1,2}, {0,1,2}, {0,1,2},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,2,3}, {0,2,3}, {0,2,3}, {0,2,3},
+ {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5},
+ {0,4,5}, {0,4,5}, {0,4,5}, {0,4,5},
+ {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5},
+ {0,5,5}, {0,5,5}, {0,5,5}, {0,5,5},
+ {9,1,7}, {9,1,7}, {1,3,7}, {1,3,7},
+ {10,1,7}, {10,1,7}, {0,8,7}, {0,8,7},
+ {0,9,7}, {0,9,7}, {0,12,8}, {0,13,8},
+ {2,3,8}, {4,2,8}, {0,14,8}, {0,15,8}
+};
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 0000001000 ... 0000001111
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab1[8] =
+{
+ {16,1,10}, {5,2,10}, {0,7,10}, {2,3,10},
+ {1,4,10}, {15,1,10}, {14,1,10}, {4,2,10}
+};
+
+/* Table B-15, DCT coefficients table one,
+ * codes 000000100x ... 000000111x
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab1a[8] =
+{
+ {5,2,9}, {5,2,9}, {14,1,9}, {14,1,9},
+ {2,4,10}, {16,1,10}, {15,1,9}, {15,1,9}
+};
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 000000010000 ... 000000011111
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab2[16] =
+{
+ {0,11,12}, {8,2,12}, {4,3,12}, {0,10,12},
+ {2,4,12}, {7,2,12}, {21,1,12}, {20,1,12},
+ {0,9,12}, {19,1,12}, {18,1,12}, {1,5,12},
+ {3,3,12}, {0,8,12}, {6,2,12}, {17,1,12}
+};
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 0000000010000 ... 0000000011111
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab3[16] =
+{
+ {10,2,13}, {9,2,13}, {5,3,13}, {3,4,13},
+ {2,5,13}, {1,7,13}, {1,6,13}, {0,15,13},
+ {0,14,13}, {0,13,13}, {0,12,13}, {26,1,13},
+ {25,1,13}, {24,1,13}, {23,1,13}, {22,1,13}
+};
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 00000000010000 ... 00000000011111
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab4[16] =
+{
+ {0,31,14}, {0,30,14}, {0,29,14}, {0,28,14},
+ {0,27,14}, {0,26,14}, {0,25,14}, {0,24,14},
+ {0,23,14}, {0,22,14}, {0,21,14}, {0,20,14},
+ {0,19,14}, {0,18,14}, {0,17,14}, {0,16,14}
+};
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 000000000010000 ... 000000000011111
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab5[16] =
+{
+ {0,40,15}, {0,39,15}, {0,38,15}, {0,37,15},
+ {0,36,15}, {0,35,15}, {0,34,15}, {0,33,15},
+ {0,32,15}, {1,14,15}, {1,13,15}, {1,12,15},
+ {1,11,15}, {1,10,15}, {1,9,15}, {1,8,15}
+};
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 0000000000010000 ... 0000000000011111
+ */
+mpeg3_DCTtab_t mpeg3_DCTtab6[16] =
+{
+ {1,18,16}, {1,17,16}, {1,16,16}, {1,15,16},
+ {6,3,16}, {16,2,16}, {15,2,16}, {14,2,16},
+ {13,2,16}, {12,2,16}, {11,2,16}, {31,1,16},
+ {30,1,16}, {29,1,16}, {28,1,16}, {27,1,16}
+};
diff --git a/core/multimedia/opieplayer/libmpeg3/video/vlc.h b/core/multimedia/opieplayer/libmpeg3/video/vlc.h
new file mode 100644
index 0000000..727040b
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/vlc.h
@@ -0,0 +1,164 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef VLC_H
+#define VLC_H
+
+/* variable length code tables */
+
+typedef struct {
+ char val, len;
+} mpeg3_VLCtab_t;
+
+typedef struct {
+ char run, level, len;
+} mpeg3_DCTtab_t;
+
+/* Added 03/38/96 by Alex de Jong : avoid IRIX GNU warning */
+#ifdef ERROR
+#undef ERROR
+#define ERROR 99
+#endif
+
+/* Table B-3, mb_type in P-pictures, codes 001..1xx */
+extern mpeg3_VLCtab_t mpeg3_PMBtab0[8];
+
+/* Table B-3, mb_type in P-pictures, codes 000001..00011x */
+extern mpeg3_VLCtab_t mpeg3_PMBtab1[8];
+
+/* Table B-4, mb_type in B-pictures, codes 0010..11xx */
+extern mpeg3_VLCtab_t mpeg3_BMBtab0[16];
+
+/* Table B-4, mb_type in B-pictures, codes 000001..00011x */
+extern mpeg3_VLCtab_t mpeg3_BMBtab1[8];
+
+/* Table B-5, mb_type in spat. scal. I-pictures, codes 0001..1xxx */
+extern mpeg3_VLCtab_t mpeg3_spIMBtab[16];
+
+/* Table B-6, mb_type in spat. scal. P-pictures, codes 0010..11xx */
+extern mpeg3_VLCtab_t mpeg3_spPMBtab0[16];
+
+/* Table B-6, mb_type in spat. scal. P-pictures, codes 0000010..000111x */
+extern mpeg3_VLCtab_t mpeg3_spPMBtab1[16];
+
+/* Table B-7, mb_type in spat. scal. B-pictures, codes 0010..11xx */
+extern mpeg3_VLCtab_t mpeg3_spBMBtab0[14];
+
+/* Table B-7, mb_type in spat. scal. B-pictures, codes 0000100..000111x */
+extern mpeg3_VLCtab_t mpeg3_spBMBtab1[12];
+
+/* Table B-7, mb_type in spat. scal. B-pictures, codes 00000100x..000001111 */
+extern mpeg3_VLCtab_t mpeg3_spBMBtab2[8];
+
+/* Table B-8, mb_type in spat. scal. B-pictures, codes 001..1xx */
+extern mpeg3_VLCtab_t mpeg3_SNRMBtab[8];
+
+/* Table B-10, motion_code, codes 0001 ... 01xx */
+extern mpeg3_VLCtab_t mpeg3_MVtab0[8];
+
+/* Table B-10, motion_code, codes 0000011 ... 000011x */
+extern mpeg3_VLCtab_t mpeg3_MVtab1[8];
+
+/* Table B-10, motion_code, codes 0000001100 ... 000001011x */
+extern mpeg3_VLCtab_t mpeg3_MVtab2[12];
+
+/* Table B-9, coded_block_pattern, codes 01000 ... 111xx */
+extern mpeg3_VLCtab_t mpeg3_CBPtab0[32];
+
+/* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */
+extern mpeg3_VLCtab_t mpeg3_CBPtab1[64];
+
+/* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */
+extern mpeg3_VLCtab_t mpeg3_CBPtab2[8];
+
+/* Table B-1, macroblock_address_increment, codes 00010 ... 011xx */
+extern mpeg3_VLCtab_t mpeg3_MBAtab1[16];
+
+/* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */
+extern mpeg3_VLCtab_t mpeg3_MBAtab2[104];
+
+/* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */
+extern mpeg3_VLCtab_t mpeg3_DClumtab0[32];
+
+/* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */
+extern mpeg3_VLCtab_t mpeg3_DClumtab1[16];
+
+/* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */
+extern mpeg3_VLCtab_t mpeg3_DCchromtab0[32];
+
+/* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */
+extern mpeg3_VLCtab_t mpeg3_DCchromtab1[32];
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 0100 ... 1xxx (used for first (DC) coefficient)
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtabfirst[12];
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 0100 ... 1xxx (used for all other coefficients)
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtabnext[12];
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 000001xx ... 00111xxx
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab0[60];
+
+/* Table B-15, DCT coefficients table one,
+ * codes 000001xx ... 11111111
+*/
+extern mpeg3_DCTtab_t mpeg3_DCTtab0a[252];
+
+/* Table B-14, DCT coefficients table zero,
+ * codes 0000001000 ... 0000001111
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab1[8];
+
+/* Table B-15, DCT coefficients table one,
+ * codes 000000100x ... 000000111x
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab1a[8];
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 000000010000 ... 000000011111
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab2[16];
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 0000000010000 ... 0000000011111
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab3[16];
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 00000000010000 ... 00000000011111
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab4[16];
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 000000000010000 ... 000000000011111
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab5[16];
+
+/* Table B-14/15, DCT coefficients table zero / one,
+ * codes 0000000000010000 ... 0000000000011111
+ */
+extern mpeg3_DCTtab_t mpeg3_DCTtab6[16];
+
+
+#endif
diff --git a/core/multimedia/opieplayer/libmpeg3/video/worksheet.c b/core/multimedia/opieplayer/libmpeg3/video/worksheet.c
new file mode 100644
index 0000000..c5a0553
--- a/dev/null
+++ b/core/multimedia/opieplayer/libmpeg3/video/worksheet.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+
+static LONGLONG mpeg3_MMX_601_Y_COEF = 0x0000004000400040;
+
+inline void mpeg3_601_mmx(unsigned long y,
+ unsigned long *output)
+{
+asm("
+/* Output will be 0x00rrggbb */
+ movd (%0), %%mm0; /* Load y 0x00000000000000yy */
+/* pmullw mpeg3_MMX_601_Y_COEF, %%mm0; // Scale y 0x00000000000000yy */
+ psllw $6, %%mm0; /* Shift y coeffs 0x0000yyy0yyy0yyy0 */
+ movd %%mm0, (%1); /* Store output */
+ "
+:
+: "r" (&y), "r" (output));
+}
+
+
+int main(int argc, char *argv[])
+{
+ unsigned char output[1024];
+
+ memset(output, 0, 1024);
+ mpeg3_601_mmx(1, (unsigned long*)output);
+ printf("%02x%02x\n", *(unsigned char*)&output[1], *(unsigned char*)&output[0]);
+}
diff --git a/core/multimedia/opieplayer/loopcontrol.cpp b/core/multimedia/opieplayer/loopcontrol.cpp
new file mode 100644
index 0000000..93a6e3f
--- a/dev/null
+++ b/core/multimedia/opieplayer/loopcontrol.cpp
@@ -0,0 +1,464 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qpe/qpeapplication.h>
+#ifdef Q_WS_QWS
+#include <qpe/qcopenvelope_qws.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+#include "loopcontrol.h"
+#include "videowidget.h"
+#include "audiodevice.h"
+#include "mediaplayerplugininterface.h"
+#include "mediaplayerstate.h"
+
+
+extern VideoWidget *videoUI; // now only needed to tell it to play a frame
+extern MediaPlayerState *mediaPlayerState;
+
+
+//#define DecodeLoopDebug(x) qDebug x
+#define DecodeLoopDebug(x)
+
+
+static char *audioBuffer = NULL;
+static AudioDevice *audioDevice = NULL;
+static bool disabledSuspendScreenSaver = FALSE;
+static bool previousSuspendMode = FALSE;
+
+
+pthread_t audio_tid;
+pthread_attr_t audio_attr;
+bool threadOkToGo = FALSE;
+
+
+class Mutex {
+public:
+ Mutex() {
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init( &attr );
+ pthread_mutex_init( &mutex, &attr );
+ pthread_mutexattr_destroy( &attr );
+ }
+
+ ~Mutex() {
+ pthread_mutex_destroy( &mutex );
+ }
+
+ void lock() {
+ pthread_mutex_lock( &mutex );
+ }
+
+ void unlock() {
+ pthread_mutex_unlock( &mutex );
+ }
+private:
+ pthread_mutex_t mutex;
+};
+
+
+void *startAudioThread( void *ptr ) {
+ LoopControl *mpegView = (LoopControl *)ptr;
+ while ( TRUE ) {
+ if ( threadOkToGo && mpegView->moreAudio )
+ mpegView->startAudio();
+ else
+ usleep( 10000 ); // Semi-buzy-wait till we are playing again
+ }
+ return 0;
+}
+
+
+Mutex *audioMutex;
+
+
+LoopControl::LoopControl( QObject *parent, const char *name )
+ : QObject( parent, name ) {
+ isMuted = FALSE;
+ connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( setMute(bool) ) );
+
+ audioMutex = new Mutex;
+
+ pthread_attr_init(&audio_attr);
+#define USE_REALTIME_AUDIO_THREAD
+#ifdef USE_REALTIME_AUDIO_THREAD
+ // Attempt to set it to real-time round robin
+ if ( pthread_attr_setschedpolicy( &audio_attr, SCHED_RR ) == 0 ) {
+ sched_param params;
+ params.sched_priority = 50;
+ pthread_attr_setschedparam(&audio_attr,&params);
+ } else {
+ qDebug( "Error setting up a realtime thread, reverting to using a normal thread." );
+ pthread_attr_destroy(&audio_attr);
+ pthread_attr_init(&audio_attr);
+ }
+#endif
+ pthread_create(&audio_tid, &audio_attr, (void * (*)(void *))startAudioThread, this);
+}
+
+
+LoopControl::~LoopControl() {
+ stop();
+}
+
+
+static long prev_frame = 0;
+static int currentSample = 0;
+
+
+void LoopControl::timerEvent( QTimerEvent *te ) {
+
+ if ( te->timerId() == videoId )
+ startVideo();
+
+ if ( te->timerId() == sliderId ) {
+ if ( hasAudioChannel && !hasVideoChannel && moreAudio ) {
+ mediaPlayerState->updatePosition( audioSampleCounter );
+ } else if ( hasVideoChannel && moreVideo ) {
+ mediaPlayerState->updatePosition( current_frame );
+ }
+ }
+
+ if ( !moreVideo && !moreAudio ) {
+ mediaPlayerState->setPlaying( FALSE );
+ mediaPlayerState->setNext();
+ }
+}
+
+
+void LoopControl::setPosition( long pos ) {
+ audioMutex->lock();
+
+ if ( hasVideoChannel && hasAudioChannel ) {
+ playtime.restart();
+ playtime = playtime.addMSecs( long((double)-pos * 1000.0 / framerate) );
+ current_frame = pos + 1;
+ mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
+ prev_frame = current_frame - 1;
+ currentSample = (int)( (double)current_frame * freq / framerate );
+ mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream );
+ audioSampleCounter = currentSample - 1;
+ } else if ( hasVideoChannel ) {
+ playtime.restart();
+ playtime = playtime.addMSecs( long((double)-pos * 1000.0 / framerate) );
+ current_frame = pos + 1;
+ mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
+ prev_frame = current_frame - 1;
+ } else if ( hasAudioChannel ) {
+ playtime.restart();
+ playtime = playtime.addMSecs( long((double)-pos * 1000.0 / freq) );
+ currentSample = pos + 1;
+ mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream );
+ audioSampleCounter = currentSample - 1;
+ }
+
+ audioMutex->unlock();
+}
+
+
+void LoopControl::startVideo() {
+
+ if ( moreVideo ) {
+
+ if ( mediaPlayerState->curDecoder() ) {
+
+ if ( hasAudioChannel && !isMuted ) {
+
+ current_frame = long( playtime.elapsed() * framerate / 1000 );
+
+ if ( prev_frame != -1 && current_frame <= prev_frame )
+ return;
+
+ } else {
+ // Don't skip
+ current_frame++;
+ }
+
+ if ( prev_frame == -1 || current_frame > prev_frame ) {
+ if ( current_frame > prev_frame + 1 ) {
+ mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
+ }
+ moreVideo = videoUI->playVideo();
+ prev_frame = current_frame;
+ }
+
+ } else {
+
+ moreVideo = FALSE;
+ killTimer( videoId );
+
+ }
+
+ }
+}
+
+
+void LoopControl::startAudio() {
+
+ audioMutex->lock();
+
+ if ( moreAudio ) {
+
+ if ( !isMuted && mediaPlayerState->curDecoder() ) {
+
+ currentSample = audioSampleCounter + 1;
+
+ if ( currentSample != audioSampleCounter + 1 )
+ qDebug("out of sync with decoder %i %i", currentSample, audioSampleCounter);
+
+ long samplesRead = 0;
+ mediaPlayerState->curDecoder()->audioReadSamples( (short*)audioBuffer, channels, 1024, samplesRead, stream );
+ long sampleWeShouldBeAt = long( playtime.elapsed() ) * freq / 1000;
+ long sampleWaitTime = currentSample - sampleWeShouldBeAt;
+
+ if ( ( sampleWaitTime > 2000 ) && ( sampleWaitTime < 20000 ) ) {
+ usleep( (long)((double)sampleWaitTime * 1000000.0 / freq) );
+ } else if ( sampleWaitTime <= -5000 ) {
+ qDebug("need to catch up by: %li (%i,%li)", -sampleWaitTime, currentSample, sampleWeShouldBeAt );
+ //mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream );
+ currentSample = sampleWeShouldBeAt;
+ }
+
+ audioDevice->write( audioBuffer, samplesRead * 2 * channels );
+ audioSampleCounter = currentSample + samplesRead - 1;
+
+ moreAudio = audioSampleCounter <= total_audio_samples;
+
+ } else {
+
+ moreAudio = FALSE;
+
+ }
+
+ }
+
+ audioMutex->unlock();
+}
+
+
+void LoopControl::killTimers() {
+
+ audioMutex->lock();
+
+ if ( hasVideoChannel )
+ killTimer( videoId );
+ killTimer( sliderId );
+ threadOkToGo = FALSE;
+
+ audioMutex->unlock();
+}
+
+
+void LoopControl::startTimers() {
+
+ audioMutex->lock();
+
+ moreVideo = FALSE;
+ moreAudio = FALSE;
+
+ if ( hasVideoChannel ) {
+ moreVideo = TRUE;
+ int mSecsBetweenFrames = (int)(100 / framerate); // 10% of the real value
+ videoId = startTimer( mSecsBetweenFrames );
+ }
+
+ if ( hasAudioChannel ) {
+ moreAudio = TRUE;
+ threadOkToGo = TRUE;
+ }
+
+ sliderId = startTimer( 300 ); // update slider every 1/3 second
+
+ audioMutex->unlock();
+}
+
+
+void LoopControl::setPaused( bool pause ) {
+
+ if ( !mediaPlayerState->curDecoder() || !mediaPlayerState->curDecoder()->isOpen() )
+ return;
+
+ if ( pause ) {
+ killTimers();
+ } else {
+ // Force an update of the position
+ mediaPlayerState->setPosition( mediaPlayerState->position() + 1 );
+ mediaPlayerState->setPosition( mediaPlayerState->position() - 1 );
+ // Just like we never stopped
+ startTimers();
+ }
+}
+
+
+void LoopControl::stop( bool willPlayAgainShortly ) {
+
+#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
+ if ( !willPlayAgainShortly && disabledSuspendScreenSaver ) {
+ disabledSuspendScreenSaver = FALSE;
+ // Re-enable the suspend mode
+ QCopEnvelope("QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
+ }
+#endif
+
+ if ( mediaPlayerState->curDecoder() && mediaPlayerState->curDecoder()->isOpen() ) {
+
+ killTimers();
+
+ audioMutex->lock();
+
+ mediaPlayerState->curDecoder()->close();
+
+ if ( audioDevice ) {
+ delete audioDevice;
+ delete audioBuffer;
+ audioDevice = 0;
+ audioBuffer = 0;
+ }
+
+ audioMutex->unlock();
+
+ }
+}
+
+
+bool LoopControl::init( const QString& filename ) {
+ stop();
+
+ audioMutex->lock();
+
+ fileName = filename;
+ stream = 0; // only play stream 0 for now
+ current_frame = total_video_frames = total_audio_samples = 0;
+
+ qDebug( "Using the %s decoder", mediaPlayerState->curDecoder()->pluginName() );
+
+ // ### Hack to use libmpeg3plugin to get the number of audio samples if we are using the libmad plugin
+ if ( mediaPlayerState->curDecoder()->pluginName() == QString("LibMadPlugin") ) {
+ if ( mediaPlayerState->libMpeg3Decoder() && mediaPlayerState->libMpeg3Decoder()->open( filename ) ) {
+ total_audio_samples = mediaPlayerState->libMpeg3Decoder()->audioSamples( 0 );
+ mediaPlayerState->libMpeg3Decoder()->close();
+ }
+ }
+
+ if ( !mediaPlayerState->curDecoder()|| !mediaPlayerState->curDecoder()->open( filename ) ) {
+ audioMutex->unlock();
+ return FALSE;
+ }
+
+ hasAudioChannel = mediaPlayerState->curDecoder()->audioStreams() > 0;
+ hasVideoChannel = mediaPlayerState->curDecoder()->videoStreams() > 0;
+
+ if ( hasAudioChannel ) {
+ int astream = 0;
+
+ channels = mediaPlayerState->curDecoder()->audioChannels( astream );
+ DecodeLoopDebug(( "channels = %d\n", channels ));
+
+ if ( !total_audio_samples )
+ total_audio_samples = mediaPlayerState->curDecoder()->audioSamples( astream );
+
+ total_audio_samples += 1000;
+
+ mediaPlayerState->setLength( total_audio_samples );
+
+ freq = mediaPlayerState->curDecoder()->audioFrequency( astream );
+ DecodeLoopDebug(( "frequency = %d\n", freq ));
+
+ audioSampleCounter = 0;
+
+ static const int bytes_per_sample = 2; //16 bit
+
+ audioDevice = new AudioDevice( freq, channels, bytes_per_sample );
+ audioBuffer = new char[ audioDevice->bufferSize() ];
+ channels = audioDevice->channels();
+
+ //### must check which frequency is actually used.
+ static const int size = 1;
+ short int buf[size];
+ long samplesRead = 0;
+ mediaPlayerState->curDecoder()->audioReadSamples( buf, channels, size, samplesRead, stream );
+ }
+
+ if ( hasVideoChannel ) {
+ total_video_frames = mediaPlayerState->curDecoder()->videoFrames( stream );
+
+ mediaPlayerState->setLength( total_video_frames );
+
+ framerate = mediaPlayerState->curDecoder()->videoFrameRate( stream );
+ DecodeLoopDebug(( "Frame rate %g total %ld", framerate, total_video_frames ));
+
+ if ( framerate <= 1.0 ) {
+ DecodeLoopDebug(( "Crazy frame rate, resetting to sensible" ));
+ framerate = 25;
+ }
+
+ if ( total_video_frames == 1 ) {
+ DecodeLoopDebug(( "Cannot seek to frame" ));
+ }
+
+ }
+
+ current_frame = 0;
+ prev_frame = -1;
+
+ connect( mediaPlayerState, SIGNAL( positionChanged( long ) ), this, SLOT( setPosition( long ) ) );
+ connect( mediaPlayerState, SIGNAL( pausedToggled( bool ) ), this, SLOT( setPaused( bool ) ) );
+
+ audioMutex->unlock();
+
+ return TRUE;
+}
+
+
+void LoopControl::play() {
+
+#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
+ if ( !disabledSuspendScreenSaver || previousSuspendMode != hasVideoChannel ) {
+ disabledSuspendScreenSaver = TRUE;
+ previousSuspendMode = hasVideoChannel;
+ // Stop the screen from blanking and power saving state
+ QCopEnvelope("QPE/System", "setScreenSaverMode(int)" )
+ << ( hasVideoChannel ? QPEApplication::Disable : QPEApplication::DisableSuspend );
+ }
+#endif
+
+ playtime.start();
+ startTimers();
+}
+
+
+void LoopControl::setMute( bool on ) {
+ if ( on != isMuted ) {
+ isMuted = on;
+ if ( !on ) {
+ // Force an update of the position
+ mediaPlayerState->setPosition( mediaPlayerState->position() + 1 );
+ mediaPlayerState->setPosition( mediaPlayerState->position() - 1 );
+ // Resume playing audio
+ moreAudio = TRUE;
+ }
+ }
+}
+
+
diff --git a/core/multimedia/opieplayer/loopcontrol.h b/core/multimedia/opieplayer/loopcontrol.h
new file mode 100644
index 0000000..967ee25
--- a/dev/null
+++ b/core/multimedia/opieplayer/loopcontrol.h
@@ -0,0 +1,88 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEGVIEW_H
+#define MPEGVIEW_H
+
+
+#include <qwidget.h>
+#include <qdatetime.h>
+
+
+class LoopControl : public QObject {
+ Q_OBJECT
+public:
+ LoopControl( QObject *parent, const char *name );
+ ~LoopControl();
+
+ bool init( const QString& filename );
+
+ bool hasVideo() const { return hasVideoChannel; }
+ bool hasAudio() const { return hasAudioChannel; }
+
+ long totalPlaytime() { return (long)(hasVideoChannel ? total_video_frames / framerate : total_audio_samples / freq); }
+
+ // These are public to run them from global functions needed to start threads
+ // Otherwise they would be private
+ void startAudio();
+ void startVideo();
+ bool moreAudio;
+ bool moreVideo;
+public slots:
+ void play();
+ void stop( bool willPlayAgainShortly = FALSE );
+
+ void setMute( bool );
+ void setPaused( bool );
+ void setPosition( long );
+
+signals:
+ void positionChanged( long, long );
+
+protected:
+ void timerEvent(QTimerEvent*);
+
+private:
+ void startTimers();
+ void killTimers();
+
+ QTime playtime;
+ int videoId;
+ int sliderId;
+
+ int audioSampleCounter;
+ long current_frame;
+ long total_video_frames;
+ long total_audio_samples;
+
+ float framerate;
+ int freq;
+ int stream;
+ int framecount;
+ int channels;
+
+ bool hasVideoChannel;
+ bool hasAudioChannel;
+ bool isMuted;
+ QString fileName;
+};
+
+
+#endif
+
diff --git a/core/multimedia/opieplayer/loopcontrol_threaded.cpp b/core/multimedia/opieplayer/loopcontrol_threaded.cpp
new file mode 100644
index 0000000..2ec4a48
--- a/dev/null
+++ b/core/multimedia/opieplayer/loopcontrol_threaded.cpp
@@ -0,0 +1,626 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#define _REENTRANT
+
+#include <qpe/qpeapplication.h>
+#include <qimage.h>
+#include <qpainter.h>
+#ifdef Q_WS_QWS
+#include <qpe/qcopenvelope_qws.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <pthread.h>
+#include "loopcontrol.h"
+#include "audiodevice.h"
+#include "videowidget.h"
+#include "audiowidget.h"
+#include "mediaplayerplugininterface.h"
+#include "mediaplayerstate.h"
+
+
+#if defined(QT_QWS_CUSTOM) || defined(QT_QWS_IPAQ)
+#define USE_REALTIME_AUDIO_THREAD
+#endif
+
+
+extern VideoWidget *videoUI; // now only needed to tell it to play a frame
+extern MediaPlayerState *mediaPlayerState;
+
+
+#define DecodeLoopDebug(x) qDebug x
+//#define DecodeLoopDebug(x)
+
+
+static char *audioBuffer = NULL;
+static AudioDevice *audioDevice = NULL;
+static bool disabledSuspendScreenSaver = FALSE;
+
+
+pthread_t video_tid;
+pthread_attr_t video_attr;
+pthread_t audio_tid;
+pthread_attr_t audio_attr;
+
+
+bool emitPlayFinished = FALSE;
+bool emitChangePos = FALSE;
+
+
+class Mutex {
+public:
+ Mutex() {
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init( &attr );
+ pthread_mutex_init( &mutex, &attr );
+ pthread_mutexattr_destroy( &attr );
+ }
+
+ ~Mutex() {
+ pthread_mutex_destroy( &mutex );
+ }
+
+ void lock() {
+ pthread_mutex_lock( &mutex );
+ }
+
+ void unlock() {
+ pthread_mutex_unlock( &mutex );
+ }
+/*
+ bool locked() {
+ switch ( pthread_mutex_trylock( &mutex ) ) {
+ case EBUSY:
+ return TRUE;
+ case 0:
+ pthread_mutex_unlock( &mutex );
+ default:
+ return FALSE;
+ }
+ }
+*/
+private:
+ pthread_mutex_t mutex;
+};
+
+
+class currentFrameObj {
+public:
+ currentFrameObj() : value( 0 ) { }
+ void set( long f ) {
+ mutex.lock();
+ value = f;
+ mediaPlayerState->curDecoder()->videoSetFrame( f, 0 );
+ mutex.unlock();
+ }
+ long get() {
+ return value;
+ }
+private:
+ long value;
+ Mutex mutex;
+};
+
+
+Mutex *videoMutex;
+Mutex *audioMutex;
+Mutex *globalMutex;
+
+
+clock_t begin;
+
+
+LoopControl::LoopControl( QObject *parent, const char *name )
+ : QObject( parent, name ) {
+ isMuted = FALSE;
+ connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( setMute(bool) ) );
+ timerid = startTimer( 200 );
+ videoMutex = new Mutex;
+ audioMutex = new Mutex;
+ globalMutex = new Mutex;
+ //begin = clock();
+}
+
+
+LoopControl::~LoopControl() {
+ stop();
+ killTimer( timerid );
+}
+
+
+static bool sendingNewPos = FALSE;
+static long prev_frame = 0;
+static int currentSample = 0;
+
+
+void LoopControl::timerEvent( QTimerEvent* ) {
+ // We need to emit playFinished from the main thread, not one of the
+ // decoding threads else we'll have all kinds of yucky things happen (reentrance).
+ // playFinished will eventually call stop() which stops these threads.
+ if ( emitPlayFinished ) {
+ emitPlayFinished = FALSE;
+ mediaPlayerState->setPlaying( FALSE );
+ }
+
+ if ( emitChangePos ) {
+
+ emitChangePos = FALSE;
+
+ if ( hasVideoChannel && hasAudioChannel ) {
+ sendingNewPos = TRUE;
+ mediaPlayerState->setPosition( current_frame );
+ } else if ( hasVideoChannel ) {
+ sendingNewPos = TRUE;
+ mediaPlayerState->setPosition( current_frame );
+ } else if ( hasAudioChannel ) {
+ sendingNewPos = TRUE;
+ mediaPlayerState->setPosition( audioSampleCounter );
+ }
+
+ }
+}
+
+
+
+
+void LoopControl::setPosition( long pos ) {
+ if ( sendingNewPos ) {
+ sendingNewPos = FALSE;
+ return;
+ }
+
+ if ( hasVideoChannel && hasAudioChannel ) {
+ videoMutex->lock();
+ audioMutex->lock();
+qDebug("setting position");
+ playtime.restart();
+ playtime = playtime.addMSecs( -pos * 1000 / framerate );
+ //begin = clock() - (double)pos * CLOCKS_PER_SEC / framerate;
+ current_frame = pos + 1;
+ mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
+ prev_frame = current_frame - 1;
+ currentSample = (int)( current_frame * freq / framerate );
+ mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream );
+ audioSampleCounter = currentSample - 1;
+ audioMutex->unlock();
+ videoMutex->unlock();
+ } else if ( hasVideoChannel ) {
+ videoMutex->lock();
+ playtime.restart();
+ playtime = playtime.addMSecs( -pos * 1000 / framerate );
+ //begin = clock() - (double)pos * CLOCKS_PER_SEC / framerate;
+ current_frame = pos + 1;
+ mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
+ videoMutex->unlock();
+ prev_frame = current_frame - 1;
+ } else if ( hasAudioChannel ) {
+ audioMutex->lock();
+ playtime.restart();
+ playtime = playtime.addMSecs( -pos * 1000 / freq );
+ //begin = clock() - (double)pos * CLOCKS_PER_SEC / freq;
+ currentSample = pos + 1; // (int)( current_frame * freq / framerate );
+ mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream );
+ audioSampleCounter = currentSample - 1;
+ audioMutex->unlock();
+ }
+}
+
+
+void *startVideoThread( void *ptr ) {
+ LoopControl *mpegView = (LoopControl *)ptr;
+ mpegView->startVideo();
+ return 0;
+}
+
+void *startAudioThread( void *ptr ) {
+ LoopControl *mpegView = (LoopControl *)ptr;
+ mpegView->startAudio();
+ return 0;
+}
+
+void LoopControl::startVideo() {
+ moreVideo = TRUE;
+
+ while ( moreVideo ) {
+
+ if ( mediaPlayerState->curDecoder() && hasVideoChannel ) {
+
+ if ( hasAudioChannel && !isMuted ) {
+
+ bool done = FALSE;
+
+ do {
+
+
+/*
+ videoMutex->lock();
+ current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 );
+ //current_frame = ( clock() - begin ) * (double)framerate / CLOCKS_PER_SEC;
+
+ // Sync to Audio
+// current_frame = (long)((double)(audioSampleCounter - 1000) * framerate / (double)freq);
+
+ long mSecsToNextFrame = 0;
+
+ if ( current_frame == prev_frame ) {
+ int nf = current_frame + 1;
+ if ( nf > 0 && nf != total_video_frames )
+ // mSecsToNextFrame = long(double(nf * CLOCKS_PER_SEC) / framerate) - ( clock() - begin );
+ mSecsToNextFrame = long(double(nf * 1000) / framerate) - ( playtime.elapsed() );
+ }
+ videoMutex->unlock();
+
+ if ( mSecsToNextFrame ) {
+ usleep( mSecsToNextFrame ); // wait a bit
+
+ videoMutex->lock();
+ // This should now be the next frame
+ current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 );
+ //current_frame = ( clock() - begin ) * (double)framerate / CLOCKS_PER_SEC;
+ videoMutex->unlock();
+ }
+
+ videoMutex->lock();
+ done = current_frame >= prev_frame;
+ videoMutex->unlock();
+*/
+ videoMutex->lock();
+ current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 );
+ done = current_frame >= prev_frame;
+ videoMutex->unlock();
+ if ( !done )
+ usleep( 1000 ); // wait a bit
+
+ } while ( !done );
+
+// qDebug("elapsed: %i %i (%f)", int( playtime.elapsed() ), current_frame, framerate );
+
+ } else {
+ videoMutex->lock();
+ current_frame++;
+ videoMutex->unlock();
+ }
+
+ videoMutex->lock();
+ bool check = current_frame && current_frame > prev_frame;
+ videoMutex->unlock();
+
+ if ( check ) {
+ videoMutex->lock();
+ if ( current_frame > prev_frame + 1 ) {
+ qDebug("skipped a frame");
+ mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
+ }
+ prev_frame = current_frame;
+ if ( moreVideo = videoUI->playVideo() )
+ emitChangePos = TRUE;
+ videoMutex->unlock();
+ }
+
+ } else
+ moreVideo = FALSE;
+
+ }
+
+ if ( !moreVideo && !moreAudio )
+ emitPlayFinished = TRUE;
+
+ pthread_exit(NULL);
+}
+
+void LoopControl::startAudio() {
+ moreAudio = TRUE;
+
+ while ( moreAudio ) {
+
+ if ( !isMuted && mediaPlayerState->curDecoder() && hasAudioChannel ) {
+
+ audioMutex->lock();
+ currentSample = mediaPlayerState->curDecoder()->audioGetSample( stream );
+
+ if ( currentSample == 0 )
+ currentSample = audioSampleCounter + 1;
+
+ if ( currentSample != audioSampleCounter + 1 )
+ qDebug("out of sync with decoder %i %i", currentSample, audioSampleCounter);
+ audioMutex->unlock();
+
+/*
+ int sampleWeShouldBeAt = int( playtime.elapsed() ) * freq / 1000;
+
+ if ( sampleWeShouldBeAt - currentSample > 20000 ) {
+ mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream );
+ currentSample = sampleWeShouldBeAt;
+ }
+*/
+ long samplesRead = 0;
+
+ const long samples = 1024;
+
+ moreAudio = !mediaPlayerState->curDecoder()->audioReadSamples( (short*)audioBuffer, channels, samples, samplesRead, stream );
+
+ audioMutex->lock();
+ long sampleWeShouldBeAt = long( playtime.elapsed() ) * freq / 1000;
+ //long sampleWeShouldBeAt = long( clock() - begin ) * (double) freq / CLOCKS_PER_SEC;
+ long sampleWaitTime = currentSample - sampleWeShouldBeAt;
+ audioMutex->unlock();
+
+ if ( sampleWaitTime >= 0 && sampleWaitTime <= 2000 ) {
+ //qDebug("sampleWaitTime: %i", sampleWaitTime);
+ usleep( ( sampleWaitTime * 1000000 ) / ( freq ) );
+ } else {
+ audioMutex->lock();
+ if ( sampleWaitTime <= -2000 ) {
+ qDebug("need to catch up by: %li (%i,%li)", -sampleWaitTime, currentSample, sampleWeShouldBeAt );
+ mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream );
+ currentSample = sampleWeShouldBeAt;
+ }
+ audioMutex->unlock();
+ }
+
+ audioDevice->write( audioBuffer, samplesRead * 2 * channels );
+
+ audioMutex->lock();
+// audioSampleCounter += samplesRead;
+ audioSampleCounter = currentSample + samplesRead - 1;
+ audioMutex->unlock();
+
+ if ( !hasVideoChannel )
+ emitChangePos = TRUE;
+
+ //qDebug("currentSample: %i audioSampleCounter: %i total_audio_samples: %i", currentSample, audioSampleCounter, total_audio_samples);
+// qDebug("current: %i counter: %i total: %i", currentSample, audioSampleCounter, (int)total_audio_samples);
+ moreAudio = audioSampleCounter <= total_audio_samples;
+
+ } else {
+
+ if ( mediaPlayerState->curDecoder() && hasAudioChannel )
+ usleep( 100000 ); // Check every 1/10 sec to see if mute is off
+ else
+ moreAudio = FALSE;
+
+ }
+ }
+
+ qDebug( "End of file" );
+
+ if ( !moreVideo && !moreAudio )
+ emitPlayFinished = TRUE;
+
+ pthread_exit(NULL);
+}
+
+void LoopControl::killTimers() {
+ if ( hasVideoChannel ) {
+ if ( pthread_self() != video_tid ) {
+ if ( pthread_cancel(video_tid) == 0 ) {
+ void *thread_result = 0;
+ if ( pthread_join(video_tid,&thread_result) != 0 )
+ qDebug("thread join error 1");
+ pthread_attr_destroy(&video_attr);
+ }
+ }
+ }
+ if ( hasAudioChannel ) {
+ if ( pthread_self() != audio_tid ) {
+ if ( pthread_cancel(audio_tid) == 0 ) {
+ void *thread_result = 0;
+ if ( pthread_join(audio_tid,&thread_result) != 0 )
+ qDebug("thread join error 2");
+ pthread_attr_destroy(&audio_attr);
+ }
+ }
+ }
+}
+
+void LoopControl::startTimers() {
+ moreVideo = FALSE;
+ moreAudio = FALSE;
+
+ if ( hasVideoChannel ) {
+ moreVideo = TRUE;
+ pthread_attr_init(&video_attr);
+ pthread_create(&video_tid, &video_attr, (void * (*)(void *))startVideoThread, this);
+ }
+
+ if ( hasAudioChannel ) {
+ moreAudio = TRUE;
+ pthread_attr_init(&audio_attr);
+#ifdef USE_REALTIME_AUDIO_THREAD
+ pthread_attr_setschedpolicy(&audio_attr,SCHED_RR); // Real-time round robin
+ //qDebug("min: %i, max: %i", sched_get_priority_min( SCHED_RR ), sched_get_priority_max( SCHED_RR ) );
+ sched_param params;
+ params.sched_priority = 50;
+ pthread_attr_setschedparam(&audio_attr,&params);
+#endif
+ pthread_create(&audio_tid, &audio_attr, (void * (*)(void *))startAudioThread, this);
+ }
+}
+
+
+
+
+void LoopControl::setPaused( bool pause ) {
+ static int whenPaused = 0;
+
+ if ( !mediaPlayerState->curDecoder() || !mediaPlayerState->curDecoder()->isOpen() )
+ return;
+
+ if ( pause ) {
+ // Remember where we are
+ whenPaused = playtime.elapsed();
+ killTimers();
+ } else {
+ // Just like we never stopped
+ playtime.restart();
+ playtime = playtime.addMSecs( -whenPaused );
+ whenPaused = 0;
+ startTimers();
+ }
+}
+
+
+void LoopControl::stop( bool willPlayAgainShortly ) {
+
+#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
+ if ( !willPlayAgainShortly && disabledSuspendScreenSaver ) {
+ disabledSuspendScreenSaver = FALSE;
+ // Re-enable the suspend mode
+ QCopEnvelope("QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
+ }
+#endif
+
+ if ( mediaPlayerState->curDecoder() && mediaPlayerState->curDecoder()->isOpen() ) {
+
+ killTimers();
+
+ mediaPlayerState->curDecoder()->close();
+
+ if ( audioDevice ) {
+ delete audioDevice;
+ delete audioBuffer;
+ audioDevice = 0;
+ audioBuffer = 0;
+ }
+
+ }
+}
+
+
+bool LoopControl::init( const QString& filename ) {
+ stop();
+ fileName = filename;
+ stream = 0; // only play stream 0 for now
+ current_frame = total_video_frames = total_audio_samples = 0;
+
+ qDebug( "Using the %s decoder", mediaPlayerState->curDecoder()->pluginName() );
+
+ // ### Hack to use libmpeg3plugin to get the number of audio samples if we are using the libmad plugin
+ if ( mediaPlayerState->curDecoder()->pluginName() == QString("LibMadPlugin") ) {
+ if ( mediaPlayerState->libMpeg3Decoder() && mediaPlayerState->libMpeg3Decoder()->open( filename ) ) {
+ total_audio_samples = mediaPlayerState->libMpeg3Decoder()->audioSamples( 0 );
+ mediaPlayerState->libMpeg3Decoder()->close();
+ }
+ }
+
+ if ( !mediaPlayerState->curDecoder()|| !mediaPlayerState->curDecoder()->open( filename ) )
+ return FALSE;
+
+ hasAudioChannel = mediaPlayerState->curDecoder()->audioStreams() > 0;
+ hasVideoChannel = mediaPlayerState->curDecoder()->videoStreams() > 0;
+
+ if ( hasAudioChannel ) {
+ int astream = 0;
+
+ channels = mediaPlayerState->curDecoder()->audioChannels( astream );
+ DecodeLoopDebug(( "channels = %d\n", channels ));
+
+ if ( !total_audio_samples )
+ total_audio_samples = mediaPlayerState->curDecoder()->audioSamples( astream );
+
+ mediaPlayerState->setLength( total_audio_samples );
+
+ freq = mediaPlayerState->curDecoder()->audioFrequency( astream );
+ DecodeLoopDebug(( "frequency = %d\n", freq ));
+
+ audioSampleCounter = 0;
+
+ static const int bytes_per_sample = 2; //16 bit
+
+ audioDevice = new AudioDevice( freq, channels, bytes_per_sample );
+ audioBuffer = new char[ audioDevice->bufferSize() ];
+ channels = audioDevice->channels();
+
+ //### must check which frequency is actually used.
+ static const int size = 1;
+ short int buf[size];
+ long samplesRead = 0;
+ mediaPlayerState->curDecoder()->audioReadSamples( buf, channels, size, samplesRead, stream );
+ }
+
+ if ( hasVideoChannel ) {
+ total_video_frames = mediaPlayerState->curDecoder()->videoFrames( stream );
+
+ mediaPlayerState->setLength( total_video_frames );
+
+ framerate = mediaPlayerState->curDecoder()->videoFrameRate( stream );
+ DecodeLoopDebug(( "Frame rate %g total %ld", framerate, total_video_frames ));
+
+ if ( framerate <= 1.0 ) {
+ DecodeLoopDebug(( "Crazy frame rate, resetting to sensible" ));
+ framerate = 25;
+ }
+
+ if ( total_video_frames == 1 ) {
+ DecodeLoopDebug(( "Cannot seek to frame" ));
+ }
+
+ }
+
+ videoMutex->lock();
+ current_frame = 0;
+ prev_frame = -1;
+ videoMutex->unlock();
+
+ connect( mediaPlayerState, SIGNAL( positionChanged( long ) ), this, SLOT( setPosition( long ) ) );
+ connect( mediaPlayerState, SIGNAL( pausedToggled( bool ) ), this, SLOT( setPaused( bool ) ) );
+
+ //setBackgroundColor( black );
+ return TRUE;
+}
+
+
+void LoopControl::play() {
+
+#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
+ if ( !disabledSuspendScreenSaver ) {
+ disabledSuspendScreenSaver = TRUE;
+ // Stop the screen from blanking and power saving state
+ QCopEnvelope("QPE/System", "setScreenSaverMode(int)" )
+ << ( hasVideoChannel ? QPEApplication::Disable : QPEApplication::DisableSuspend );
+ }
+#endif
+
+ //begin = clock();
+ playtime.start();
+ startTimers();
+ //updateGeometry();
+}
+
+
+void LoopControl::setMute( bool on ) {
+ if ( isMuted != on ) {
+ isMuted = on;
+ if ( isMuted ) {
+ } else {
+ int frame = current_frame; // mediaPlayerState->curDecoder()->videoGetFrame( stream );
+ playtime.restart();
+ playtime = playtime.addMSecs( -frame * 1000 / framerate );
+ //begin = clock() - (double)frame * CLOCKS_PER_SEC / framerate;
+ mediaPlayerState->curDecoder()->audioSetSample( frame*freq/framerate, stream );
+ }
+ }
+}
+
+
diff --git a/core/multimedia/opieplayer/loopcontrol_threaded.h b/core/multimedia/opieplayer/loopcontrol_threaded.h
new file mode 100644
index 0000000..9a009d1
--- a/dev/null
+++ b/core/multimedia/opieplayer/loopcontrol_threaded.h
@@ -0,0 +1,89 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MPEGVIEW_H
+#define MPEGVIEW_H
+
+
+#include <qwidget.h>
+#include <qdatetime.h>
+
+
+class LoopControl : public QObject {
+ Q_OBJECT
+public:
+ LoopControl( QObject *parent, const char *name );
+ ~LoopControl();
+
+ bool init( const QString& filename );
+
+ bool hasVideo() const { return hasVideoChannel; }
+ bool hasAudio() const { return hasAudioChannel; }
+
+ long totalPlaytime() { return (long)(hasVideoChannel ? total_video_frames / framerate : total_audio_samples / freq); }
+
+ // These are public to run them from global functions needed to start threads
+ // Otherwise they would be private
+ void startAudio();
+ void startVideo();
+public slots:
+ void play();
+ void stop( bool willPlayAgainShortly = FALSE );
+
+ void setMute( bool );
+ void setPaused( bool );
+ void setPosition( long );
+
+signals:
+ void positionChanged( long, long );
+ void playFinished();
+
+protected:
+ void timerEvent(QTimerEvent*);
+
+private:
+ void startTimers();
+ void killTimers();
+
+
+ QTime playtime;
+ int timerid;
+ int audioSampleCounter;
+ long current_frame;
+ long total_video_frames;
+ long total_audio_samples;
+
+ float framerate;
+ int freq;
+ int stream;
+ int framecount;
+ int channels;
+
+ bool moreAudio;
+ bool moreVideo;
+
+ bool hasVideoChannel;
+ bool hasAudioChannel;
+ bool isMuted;
+ QString fileName;
+};
+
+
+#endif
+
diff --git a/core/multimedia/opieplayer/main.cpp b/core/multimedia/opieplayer/main.cpp
new file mode 100644
index 0000000..5246e40
--- a/dev/null
+++ b/core/multimedia/opieplayer/main.cpp
@@ -0,0 +1,57 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qpe/qpeapplication.h>
+#include "mediaplayerstate.h"
+#include "playlistwidget.h"
+#include "audiowidget.h"
+#include "videowidget.h"
+#include "loopcontrol.h"
+#include "mediaplayer.h"
+
+
+MediaPlayerState *mediaPlayerState;
+PlayListWidget *playList;
+AudioWidget *audioUI;
+VideoWidget *videoUI;
+LoopControl *loopControl;
+
+
+int main(int argc, char **argv) {
+ QPEApplication a(argc,argv);
+
+ MediaPlayerState st( 0, "mediaPlayerState" );
+ mediaPlayerState = &st;
+ PlayListWidget pl( 0, "playList" );
+ playList = &pl;
+ AudioWidget aw( 0, "audioUI" );
+ audioUI = &aw;
+ VideoWidget vw( 0, "videoUI" );
+ videoUI = &vw;
+ LoopControl lc( 0, "loopControl" );
+ loopControl = &lc;
+ MediaPlayer mp( 0, "mediaPlayer" );
+
+ pl.setCaption( MediaPlayer::tr("Media Player") );
+ a.showMainDocumentWidget(&pl);
+
+ return a.exec();
+}
+
+
diff --git a/core/multimedia/opieplayer/mediaplayer.cpp b/core/multimedia/opieplayer/mediaplayer.cpp
new file mode 100644
index 0000000..3d8f76c
--- a/dev/null
+++ b/core/multimedia/opieplayer/mediaplayer.cpp
@@ -0,0 +1,182 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qpe/qpeapplication.h>
+#include <qpe/qlibrary.h>
+#include <qpe/resource.h>
+#include <qpe/config.h>
+
+#include <qmainwindow.h>
+#include <qmessagebox.h>
+#include <qwidgetstack.h>
+#include <qfile.h>
+
+#include "mediaplayer.h"
+#include "playlistwidget.h"
+#include "audiowidget.h"
+#include "loopcontrol.h"
+#include "audiodevice.h"
+
+#include "mediaplayerstate.h"
+
+
+extern AudioWidget *audioUI;
+extern PlayListWidget *playList;
+extern LoopControl *loopControl;
+extern MediaPlayerState *mediaPlayerState;
+
+
+MediaPlayer::MediaPlayer( QObject *parent, const char *name )
+ : QObject( parent, name ), volumeDirection( 0 ), currentFile( NULL ) {
+
+ connect( mediaPlayerState, SIGNAL( playingToggled( bool ) ), this, SLOT( setPlaying( bool ) ) );
+ connect( mediaPlayerState, SIGNAL( pausedToggled( bool ) ), this, SLOT( pauseCheck( bool ) ) );
+ connect( mediaPlayerState, SIGNAL( next() ), this, SLOT( next() ) );
+ connect( mediaPlayerState, SIGNAL( prev() ), this, SLOT( prev() ) );
+
+ connect( audioUI, SIGNAL( moreClicked() ), this, SLOT( startIncreasingVolume() ) );
+ connect( audioUI, SIGNAL( lessClicked() ), this, SLOT( startDecreasingVolume() ) );
+ connect( audioUI, SIGNAL( moreReleased() ), this, SLOT( stopChangingVolume() ) );
+ connect( audioUI, SIGNAL( lessReleased() ), this, SLOT( stopChangingVolume() ) );
+}
+
+
+MediaPlayer::~MediaPlayer() {
+}
+
+
+void MediaPlayer::pauseCheck( bool b ) {
+ // Only pause if playing
+ if ( b && !mediaPlayerState->playing() )
+ mediaPlayerState->setPaused( FALSE );
+}
+
+
+void MediaPlayer::play() {
+ mediaPlayerState->setPlaying( FALSE );
+ mediaPlayerState->setPlaying( TRUE );
+}
+
+
+void MediaPlayer::setPlaying( bool play ) {
+
+ if ( !play ) {
+ mediaPlayerState->setPaused( FALSE );
+ loopControl->stop( FALSE );
+ return;
+ }
+
+ if ( mediaPlayerState->paused() ) {
+ mediaPlayerState->setPaused( FALSE );
+ return;
+ }
+
+ const DocLnk *playListCurrent = playList->current();
+
+ if ( playListCurrent != NULL ) {
+ loopControl->stop( TRUE );
+ currentFile = playListCurrent;
+ }
+
+ if ( currentFile == NULL ) {
+ QMessageBox::critical( 0, tr( "No file"), tr( "Error: There is no file selected" ) );
+ mediaPlayerState->setPlaying( FALSE );
+ return;
+ }
+
+ if ( !QFile::exists( currentFile->file() ) ) {
+ QMessageBox::critical( 0, tr( "File not found"), tr( "The following file was not found: <i>" ) + currentFile->file() + "</i>" );
+ mediaPlayerState->setPlaying( FALSE );
+ return;
+ }
+
+ if ( !mediaPlayerState->newDecoder( currentFile->file() ) ) {
+ QMessageBox::critical( 0, tr( "No decoder found"), tr( "Sorry, no appropriate decoders found for this file: <i>" ) + currentFile->file() + "</i>" );
+ mediaPlayerState->setPlaying( FALSE );
+ return;
+ }
+
+ if ( !loopControl->init( currentFile->file() ) ) {
+ QMessageBox::critical( 0, tr( "Error opening file"), tr( "Sorry, an error occured trying to play the file: <i>" ) + currentFile->file() + "</i>" );
+ mediaPlayerState->setPlaying( FALSE );
+ return;
+ }
+
+ long seconds = loopControl->totalPlaytime();
+ QString time; time.sprintf("%li:%02i", seconds/60, (int)seconds%60 );
+ QString tickerText = tr( " File: " ) + currentFile->name() + tr(", Length: ") + time;
+ QString fileInfo = mediaPlayerState->curDecoder()->fileInfo();
+ if ( !fileInfo.isEmpty() )
+ tickerText += ", " + fileInfo;
+ audioUI->setTickerText( tickerText + "." );
+
+ loopControl->play();
+
+ mediaPlayerState->setView( loopControl->hasVideo() ? 'v' : 'a' );
+}
+
+
+void MediaPlayer::prev() {
+ if ( playList->prev() )
+ play();
+ else if ( mediaPlayerState->looping() ) {
+ if ( playList->last() )
+ play();
+ } else
+ mediaPlayerState->setList();
+}
+
+
+void MediaPlayer::next() {
+ if ( playList->next() )
+ play();
+ else if ( mediaPlayerState->looping() ) {
+ if ( playList->first() )
+ play();
+ } else
+ mediaPlayerState->setList();
+}
+
+
+void MediaPlayer::startDecreasingVolume() {
+ volumeDirection = -1;
+ startTimer( 100 );
+ AudioDevice::decreaseVolume();
+}
+
+
+void MediaPlayer::startIncreasingVolume() {
+ volumeDirection = +1;
+ startTimer( 100 );
+ AudioDevice::increaseVolume();
+}
+
+
+void MediaPlayer::stopChangingVolume() {
+ killTimers();
+}
+
+
+void MediaPlayer::timerEvent( QTimerEvent * ) {
+ if ( volumeDirection == +1 )
+ AudioDevice::increaseVolume();
+ else if ( volumeDirection == -1 )
+ AudioDevice::decreaseVolume();
+}
+
diff --git a/core/multimedia/opieplayer/mediaplayer.h b/core/multimedia/opieplayer/mediaplayer.h
new file mode 100644
index 0000000..379d95c
--- a/dev/null
+++ b/core/multimedia/opieplayer/mediaplayer.h
@@ -0,0 +1,59 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MEDIA_PLAYER_H
+#define MEDIA_PLAYER_H
+
+
+#include <qmainwindow.h>
+#include <qframe.h>
+#include <qpe/qlibrary.h>
+#include "mediaplayerplugininterface.h"
+
+
+class DocLnk;
+
+
+class MediaPlayer : public QObject {
+ Q_OBJECT
+public:
+ MediaPlayer( QObject *parent, const char *name );
+ ~MediaPlayer();
+
+private slots:
+ void setPlaying( bool );
+ void pauseCheck( bool );
+ void play();
+ void next();
+ void prev();
+ void startIncreasingVolume();
+ void startDecreasingVolume();
+ void stopChangingVolume();
+
+protected:
+ void timerEvent( QTimerEvent *e );
+
+private:
+ int volumeDirection;
+ const DocLnk *currentFile;
+};
+
+
+#endif // MEDIA_PLAYER_H
+
diff --git a/core/multimedia/opieplayer/mediaplayerplugininterface.h b/core/multimedia/opieplayer/mediaplayerplugininterface.h
new file mode 100644
index 0000000..24d5a80
--- a/dev/null
+++ b/core/multimedia/opieplayer/mediaplayerplugininterface.h
@@ -0,0 +1,113 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MEDIA_PLAYER_PLUGIN_INTERFACE_H
+#define MEDIA_PLAYER_PLUGIN_INTERFACE_H
+
+#include <qpe/qcom.h>
+
+#ifndef QT_NO_COMPONENT
+// {c0093632-b44c-4cf7-a279-d82fe8a8890c}
+# ifndef IID_MediaPlayerPlugin
+# define IID_MediaPlayerPlugin QUuid( 0xc0093632, 0xb44c, 0x4cf7, 0xa2, 0x79, 0xd8, 0x2f, 0xe8, 0xa8, 0x89, 0x0c )
+# endif
+#endif
+
+
+enum ColorFormat {
+ RGB565,
+ BGR565,
+ RGBA8888,
+ BGRA8888
+};
+
+
+class MediaPlayerDecoder {
+
+public:
+ virtual ~MediaPlayerDecoder() { };
+
+ // About Plugin
+ virtual const char *pluginName() = 0;
+ virtual const char *pluginComment() = 0;
+ virtual double pluginVersion() = 0;
+
+ virtual bool isFileSupported( const QString& file ) = 0;
+ virtual bool open( const QString& file ) = 0;
+ virtual bool close() = 0;
+ virtual bool isOpen() = 0;
+ virtual const QString &fileInfo() = 0;
+
+ // If decoder doesn't support audio then return 0 here
+ virtual int audioStreams() = 0;
+ virtual int audioChannels( int stream ) = 0;
+ virtual int audioFrequency( int stream ) = 0;
+ virtual int audioSamples( int stream ) = 0;
+ virtual bool audioSetSample( long sample, int stream ) = 0;
+ virtual long audioGetSample( int stream ) = 0;
+// virtual bool audioReadMonoSamples( short *samples, long samples, long& samplesRead, int stream ) = 0;
+// virtual bool audioReadStereoSamples( short *samples, long samples, long& samplesRead, int stream ) = 0;
+ virtual bool audioReadSamples( short *samples, int channels, long samples, long& samplesRead, int stream ) = 0;
+ // Libmpeg3 functions, perhaps good for reading an audio file with 5 channels or something!
+// virtual bool audioReadSamples( short *samples, int channel, long samples, int stream ) = 0;
+// virtual bool audioReReadSamples( short *samples, int channel, long samples, int stream ) = 0;
+
+ // If decoder doesn't support video then return 0 here
+ virtual int videoStreams() = 0;
+ virtual int videoWidth( int stream ) = 0;
+ virtual int videoHeight( int stream ) = 0;
+ virtual double videoFrameRate( int stream ) = 0; // frames per second (this may change to frames/1000secs)
+ virtual int videoFrames( int stream ) = 0;
+ virtual bool videoSetFrame( long sample, int stream ) = 0;
+ virtual long videoGetFrame( int stream ) = 0;
+ virtual bool videoReadFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, ColorFormat color_model, int stream ) = 0;
+ virtual bool videoReadScaledFrame( unsigned char **output_rows, int in_x, int in_y, int in_w, int in_h, int out_w, int out_h, ColorFormat color_model, int stream ) = 0;
+ virtual bool videoReadYUVFrame( char *y_output, char *u_output, char *v_output, int in_x, int in_y, int in_w, int in_h, int stream ) = 0;
+
+ // Profiling
+ virtual double getTime() = 0;
+
+ // Ignore if these aren't supported
+ virtual bool setSMP( int cpus ) = 0;
+ virtual bool setMMX( bool useMMX ) = 0;
+
+ // Capabilities
+ virtual bool supportsAudio() = 0;
+ virtual bool supportsVideo() = 0;
+ virtual bool supportsYUV() = 0;
+ virtual bool supportsMMX() = 0;
+ virtual bool supportsSMP() = 0;
+ virtual bool supportsStereo() = 0;
+ virtual bool supportsScaling() = 0;
+
+};
+
+
+class MediaPlayerEncoder;
+
+
+struct MediaPlayerPluginInterface : public QUnknownInterface
+{
+ virtual MediaPlayerDecoder *decoder() = 0;
+ virtual MediaPlayerEncoder *encoder() = 0;
+};
+
+
+#endif
+
diff --git a/core/multimedia/opieplayer/mediaplayerstate.cpp b/core/multimedia/opieplayer/mediaplayerstate.cpp
new file mode 100644
index 0000000..9b9d133
--- a/dev/null
+++ b/core/multimedia/opieplayer/mediaplayerstate.cpp
@@ -0,0 +1,185 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qpe/qpeapplication.h>
+#include <qpe/qlibrary.h>
+#include <qpe/config.h>
+#include <qvaluelist.h>
+#include <qobject.h>
+#include <qdir.h>
+#include "mediaplayerplugininterface.h"
+#include "mediaplayerstate.h"
+
+#ifdef QT_NO_COMPONENT
+// Plugins which are compiled in when no plugin architecture available
+#include "libmad/libmadpluginimpl.h"
+#include "libmpeg3/libmpeg3pluginimpl.h"
+#include "wavplugin/wavpluginimpl.h"
+#endif
+
+
+//#define MediaPlayerDebug(x) qDebug x
+#define MediaPlayerDebug(x)
+
+
+MediaPlayerState::MediaPlayerState( QObject *parent, const char *name )
+ : QObject( parent, name ), decoder( NULL ), libmpeg3decoder( NULL ) {
+ Config cfg( "MediaPlayer" );
+ readConfig( cfg );
+ loadPlugins();
+}
+
+
+MediaPlayerState::~MediaPlayerState() {
+ Config cfg( "MediaPlayer" );
+ writeConfig( cfg );
+}
+
+
+void MediaPlayerState::readConfig( Config& cfg ) {
+ cfg.setGroup("Options");
+ isFullscreen = cfg.readBoolEntry( "FullScreen" );
+ isScaled = cfg.readBoolEntry( "Scaling" );
+ isLooping = cfg.readBoolEntry( "Looping" );
+ isShuffled = cfg.readBoolEntry( "Shuffle" );
+ usePlaylist = cfg.readBoolEntry( "UsePlayList" );
+ isPlaying = FALSE;
+ isPaused = FALSE;
+ curPosition = 0;
+ curLength = 0;
+ curView = 'l';
+}
+
+
+void MediaPlayerState::writeConfig( Config& cfg ) const {
+ cfg.setGroup("Options");
+ cfg.writeEntry("FullScreen", isFullscreen );
+ cfg.writeEntry("Scaling", isScaled );
+ cfg.writeEntry("Looping", isLooping );
+ cfg.writeEntry("Shuffle", isShuffled );
+ cfg.writeEntry("UsePlayList", usePlaylist );
+}
+
+
+struct MediaPlayerPlugin {
+#ifndef QT_NO_COMPONENT
+ QLibrary *library;
+#endif
+ MediaPlayerPluginInterface *iface;
+ MediaPlayerDecoder *decoder;
+ MediaPlayerEncoder *encoder;
+};
+
+
+static QValueList<MediaPlayerPlugin> pluginList;
+
+
+// Find the first decoder which supports this type of file
+MediaPlayerDecoder *MediaPlayerState::newDecoder( const QString& file ) {
+ MediaPlayerDecoder *tmpDecoder = NULL;
+ QValueList<MediaPlayerPlugin>::Iterator it;
+ for ( it = pluginList.begin(); it != pluginList.end(); ++it ) {
+ if ( (*it).decoder->isFileSupported( file ) ) {
+ tmpDecoder = (*it).decoder;
+ break;
+ }
+ }
+ return decoder = tmpDecoder;
+}
+
+
+MediaPlayerDecoder *MediaPlayerState::curDecoder() {
+ return decoder;
+}
+
+
+// ### hack to get true sample count
+MediaPlayerDecoder *MediaPlayerState::libMpeg3Decoder() {
+ return libmpeg3decoder;
+}
+
+
+void MediaPlayerState::loadPlugins() {
+
+#ifndef QT_NO_COMPONENT
+ QValueList<MediaPlayerPlugin>::Iterator mit;
+ for ( mit = pluginList.begin(); mit != pluginList.end(); ++mit ) {
+ (*mit).iface->release();
+ (*mit).library->unload();
+ delete (*mit).library;
+ }
+ pluginList.clear();
+
+ QString path = QPEApplication::qpeDir() + "/plugins/codecs";
+ QDir dir( path, "lib*.so" );
+ QStringList list = dir.entryList();
+ QStringList::Iterator it;
+ for ( it = list.begin(); it != list.end(); ++it ) {
+ MediaPlayerPluginInterface *iface = 0;
+ QLibrary *lib = new QLibrary( path + "/" + *it );
+
+ MediaPlayerDebug(( "querying: %s", QString( path + "/" + *it ).latin1() ));
+
+ if ( lib->queryInterface( IID_MediaPlayerPlugin, (QUnknownInterface**)&iface ) == QS_OK ) {
+
+ MediaPlayerDebug(( "loading: %s", QString( path + "/" + *it ).latin1() ));
+
+ MediaPlayerPlugin plugin;
+ plugin.library = lib;
+ plugin.iface = iface;
+ plugin.decoder = plugin.iface->decoder();
+ plugin.encoder = plugin.iface->encoder();
+ pluginList.append( plugin );
+
+ // ### hack to get true sample count
+ if ( plugin.decoder->pluginName() == QString("LibMpeg3Plugin") )
+ libmpeg3decoder = plugin.decoder;
+
+ } else {
+ delete lib;
+ }
+ }
+#else
+ pluginList.clear();
+
+ MediaPlayerPlugin plugin0;
+ plugin0.iface = new LibMpeg3PluginImpl;
+ plugin0.decoder = plugin0.iface->decoder();
+ plugin0.encoder = plugin0.iface->encoder();
+ pluginList.append( plugin0 );
+
+ MediaPlayerPlugin plugin1;
+ plugin1.iface = new LibMadPluginImpl;
+ plugin1.decoder = plugin1.iface->decoder();
+ plugin1.encoder = plugin1.iface->encoder();
+ pluginList.append( plugin1 );
+
+ MediaPlayerPlugin plugin2;
+ plugin2.iface = new WavPluginImpl;
+ plugin2.decoder = plugin2.iface->decoder();
+ plugin2.encoder = plugin2.iface->encoder();
+ pluginList.append( plugin2 );
+#endif
+
+ if ( pluginList.count() )
+ MediaPlayerDebug(( "%i decoders found", pluginList.count() ));
+ else
+ MediaPlayerDebug(( "No decoders found" ));
+}
+
diff --git a/core/multimedia/opieplayer/mediaplayerstate.h b/core/multimedia/opieplayer/mediaplayerstate.h
new file mode 100644
index 0000000..5d95b92
--- a/dev/null
+++ b/core/multimedia/opieplayer/mediaplayerstate.h
@@ -0,0 +1,117 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef MEDIA_PLAYER_STATE_H
+#define MEDIA_PLAYER_STATE_H
+
+
+#include <qobject.h>
+
+
+class MediaPlayerDecoder;
+class Config;
+
+
+class MediaPlayerState : public QObject {
+Q_OBJECT
+public:
+ MediaPlayerState( QObject *parent, const char *name );
+ ~MediaPlayerState();
+
+ bool fullscreen() { return isFullscreen; }
+ bool scaled() { return isScaled; }
+ bool looping() { return isLooping; }
+ bool shuffled() { return isShuffled; }
+ bool playlist() { return usePlaylist; }
+ bool paused() { return isPaused; }
+ bool playing() { return isPlaying; }
+ long position() { return curPosition; }
+ long length() { return curLength; }
+ char view() { return curView; }
+
+ MediaPlayerDecoder *newDecoder( const QString& file );
+ MediaPlayerDecoder *curDecoder();
+ MediaPlayerDecoder *libMpeg3Decoder(); // ### Yucky hack needed to use libmpeg3plugin to get the
+ // number of audio samples if we are using the libmad plugin
+public slots:
+ void setFullscreen( bool b ) { if ( isFullscreen == b ) return; isFullscreen = b; emit fullscreenToggled(b); }
+ void setScaled( bool b ) { if ( isScaled == b ) return; isScaled = b; emit scaledToggled(b); }
+ void setLooping( bool b ) { if ( isLooping == b ) return; isLooping = b; emit loopingToggled(b); }
+ void setShuffled( bool b ) { if ( isShuffled == b ) return; isShuffled = b; emit shuffledToggled(b); }
+ void setPlaylist( bool b ) { if ( usePlaylist == b ) return; usePlaylist = b; emit playlistToggled(b); }
+ void setPaused( bool b ) { if ( isPaused == b ) return; isPaused = b; emit pausedToggled(b); }
+ void setPlaying( bool b ) { if ( isPlaying == b ) return; isPlaying = b; emit playingToggled(b); }
+ void setPosition( long p ) { if ( curPosition == p ) return; curPosition = p; emit positionChanged(p); }
+ void updatePosition( long p ){ if ( curPosition == p ) return; curPosition = p; emit positionUpdated(p); }
+ void setLength( long l ) { if ( curLength == l ) return; curLength = l; emit lengthChanged(l); }
+ void setView( char v ) { if ( curView == v ) return; curView = v; emit viewChanged(v); }
+
+ void setPrev() { emit prev(); }
+ void setNext() { emit next(); }
+ void setList() { setPlaying( FALSE ); setView('l'); }
+ void setVideo() { setView('v'); }
+ void setAudio() { setView('a'); }
+
+ void toggleFullscreen() { setFullscreen( !isFullscreen ); }
+ void toggleScaled() { setScaled( !isScaled); }
+ void toggleLooping() { setLooping( !isLooping); }
+ void toggleShuffled() { setShuffled( !isShuffled); }
+ void togglePlaylist() { setPlaylist( !usePlaylist); }
+ void togglePaused() { setPaused( !isPaused); }
+ void togglePlaying() { setPlaying( !isPlaying); }
+
+signals:
+ void fullscreenToggled( bool );
+ void scaledToggled( bool );
+ void loopingToggled( bool );
+ void shuffledToggled( bool );
+ void playlistToggled( bool );
+ void pausedToggled( bool );
+ void playingToggled( bool );
+ void positionChanged( long ); // When the slider is moved
+ void positionUpdated( long ); // When the media file progresses
+ void lengthChanged( long );
+ void viewChanged( char );
+
+ void prev();
+ void next();
+
+private:
+ bool isFullscreen;
+ bool isScaled;
+ bool isLooping;
+ bool isShuffled;
+ bool usePlaylist;
+ bool isPaused;
+ bool isPlaying;
+ long curPosition;
+ long curLength;
+ char curView;
+
+ MediaPlayerDecoder *decoder;
+ MediaPlayerDecoder *libmpeg3decoder;
+
+ void loadPlugins();
+ void readConfig( Config& cfg );
+ void writeConfig( Config& cfg ) const;
+};
+
+
+#endif // MEDIA_PLAYER_STATE_H
+
diff --git a/core/multimedia/opieplayer/mpegplayer.pro b/core/multimedia/opieplayer/mpegplayer.pro
new file mode 100644
index 0000000..d6952f8
--- a/dev/null
+++ b/core/multimedia/opieplayer/mpegplayer.pro
@@ -0,0 +1,21 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = loopcontrol.h mediaplayerplugininterface.h playlistselection.h mediaplayerstate.h \
+ videowidget.h audiowidget.h playlistwidget.h mediaplayer.h audiodevice.h
+SOURCES = main.cpp \
+ loopcontrol.cpp playlistselection.cpp mediaplayerstate.cpp \
+ videowidget.cpp audiowidget.cpp playlistwidget.cpp mediaplayer.cpp audiodevice.cpp
+TARGET = mpegplayer
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe -lpthread
+
+# INTERFACES =
+# INCLUDEPATH += $(QPEDIR)/include
+# CONFIG+=static
+# TMAKE_CXXFLAGS += -DQPIM_STANDALONE
+# LIBS += libmpeg3/libmpeg3.a -lpthread
+# LIBS += $(QPEDIR)/plugins/codecs/liblibmadplugin.so
+
+TRANSLATIONS = ../i18n/de/mpegplayer.ts
diff --git a/core/multimedia/opieplayer/playlistselection.cpp b/core/multimedia/opieplayer/playlistselection.cpp
new file mode 100644
index 0000000..fbfb946
--- a/dev/null
+++ b/core/multimedia/opieplayer/playlistselection.cpp
@@ -0,0 +1,179 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qpe/applnk.h>
+#include <qpe/resource.h>
+#include <qpainter.h>
+#include <qimage.h>
+#include <qheader.h>
+#include <qlistview.h>
+#include <qlist.h>
+#include <qpixmap.h>
+
+#include "playlistselection.h"
+
+#include <stdlib.h>
+
+
+class PlayListSelectionItem : public QListViewItem {
+public:
+ PlayListSelectionItem( QListView *parent, const DocLnk *f ) : QListViewItem( parent ), fl( f ) {
+ setText( 0, f->name() );
+ setPixmap( 0, f->pixmap() );
+ }
+
+ ~PlayListSelectionItem() {
+ };
+
+ const DocLnk *file() const { return fl; }
+
+private:
+ const DocLnk *fl;
+};
+
+
+PlayListSelection::PlayListSelection( QWidget *parent, const char *name )
+ : QListView( parent, name )
+{
+#ifdef USE_PLAYLIST_BACKGROUND
+ setStaticBackground( TRUE );
+ setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/background" ) );
+#endif
+ setAllColumnsShowFocus( TRUE );
+ addColumn( tr( "Playlist Selection" ) );
+ header()->hide();
+ setSorting( -1, FALSE );
+}
+
+
+PlayListSelection::~PlayListSelection() {
+}
+
+
+#ifdef USE_PLAYLIST_BACKGROUND
+void PlayListSelection::drawBackground( QPainter *p, const QRect &r ) {
+ p->fillRect( r, QBrush( white ) );
+ QImage logo = Resource::loadImage( "mpegplayer/background" );
+ if ( !logo.isNull() )
+ p->drawImage( (width() - logo.width()) / 2, (height() - logo.height()) / 2, logo );
+}
+#endif
+
+
+void PlayListSelection::contentsMouseMoveEvent( QMouseEvent *event ) {
+ if ( event->state() == QMouseEvent::LeftButton ) {
+ QListViewItem *currentItem = selectedItem();
+ QListViewItem *itemUnder = itemAt( QPoint( event->pos().x(), event->pos().y() - contentsY() ) );
+ if ( currentItem && currentItem->itemAbove() == itemUnder )
+ moveSelectedUp();
+ else if ( currentItem && currentItem->itemBelow() == itemUnder )
+ moveSelectedDown();
+ }
+}
+
+
+const DocLnk *PlayListSelection::current() {
+ PlayListSelectionItem *item = (PlayListSelectionItem *)selectedItem();
+ if ( item )
+ return item->file();
+ return NULL;
+}
+
+
+void PlayListSelection::addToSelection( const DocLnk &lnk ) {
+ PlayListSelectionItem *item = new PlayListSelectionItem( this, new DocLnk( lnk ) );
+ QListViewItem *current = selectedItem();
+ if ( current )
+ item->moveItem( current );
+ setSelected( item, TRUE );
+ ensureItemVisible( selectedItem() );
+}
+
+
+void PlayListSelection::removeSelected() {
+ QListViewItem *item = selectedItem();
+ if ( item )
+ delete item;
+ setSelected( currentItem(), TRUE );
+ ensureItemVisible( selectedItem() );
+}
+
+
+void PlayListSelection::moveSelectedUp() {
+ QListViewItem *item = selectedItem();
+ if ( item && item->itemAbove() )
+ item->itemAbove()->moveItem( item );
+ ensureItemVisible( selectedItem() );
+}
+
+
+void PlayListSelection::moveSelectedDown() {
+ QListViewItem *item = selectedItem();
+ if ( item && item->itemBelow() )
+ item->moveItem( item->itemBelow() );
+ ensureItemVisible( selectedItem() );
+}
+
+
+bool PlayListSelection::prev() {
+ QListViewItem *item = selectedItem();
+ if ( item && item->itemAbove() )
+ setSelected( item->itemAbove(), TRUE );
+ else
+ return FALSE;
+ ensureItemVisible( selectedItem() );
+ return TRUE;
+}
+
+
+bool PlayListSelection::next() {
+ QListViewItem *item = selectedItem();
+ if ( item && item->itemBelow() )
+ setSelected( item->itemBelow(), TRUE );
+ else
+ return FALSE;
+ ensureItemVisible( selectedItem() );
+ return TRUE;
+}
+
+
+bool PlayListSelection::first() {
+ QListViewItem *item = firstChild();
+ if ( item )
+ setSelected( item, TRUE );
+ else
+ return FALSE;
+ ensureItemVisible( selectedItem() );
+ return TRUE;
+}
+
+
+bool PlayListSelection::last() {
+ QListViewItem *prevItem = NULL;
+ QListViewItem *item = firstChild();
+ while ( ( item = item->nextSibling() ) )
+ prevItem = item;
+ if ( prevItem )
+ setSelected( prevItem, TRUE );
+ else
+ return FALSE;
+ ensureItemVisible( selectedItem() );
+ return TRUE;
+}
+
diff --git a/core/multimedia/opieplayer/playlistselection.h b/core/multimedia/opieplayer/playlistselection.h
new file mode 100644
index 0000000..6ce6bdc
--- a/dev/null
+++ b/core/multimedia/opieplayer/playlistselection.h
@@ -0,0 +1,62 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef PLAY_LIST_SELECTION_H
+#define PLAY_LIST_SELECTION_H
+
+
+#include <qlist.h>
+#include <qlistview.h>
+#include <qpe/applnk.h>
+
+
+class PlayListSelection : public QListView {
+ Q_OBJECT
+public:
+ PlayListSelection( QWidget *parent, const char *name=0 );
+ ~PlayListSelection();
+
+ const DocLnk *current(); // retrieve the current playlist entry (media file link)
+
+public slots:
+ void addToSelection( const DocLnk & ); // Add a media file to the playlist
+ void removeSelected(); // Remove a media file from the playlist
+ void moveSelectedUp(); // Move the media file up the playlist so it is played earlier
+ void moveSelectedDown(); // Move the media file down the playlist so it is played later
+ bool prev();
+ bool next();
+ bool first();
+ bool last();
+
+protected:
+ virtual void contentsMouseMoveEvent(QMouseEvent *);
+#ifdef USE_PLAYLIST_BACKGROUND
+ virtual void drawBackground( QPainter *p, const QRect &r );
+ virtual void paintEmptyArea( QPainter *p, const QRect &r ) { drawBackground( p, r ); };
+#endif
+
+private:
+ QList<DocLnk> selectedList;
+ const DocLnk *lnk;
+};
+
+
+#endif // PLAY_LIST_SELECTION_H
+
+
diff --git a/core/multimedia/opieplayer/playlistwidget.cpp b/core/multimedia/opieplayer/playlistwidget.cpp
new file mode 100644
index 0000000..969fc4b
--- a/dev/null
+++ b/core/multimedia/opieplayer/playlistwidget.cpp
@@ -0,0 +1,448 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qpe/qpemenubar.h>
+#include <qpe/qpetoolbar.h>
+#include <qpe/fileselector.h>
+#include <qpe/applnk.h>
+#include <qpe/config.h>
+#include <qpe/global.h>
+#include <qpe/resource.h>
+#include <qaction.h>
+#include <qimage.h>
+#include <qfile.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qlist.h>
+#include <qlistbox.h>
+#include <qmainwindow.h>
+#include <qmessagebox.h>
+#include <qtoolbutton.h>
+
+#include "playlistselection.h"
+#include "playlistwidget.h"
+#include "mediaplayerstate.h"
+
+#include <stdlib.h>
+
+
+extern MediaPlayerState *mediaPlayerState;
+
+
+class PlayListWidgetPrivate {
+public:
+ QToolButton *tbPlay;
+ QToolButton *tbFull;
+ QToolButton *tbLoop;
+ QToolButton *tbScale;
+ QToolButton *tbShuffle;
+
+ QFrame *playListFrame;
+ FileSelector *files;
+ PlayListSelection *selectedFiles;
+ bool setDocumentUsed;
+ DocLnk *current;
+};
+
+
+class ToolButton : public QToolButton {
+public:
+ ToolButton( QWidget *parent, const char *name, const QString& icon, QObject *handler, const QString& slot, bool t = FALSE )
+ : QToolButton( parent, name ) {
+ setTextLabel( name );
+ setPixmap( Resource::loadPixmap( icon ) );
+ setAutoRaise( TRUE );
+ setFocusPolicy( QWidget::NoFocus );
+ setToggleButton( t );
+ connect( this, t ? SIGNAL( toggled(bool) ) : SIGNAL( clicked() ), handler, slot );
+ QPEMenuToolFocusManager::manager()->addWidget( this );
+ }
+};
+
+
+class MenuItem : public QAction {
+public:
+ MenuItem( QWidget *parent, const QString& text, QObject *handler, const QString& slot )
+ : QAction( text, QString::null, 0, 0 ) {
+ connect( this, SIGNAL( activated() ), handler, slot );
+ addTo( parent );
+ }
+};
+
+
+PlayListWidget::PlayListWidget( QWidget* parent, const char* name, WFlags fl )
+ : QMainWindow( parent, name, fl ) {
+
+ d = new PlayListWidgetPrivate;
+ d->setDocumentUsed = FALSE;
+ d->current = NULL;
+
+ setBackgroundMode( PaletteButton );
+
+ setCaption( tr("MediaPlayer") );
+ setIcon( Resource::loadPixmap( "MPEGPlayer" ) );
+
+ setToolBarsMovable( FALSE );
+
+ // Create Toolbar
+ QPEToolBar *toolbar = new QPEToolBar( this );
+ toolbar->setHorizontalStretchable( TRUE );
+
+ // Create Menubar
+ QPEMenuBar *menu = new QPEMenuBar( toolbar );
+ menu->setMargin( 0 );
+
+ QPEToolBar *bar = new QPEToolBar( this );
+ bar->setLabel( tr( "Play Operations" ) );
+#ifdef BUTTONS_ON_TOOLBAR
+ d->tbPlay = new ToolButton( bar, tr( "Play" ), "mpegplayer/play", mediaPlayerState, SLOT(setPlaying(bool)), TRUE );
+ d->tbShuffle = new ToolButton( bar, tr( "Randomize" ), "mpegplayer/shuffle", mediaPlayerState, SLOT(setShuffled(bool)), TRUE );
+#endif
+ d->tbLoop = new ToolButton( bar, tr( "Loop" ), "mpegplayer/loop", mediaPlayerState, SLOT(setLooping(bool)), TRUE );
+ d->tbFull = new ToolButton( bar, tr( "Fullscreen" ), "fullscreen", mediaPlayerState, SLOT(setFullscreen(bool)), TRUE );
+ d->tbScale = new ToolButton( bar, tr( "Scale" ), "mpegplayer/scale", mediaPlayerState, SLOT(setScaled(bool)), TRUE );
+
+ QPopupMenu *pmPlayList = new QPopupMenu( this );
+ menu->insertItem( tr( "PlayList" ), pmPlayList );
+ new MenuItem( pmPlayList, tr( "Toggle PlayList" ), mediaPlayerState, SLOT( togglePlaylist() ) );
+ new MenuItem( pmPlayList, tr( "Clear List" ), this, SLOT( clearList() ) );
+ new MenuItem( pmPlayList, tr( "Add all music files" ), this, SLOT( addAllMusicToList() ) );
+ new MenuItem( pmPlayList, tr( "Add all video files" ), this, SLOT( addAllVideoToList() ) );
+ new MenuItem( pmPlayList, tr( "Add all files" ), this, SLOT( addAllToList() ) );
+#ifdef CAN_SAVE_LOAD_PLAYLISTS
+ new MenuItem( pmPlayList, tr( "Save PlayList" ), this, SLOT( saveList() ) );
+ new MenuItem( pmPlayList, tr( "Load PlayList" ), this, SLOT( loadList() ) );
+#endif
+
+ QVBox *vbox5 = new QVBox( this ); vbox5->setBackgroundMode( PaletteButton );
+
+ // Add the playlist area
+ QVBox *vbox3 = new QVBox( vbox5 ); vbox3->setBackgroundMode( PaletteButton );
+ d->playListFrame = vbox3;
+
+ QLabel *plString = new QLabel( tr(" PlayList"), vbox3 );
+ plString->setBackgroundMode( QButton::PaletteButton );
+ plString->setFont( QFont( "Helvetica", 8, QFont::Bold ) );
+
+ QHBox *hbox2 = new QHBox( vbox3 ); hbox2->setBackgroundMode( PaletteButton );
+ d->selectedFiles = new PlayListSelection( hbox2 );
+ QVBox *vbox1 = new QVBox( hbox2 ); vbox1->setBackgroundMode( PaletteButton );
+
+#ifndef BUTTONS_ON_TOOLBAR
+ d->tbPlay = new ToolButton( vbox1, tr( "Play" ), "mpegplayer/play", mediaPlayerState, SLOT(setPlaying(bool)), TRUE );
+ QVBox *stretch1 = new QVBox( vbox1 ); stretch1->setBackgroundMode( PaletteButton ); // add stretch
+#endif
+ new ToolButton( vbox1, tr( "Move Up" ), "mpegplayer/up", d->selectedFiles, SLOT(moveSelectedUp()) );
+ new ToolButton( vbox1, tr( "Remove" ), "mpegplayer/cut", d->selectedFiles, SLOT(removeSelected()) );
+ new ToolButton( vbox1, tr( "Move Down" ), "mpegplayer/down", d->selectedFiles, SLOT(moveSelectedDown()) );
+ QVBox *stretch2 = new QVBox( vbox1 ); stretch2->setBackgroundMode( PaletteButton ); // add stretch
+#ifndef BUTTONS_ON_TOOLBAR
+ d->tbShuffle = new ToolButton( vbox1, tr( "Randomize" ), "mpegplayer/shuffle", mediaPlayerState, SLOT(setShuffled(bool)), TRUE );
+#endif
+
+ // add the library area
+ QVBox *vbox4 = new QVBox( vbox5 ); vbox4->setBackgroundMode( PaletteButton );
+
+ QLabel *libString = new QLabel( tr(" Media Library"), vbox4 );
+ libString->setBackgroundMode( QButton::PaletteButton );
+ libString->setFont( QFont( "Helvetica", 8, QFont::Bold ) );
+
+ QHBox *hbox6 = new QHBox( vbox4 ); hbox6->setBackgroundMode( PaletteButton );
+ d->files = new FileSelector( "video/*;audio/*", hbox6, "Find Media Files", FALSE, FALSE );
+ d->files->setBackgroundMode( PaletteButton );
+ QVBox *vbox7 = new QVBox( hbox6 ); vbox7->setBackgroundMode( PaletteButton );
+
+#ifdef SIDE_BUTTONS
+ new ToolButton( vbox7, tr( "Add to Playlist" ), "mpegplayer/add_to_playlist", d->selectedFiles, SLOT(addSelected()) );
+ new ToolButton( vbox7, tr( "Remove from Playlist" ), "mpegplayer/remove_from_playlist", d->selectedFiles, SLOT(removeSelected()) );
+ QVBox *stretch3 = new QVBox( vbox1 ); stretch3->setBackgroundMode( PaletteButton ); // add stretch
+#endif
+
+ connect( d->files, SIGNAL( fileSelected( const DocLnk & ) ), this, SLOT( addToSelection( const DocLnk & ) ) );
+ connect( mediaPlayerState, SIGNAL( playingToggled( bool ) ), d->tbPlay, SLOT( setOn( bool ) ) );
+ connect( mediaPlayerState, SIGNAL( loopingToggled( bool ) ), d->tbLoop, SLOT( setOn( bool ) ) );
+ connect( mediaPlayerState, SIGNAL( shuffledToggled( bool ) ), d->tbShuffle, SLOT( setOn( bool ) ) );
+ connect( mediaPlayerState, SIGNAL( fullscreenToggled( bool ) ), d->tbFull, SLOT( setOn( bool ) ) );
+ connect( mediaPlayerState, SIGNAL( scaledToggled( bool ) ), d->tbScale, SLOT( setOn( bool ) ) );
+ connect( mediaPlayerState, SIGNAL( fullscreenToggled( bool ) ), d->tbScale, SLOT( setEnabled( bool ) ) );
+ connect( mediaPlayerState, SIGNAL( playlistToggled( bool ) ), this, SLOT( setPlaylist( bool ) ) );
+
+ setCentralWidget( vbox5 );
+
+ Config cfg( "MediaPlayer" );
+ readConfig( cfg );
+
+ initializeStates();
+}
+
+
+PlayListWidget::~PlayListWidget() {
+ Config cfg( "MediaPlayer" );
+ writeConfig( cfg );
+
+ if ( d->current )
+ delete d->current;
+ delete d;
+}
+
+
+void PlayListWidget::initializeStates() {
+ d->tbPlay->setOn( mediaPlayerState->playing() );
+ d->tbLoop->setOn( mediaPlayerState->looping() );
+ d->tbShuffle->setOn( mediaPlayerState->shuffled() );
+ d->tbFull->setOn( mediaPlayerState->fullscreen() );
+ d->tbScale->setOn( mediaPlayerState->scaled() );
+ d->tbScale->setEnabled( mediaPlayerState->fullscreen() );
+ setPlaylist( mediaPlayerState->playlist() );
+}
+
+
+void PlayListWidget::readConfig( Config& cfg ) {
+ cfg.setGroup("PlayList");
+
+ int noOfFiles = cfg.readNumEntry("NumberOfFiles", 0 );
+
+ for ( int i = 0; i < noOfFiles; i++ ) {
+ QString entryName;
+ entryName.sprintf( "File%i", i + 1 );
+ QString linkFile = cfg.readEntry( entryName );
+ DocLnk lnk( linkFile );
+ if ( lnk.isValid() )
+ d->selectedFiles->addToSelection( lnk );
+
+ }
+}
+
+
+void PlayListWidget::writeConfig( Config& cfg ) const {
+ cfg.setGroup("PlayList");
+
+ int noOfFiles = 0;
+
+ d->selectedFiles->first();
+ do {
+ const DocLnk *lnk = d->selectedFiles->current();
+ if ( lnk ) {
+ QString entryName;
+ entryName.sprintf( "File%i", noOfFiles + 1 );
+ cfg.writeEntry( entryName, lnk->linkFile() );
+ // if this link does exist, add it so we have the file
+ // next time...
+ if ( !QFile::exists( lnk->linkFile() ) ) {
+ // the way writing lnks doesn't really check for out
+ // of disk space, but check it anyway.
+ if ( !lnk->writeLink() ) {
+ QMessageBox::critical( 0, tr("Out of space"),
+ tr( "There was a problem saving "
+ "the playlist.\n"
+ "Your playlist "
+ "may be missing some entries\n"
+ "the next time you start it." )
+ );
+ }
+ }
+ noOfFiles++;
+ }
+ } while ( d->selectedFiles->next() );
+
+ cfg.writeEntry("NumberOfFiles", noOfFiles );
+}
+
+
+void PlayListWidget::addToSelection( const DocLnk& lnk ) {
+ d->setDocumentUsed = FALSE;
+ if ( mediaPlayerState->playlist() )
+ d->selectedFiles->addToSelection( lnk );
+ else
+ mediaPlayerState->setPlaying( TRUE );
+}
+
+
+void PlayListWidget::clearList() {
+ while ( first() )
+ d->selectedFiles->removeSelected();
+}
+
+
+void PlayListWidget::addAllToList() {
+ DocLnkSet files;
+ Global::findDocuments(&files, "video/*;audio/*");
+ QListIterator<DocLnk> dit( files.children() );
+ for ( ; dit.current(); ++dit )
+ d->selectedFiles->addToSelection( **dit );
+}
+
+
+void PlayListWidget::addAllMusicToList() {
+ DocLnkSet files;
+ Global::findDocuments(&files, "audio/*");
+ QListIterator<DocLnk> dit( files.children() );
+ for ( ; dit.current(); ++dit )
+ d->selectedFiles->addToSelection( **dit );
+}
+
+
+void PlayListWidget::addAllVideoToList() {
+ DocLnkSet files;
+ Global::findDocuments(&files, "video/*");
+ QListIterator<DocLnk> dit( files.children() );
+ for ( ; dit.current(); ++dit )
+ d->selectedFiles->addToSelection( **dit );
+}
+
+
+void PlayListWidget::setDocument(const QString& fileref) {
+ if ( fileref.isNull() ) {
+ QMessageBox::critical( 0, tr( "Invalid File" ), tr( "There was a problem in getting the file." ) );
+ return;
+ }
+ if ( mediaPlayerState->playlist() )
+ addToSelection( DocLnk( fileref ) );
+ else {
+ d->setDocumentUsed = TRUE;
+ if ( d->current )
+ delete d->current;
+ d->current = new DocLnk( fileref );
+ }
+ mediaPlayerState->setPlaying( FALSE );
+ mediaPlayerState->setPlaying( TRUE );
+}
+
+
+void PlayListWidget::setActiveWindow() {
+ // When we get raised we need to ensure that it switches views
+ char origView = mediaPlayerState->view();
+ mediaPlayerState->setView( 'l' ); // invalidate
+ mediaPlayerState->setView( origView ); // now switch back
+}
+
+
+void PlayListWidget::useSelectedDocument() {
+ d->setDocumentUsed = FALSE;
+}
+
+
+const DocLnk *PlayListWidget::current() {
+ if ( mediaPlayerState->playlist() )
+ return d->selectedFiles->current();
+ else if ( d->setDocumentUsed && d->current ) {
+ return d->current;
+ } else
+ return d->files->selected();
+}
+
+
+bool PlayListWidget::prev() {
+ if ( mediaPlayerState->playlist() ) {
+ if ( mediaPlayerState->shuffled() ) {
+ const DocLnk *cur = current();
+ int j = 1 + (int)(97.0 * rand() / (RAND_MAX + 1.0));
+ for ( int i = 0; i < j; i++ ) {
+ if ( !d->selectedFiles->next() )
+ d->selectedFiles->first();
+ }
+ if ( cur == current() )
+ if ( !d->selectedFiles->next() )
+ d->selectedFiles->first();
+ return TRUE;
+ } else {
+ if ( !d->selectedFiles->prev() ) {
+ if ( mediaPlayerState->looping() ) {
+ return d->selectedFiles->last();
+ } else {
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+ } else {
+ return mediaPlayerState->looping();
+ }
+}
+
+
+bool PlayListWidget::next() {
+ if ( mediaPlayerState->playlist() ) {
+ if ( mediaPlayerState->shuffled() ) {
+ return prev();
+ } else {
+ if ( !d->selectedFiles->next() ) {
+ if ( mediaPlayerState->looping() ) {
+ return d->selectedFiles->first();
+ } else {
+ return FALSE;
+ }
+ }
+ return TRUE;
+ }
+ } else {
+ return mediaPlayerState->looping();
+ }
+}
+
+
+bool PlayListWidget::first() {
+ if ( mediaPlayerState->playlist() )
+ return d->selectedFiles->first();
+ else
+ return mediaPlayerState->looping();
+}
+
+
+bool PlayListWidget::last() {
+ if ( mediaPlayerState->playlist() )
+ return d->selectedFiles->last();
+ else
+ return mediaPlayerState->looping();
+}
+
+
+void PlayListWidget::saveList() {
+ QString filename;
+// pseudo code
+// filename = QLineEdit->getText();
+ Config cfg( filename + ".playlist" );
+ writeConfig( cfg );
+}
+
+
+void PlayListWidget::loadList() {
+ QString filename;
+// pseudo code
+// filename = FileSelector->openFile( "*.playlist" );
+ Config cfg( filename + ".playlist" );
+ readConfig( cfg );
+}
+
+
+void PlayListWidget::setPlaylist( bool shown ) {
+ if ( shown )
+ d->playListFrame->show();
+ else
+ d->playListFrame->hide();
+}
+
+
+void PlayListWidget::setView( char view ) {
+ if ( view == 'l' )
+ showMaximized();
+ else
+ hide();
+}
+
diff --git a/core/multimedia/opieplayer/playlistwidget.h b/core/multimedia/opieplayer/playlistwidget.h
new file mode 100644
index 0000000..6976641
--- a/dev/null
+++ b/core/multimedia/opieplayer/playlistwidget.h
@@ -0,0 +1,68 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef PLAY_LIST_WIDGET_H
+#define PLAY_LIST_WIDGET_H
+
+
+#include <qmainwindow.h>
+#include <qpe/applnk.h>
+
+
+class PlayListWidgetPrivate;
+class Config;
+
+
+class PlayListWidget : public QMainWindow {
+ Q_OBJECT
+public:
+ PlayListWidget( QWidget* parent=0, const char* name=0, WFlags fl=0 );
+ ~PlayListWidget();
+
+ // retrieve the current playlist entry (media file link)
+ const DocLnk *current();
+ void useSelectedDocument();
+
+public slots:
+ void setDocument( const QString& fileref );
+ void addToSelection( const DocLnk& ); // Add a media file to the playlist
+ void setActiveWindow(); // need to handle this to show the right view
+ void setPlaylist( bool ); // Show/Hide the playlist
+ void setView( char );
+ void clearList();
+ void addAllToList();
+ void addAllMusicToList();
+ void addAllVideoToList();
+ void saveList(); // Save the playlist
+ void loadList(); // Load a playlist
+ bool first();
+ bool last();
+ bool next();
+ bool prev();
+
+private:
+ void initializeStates();
+ void readConfig( Config& cfg );
+ void writeConfig( Config& cfg ) const;
+ PlayListWidgetPrivate *d; // Private implementation data
+};
+
+
+#endif // PLAY_LIST_WIDGET_H
+
diff --git a/core/multimedia/opieplayer/qpe-mpegplayer.control b/core/multimedia/opieplayer/qpe-mpegplayer.control
new file mode 100644
index 0000000..2cad8ab
--- a/dev/null
+++ b/core/multimedia/opieplayer/qpe-mpegplayer.control
@@ -0,0 +1,9 @@
+Files: bin/mpegplayer pics/mpegplayer/* apps/Applications/mpegplayer.desktop plugins/codecs/libmpeg3plugin.so plugins/codecs/libmpeg3plugin.so.1 plugins/codecs/libmpeg3plugin.so.1.0 plugins/codecs/libmpeg3plugin.so.1.0.0
+Priority: optional
+Section: qpe/applications
+Maintainer: John Ryland <jryland@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: MPEG video/audio player
+ The mpegplayer for the Qtopia environment.
diff --git a/core/multimedia/opieplayer/videowidget.cpp b/core/multimedia/opieplayer/videowidget.cpp
new file mode 100644
index 0000000..f3974a0
--- a/dev/null
+++ b/core/multimedia/opieplayer/videowidget.cpp
@@ -0,0 +1,423 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <qpe/resource.h>
+#include <qwidget.h>
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qslider.h>
+#include <qdrawutil.h>
+#include "videowidget.h"
+#include "mediaplayerplugininterface.h"
+#include "mediaplayerstate.h"
+
+
+#ifdef Q_WS_QWS
+# define USE_DIRECT_PAINTER
+# include <qdirectpainter_qws.h>
+# include <qgfxraster_qws.h>
+#endif
+
+
+extern MediaPlayerState *mediaPlayerState;
+
+
+static const int xo = 2; // movable x offset
+static const int yo = 0; // movable y offset
+
+
+struct MediaButton {
+ int xPos, yPos;
+ bool isToggle, isHeld, isDown;
+ int controlType;
+};
+
+
+// Layout information for the videoButtons (and if it is a toggle button or not)
+MediaButton videoButtons[] = {
+ { 5+0*32+xo, 200+yo, FALSE, FALSE, FALSE, 4 }, // previous
+ { 5+1*32+xo, 200+yo, FALSE, FALSE, FALSE, 1 }, // stop
+ { 5+2*32+xo, 200+yo, TRUE, FALSE, FALSE, 0 }, // play
+ { 5+3*32+xo, 200+yo, TRUE, FALSE, FALSE, 2 }, // pause
+ { 5+4*32+xo, 200+yo, FALSE, FALSE, FALSE, 3 }, // next
+ { 5+5*32+xo, 200+yo, FALSE, FALSE, FALSE, 8 }, // playlist
+ { 5+6*32+xo, 200+yo, TRUE, FALSE, FALSE, 9 } // fullscreen
+};
+
+
+static const int numButtons = (sizeof(videoButtons)/sizeof(MediaButton));
+
+
+VideoWidget::VideoWidget(QWidget* parent, const char* name, WFlags f) :
+ QWidget( parent, name, f ), scaledWidth( 0 ), scaledHeight( 0 ) {
+ setCaption( tr("MediaPlayer") );
+ setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) );
+ pixmaps[0] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaButton0a" ) );
+ pixmaps[1] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaButton0b" ) );
+ pixmaps[2] = new QPixmap( Resource::loadPixmap( "mpegplayer/mediaControls0" ) );
+ currentFrame = new QImage( 220 + 2, 160, (QPixmap::defaultDepth() == 16) ? 16 : 32 );
+
+ slider = new QSlider( Qt::Horizontal, this );
+ slider->setMinValue( 0 );
+ slider->setMaxValue( 1 );
+ slider->setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) );
+ slider->setFocusPolicy( QWidget::NoFocus );
+ slider->setGeometry( QRect( 7, 250, 220, 20 ) );
+
+ connect( slider, SIGNAL( sliderPressed() ), this, SLOT( sliderPressed() ) );
+ connect( slider, SIGNAL( sliderReleased() ), this, SLOT( sliderReleased() ) );
+
+ connect( mediaPlayerState, SIGNAL( lengthChanged(long) ), this, SLOT( setLength(long) ) );
+ connect( mediaPlayerState, SIGNAL( positionChanged(long) ),this, SLOT( setPosition(long) ) );
+ connect( mediaPlayerState, SIGNAL( positionUpdated(long) ),this, SLOT( setPosition(long) ) );
+ connect( mediaPlayerState, SIGNAL( viewChanged(char) ), this, SLOT( setView(char) ) );
+ connect( mediaPlayerState, SIGNAL( pausedToggled(bool) ), this, SLOT( setPaused(bool) ) );
+ connect( mediaPlayerState, SIGNAL( playingToggled(bool) ), this, SLOT( setPlaying(bool) ) );
+
+ // Intialise state
+ setLength( mediaPlayerState->length() );
+ setPosition( mediaPlayerState->position() );
+ setFullscreen( mediaPlayerState->fullscreen() );
+ setPaused( mediaPlayerState->paused() );
+ setPlaying( mediaPlayerState->playing() );
+}
+
+
+VideoWidget::~VideoWidget() {
+ for ( int i = 0; i < 3; i++ )
+ delete pixmaps[i];
+ delete currentFrame;
+}
+
+
+static bool videoSliderBeingMoved = FALSE;
+
+
+void VideoWidget::sliderPressed() {
+ videoSliderBeingMoved = TRUE;
+}
+
+
+void VideoWidget::sliderReleased() {
+ videoSliderBeingMoved = FALSE;
+ if ( slider->width() == 0 )
+ return;
+ long val = long((double)slider->value() * mediaPlayerState->length() / slider->width());
+ mediaPlayerState->setPosition( val );
+}
+
+
+void VideoWidget::setPosition( long i ) {
+ updateSlider( i, mediaPlayerState->length() );
+}
+
+
+void VideoWidget::setLength( long max ) {
+ updateSlider( mediaPlayerState->position(), max );
+}
+
+
+void VideoWidget::setView( char view ) {
+ if ( view == 'v' ) {
+ makeVisible();
+ } else {
+ // Effectively blank the view next time we show it so it looks nicer
+ scaledWidth = 0;
+ scaledHeight = 0;
+ hide();
+ }
+}
+
+
+void VideoWidget::updateSlider( long i, long max ) {
+ // Will flicker too much if we don't do this
+ if ( max == 0 )
+ return;
+ int width = slider->width();
+ int val = int((double)i * width / max);
+ if ( !mediaPlayerState->fullscreen() && !videoSliderBeingMoved ) {
+ if ( slider->value() != val )
+ slider->setValue( val );
+ if ( slider->maxValue() != width )
+ slider->setMaxValue( width );
+ }
+}
+
+
+void VideoWidget::setToggleButton( int i, bool down ) {
+ if ( down != videoButtons[i].isDown )
+ toggleButton( i );
+}
+
+
+void VideoWidget::toggleButton( int i ) {
+ videoButtons[i].isDown = !videoButtons[i].isDown;
+ QPainter p(this);
+ paintButton ( &p, i );
+}
+
+
+void VideoWidget::paintButton( QPainter *p, int i ) {
+ int x = videoButtons[i].xPos;
+ int y = videoButtons[i].yPos;
+ int offset = 10 + videoButtons[i].isDown;
+ p->drawPixmap( x, y, *pixmaps[videoButtons[i].isDown] );
+ p->drawPixmap( x + 1 + offset, y + offset, *pixmaps[2], 9 * videoButtons[i].controlType, 0, 9, 9 );
+}
+
+
+void VideoWidget::mouseMoveEvent( QMouseEvent *event ) {
+ for ( int i = 0; i < numButtons; i++ ) {
+ int x = videoButtons[i].xPos;
+ int y = videoButtons[i].yPos;
+ if ( event->state() == QMouseEvent::LeftButton ) {
+ // The test to see if the mouse click is inside the circular button or not
+ // (compared with the radius squared to avoid a square-root of our distance)
+ int radius = 16;
+ QPoint center = QPoint( x + radius, y + radius );
+ QPoint dXY = center - event->pos();
+ int dist = dXY.x() * dXY.x() + dXY.y() * dXY.y();
+ bool isOnButton = dist <= (radius * radius);
+ if ( isOnButton != videoButtons[i].isHeld ) {
+ videoButtons[i].isHeld = isOnButton;
+ toggleButton(i);
+ }
+ } else {
+ if ( videoButtons[i].isHeld ) {
+ videoButtons[i].isHeld = FALSE;
+ if ( !videoButtons[i].isToggle )
+ setToggleButton( i, FALSE );
+ switch (i) {
+ case VideoPlay: mediaPlayerState->setPlaying(videoButtons[i].isDown); return;
+ case VideoStop: mediaPlayerState->setPlaying(FALSE); return;
+ case VideoPause: mediaPlayerState->setPaused(videoButtons[i].isDown); return;
+ case VideoNext: mediaPlayerState->setNext(); return;
+ case VideoPrevious: mediaPlayerState->setPrev(); return;
+ case VideoPlayList: mediaPlayerState->setList(); return;
+ case VideoFullscreen: mediaPlayerState->setFullscreen( TRUE ); makeVisible(); return;
+ }
+ }
+ }
+ }
+}
+
+
+void VideoWidget::mousePressEvent( QMouseEvent *event ) {
+ mouseMoveEvent( event );
+}
+
+
+void VideoWidget::mouseReleaseEvent( QMouseEvent *event ) {
+ if ( mediaPlayerState->fullscreen() ) {
+ mediaPlayerState->setFullscreen( FALSE );
+ makeVisible();
+ } else {
+ mouseMoveEvent( event );
+ }
+}
+
+
+void VideoWidget::makeVisible() {
+ if ( mediaPlayerState->fullscreen() ) {
+ setBackgroundMode( QWidget::NoBackground );
+ showFullScreen();
+ resize( qApp->desktop()->size() );
+ slider->hide();
+ } else {
+ setBackgroundPixmap( Resource::loadPixmap( "mpegplayer/metalFinish" ) );
+ showNormal();
+ showMaximized();
+ slider->show();
+ }
+}
+
+
+void VideoWidget::paintEvent( QPaintEvent * ) {
+ QPainter p( this );
+
+ if ( mediaPlayerState->fullscreen() ) {
+ // Clear the background
+ p.setBrush( QBrush( Qt::black ) );
+ p.drawRect( rect() );
+
+ // Draw the current frame
+ //p.drawImage( ); // If using directpainter we won't have a copy except whats on the screen
+ } else {
+ // draw border
+ qDrawShadePanel( &p, 4, 15, 230, 170, colorGroup(), TRUE, 5, NULL );
+
+ // Clear the movie screen first
+ p.setBrush( QBrush( Qt::black ) );
+ p.drawRect( 9, 20, 220, 160 );
+
+ // draw current frame (centrally positioned from scaling to maintain aspect ratio)
+ p.drawImage( 9 + (220 - scaledWidth) / 2, 20 + (160 - scaledHeight) / 2, *currentFrame, 0, 0, scaledWidth, scaledHeight );
+
+ // draw the buttons
+ for ( int i = 0; i < numButtons; i++ )
+ paintButton( &p, i );
+
+ // draw the slider
+ slider->repaint( TRUE );
+ }
+}
+
+
+void VideoWidget::closeEvent( QCloseEvent* ) {
+ mediaPlayerState->setList();
+}
+
+
+bool VideoWidget::playVideo() {
+ bool result = FALSE;
+
+ int stream = 0;
+
+ int sw = mediaPlayerState->curDecoder()->videoWidth( stream );
+ int sh = mediaPlayerState->curDecoder()->videoHeight( stream );
+ int dd = QPixmap::defaultDepth();
+ int w = height();
+ int h = width();
+
+ ColorFormat format = (dd == 16) ? RGB565 : BGRA8888;
+
+ if ( mediaPlayerState->fullscreen() ) {
+#ifdef USE_DIRECT_PAINTER
+ QDirectPainter p(this);
+
+ if ( ( qt_screen->transformOrientation() == 3 ) &&
+ ( ( dd == 16 ) || ( dd == 32 ) ) && ( p.numRects() == 1 ) ) {
+
+ w = 320;
+ h = 240;
+
+ if ( mediaPlayerState->scaled() ) {
+ // maintain aspect ratio
+ if ( w * sh > sw * h )
+ w = sw * h / sh;
+ else
+ h = sh * w / sw;
+ } else {
+ w = sw;
+ h = sh;
+ }
+
+ w--; // we can't allow libmpeg to overwrite.
+ QPoint roff = qt_screen->mapToDevice( p.offset(), QSize( qt_screen->width(), qt_screen->height() ) );
+
+ int ox = roff.x() - height() + 2 + (height() - w) / 2;
+ int oy = roff.y() + (width() - h) / 2;
+ int sx = 0, sy = 0;
+
+ uchar* fp = p.frameBuffer() + p.lineStep() * oy;
+ fp += dd * ox / 8;
+ uchar **jt = new uchar*[h];
+ for ( int i = h; i; i-- ) {
+ jt[h - i] = fp;
+ fp += p.lineStep();
+ }
+
+ result = mediaPlayerState->curDecoder()->videoReadScaledFrame( jt, sx, sy, sw, sh, w, h, format, 0) == 0;
+
+ delete [] jt;
+ } else {
+#endif
+ QPainter p(this);
+
+ w = 320;
+ h = 240;
+
+ if ( mediaPlayerState->scaled() ) {
+ // maintain aspect ratio
+ if ( w * sh > sw * h )
+ w = sw * h / sh;
+ else
+ h = sh * w / sw;
+ } else {
+ w = sw;
+ h = sh;
+ }
+
+ int bytes = ( dd == 16 ) ? 2 : 4;
+ QImage tempFrame( w, h, bytes << 3 );
+ result = mediaPlayerState->curDecoder()->videoReadScaledFrame( tempFrame.jumpTable(),
+ 0, 0, sw, sh, w, h, format, 0) == 0;
+ if ( result && mediaPlayerState->fullscreen() ) {
+
+ int rw = h, rh = w;
+ QImage rotatedFrame( rw, rh, bytes << 3 );
+
+ ushort* in = (ushort*)tempFrame.bits();
+ ushort* out = (ushort*)rotatedFrame.bits();
+ int spl = rotatedFrame.bytesPerLine() / bytes;
+ for (int x=0; x<h; x++) {
+ if ( bytes == 2 ) {
+ ushort* lout = out++ + (w - 1)*spl;
+ for (int y=0; y<w; y++) {
+ *lout=*in++;
+ lout-=spl;
+ }
+ } else {
+ ulong* lout = ((ulong *)out)++ + (w - 1)*spl;
+ for (int y=0; y<w; y++) {
+ *lout=*((ulong*)in)++;
+ lout-=spl;
+ }
+ }
+ }
+
+ p.drawImage( (240 - rw) / 2, (320 - rh) / 2, rotatedFrame, 0, 0, rw, rh );
+ }
+#ifdef USE_DIRECT_PAINTER
+ }
+#endif
+ } else {
+
+ w = 220;
+ h = 160;
+
+ // maintain aspect ratio
+ if ( w * sh > sw * h )
+ w = sw * h / sh;
+ else
+ h = sh * w / sw;
+
+ result = mediaPlayerState->curDecoder()->videoReadScaledFrame( currentFrame->jumpTable(), 0, 0, sw, sh, w, h, format, 0) == 0;
+
+ QPainter p( this );
+
+ // Image changed size, therefore need to blank the possibly unpainted regions first
+ if ( scaledWidth != w || scaledHeight != h ) {
+ p.setBrush( QBrush( Qt::black ) );
+ p.drawRect( 9, 20, 220, 160 );
+ }
+
+ scaledWidth = w;
+ scaledHeight = h;
+
+ if ( result ) {
+ p.drawImage( 9 + (220 - scaledWidth) / 2, 20 + (160 - scaledHeight) / 2, *currentFrame, 0, 0, scaledWidth, scaledHeight );
+ }
+
+ }
+
+ return result;
+}
+
+
diff --git a/core/multimedia/opieplayer/videowidget.h b/core/multimedia/opieplayer/videowidget.h
new file mode 100644
index 0000000..8b49091
--- a/dev/null
+++ b/core/multimedia/opieplayer/videowidget.h
@@ -0,0 +1,88 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef VIDEO_WIDGET_H
+#define VIDEO_WIDGET_H
+
+
+#include <qwidget.h>
+
+
+class QPixmap;
+class QSlider;
+
+
+enum VideoButtons {
+ VideoPrevious,
+ VideoStop,
+ VideoPlay,
+ VideoPause,
+ VideoNext,
+ VideoPlayList,
+ VideoFullscreen
+};
+
+
+class VideoWidget : public QWidget {
+ Q_OBJECT
+public:
+ VideoWidget( QWidget* parent=0, const char* name=0, WFlags f=0 );
+ ~VideoWidget();
+
+ bool playVideo();
+
+public slots:
+ void updateSlider( long, long );
+ void sliderPressed( );
+ void sliderReleased( );
+ void setPaused( bool b) { setToggleButton( VideoPause, b ); }
+ void setPlaying( bool b) { setToggleButton( VideoPlay, b ); }
+ void setFullscreen( bool b ) { setToggleButton( VideoFullscreen, b ); }
+ void makeVisible();
+ void setPosition( long );
+ void setLength( long );
+ void setView( char );
+
+signals:
+ void sliderMoved( long );
+
+protected:
+ void paintEvent( QPaintEvent *pe );
+ void mouseMoveEvent( QMouseEvent *event );
+ void mousePressEvent( QMouseEvent *event );
+ void mouseReleaseEvent( QMouseEvent *event );
+ void closeEvent( QCloseEvent *event );
+
+private:
+ void paintButton( QPainter *p, int i );
+ void toggleButton( int );
+ void setToggleButton( int, bool );
+
+ QSlider *slider;
+ QPixmap *pixmaps[3];
+ QImage *currentFrame;
+ int scaledWidth;
+ int scaledHeight;
+};
+
+
+#endif // VIDEO_WIDGET_H
+
+
+
diff --git a/core/multimedia/opieplayer/wavplugin/.cvsignore b/core/multimedia/opieplayer/wavplugin/.cvsignore
new file mode 100644
index 0000000..6fe2396
--- a/dev/null
+++ b/core/multimedia/opieplayer/wavplugin/.cvsignore
@@ -0,0 +1,2 @@
+moc_*
+Makefile
diff --git a/core/multimedia/opieplayer/wavplugin/Makefile.in b/core/multimedia/opieplayer/wavplugin/Makefile.in
new file mode 100644
index 0000000..c9203f8
--- a/dev/null
+++ b/core/multimedia/opieplayer/wavplugin/Makefile.in
@@ -0,0 +1,112 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS) $(SYSCONF_CXXFLAGS_LIB) -DQCONFIG=\"qpe\"
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS) $(SYSCONF_CFLAGS_LIB) -DQCONFIG=\"qpe\"
+INCPATH = -I$(QPEDIR)/include -I..
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../../plugins/codecs/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = wavplugin
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = wavplugin.h \
+ wavpluginimpl.h
+SOURCES = wavplugin.cpp \
+ wavpluginimpl.cpp
+OBJECTS = wavplugin.o \
+ wavpluginimpl.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC =
+OBJMOC =
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(SYSCONF_LINK_TARGET)
+
+$(DESTDIR)$(SYSCONF_LINK_TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK_LIB)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake wavplugin.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+wavplugin.o: wavplugin.cpp \
+ wavplugin.h \
+ ../mediaplayerplugininterface.h
+
+wavpluginimpl.o: wavpluginimpl.cpp \
+ wavplugin.h \
+ ../mediaplayerplugininterface.h \
+ wavpluginimpl.h \
+ ../mediaplayerplugininterface.h
+
+
diff --git a/core/multimedia/opieplayer/wavplugin/qpe-wavplugin.control b/core/multimedia/opieplayer/wavplugin/qpe-wavplugin.control
new file mode 100644
index 0000000..8e7eedb
--- a/dev/null
+++ b/core/multimedia/opieplayer/wavplugin/qpe-wavplugin.control
@@ -0,0 +1,9 @@
+Files: plugins/codecs/libwavplugin.so.1.0.0 plugins/codecs/libwavplugin.so.1.0 plugins/codecs/libwavplugin.so.1 plugins/codecs/libwavplugin.so
+Priority: optional
+Section: qpe/plugins
+Maintainer: John Ryland <jryland@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: WAV file plugin
+ Plugin to play WAV files with the mediaplayer in the Qtopia environment.
diff --git a/core/multimedia/opieplayer/wavplugin/wavplugin.cpp b/core/multimedia/opieplayer/wavplugin/wavplugin.cpp
new file mode 100644
index 0000000..60a0024
--- a/dev/null
+++ b/core/multimedia/opieplayer/wavplugin/wavplugin.cpp
@@ -0,0 +1,334 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <qfile.h>
+#include "wavplugin.h"
+
+
+//#define debugMsg(a) qDebug(a)
+#define debugMsg(a)
+
+
+struct RiffChunk {
+ char id[4];
+ Q_UINT32 size;
+ char data[4];
+};
+
+
+struct ChunkData {
+ Q_INT16 formatTag;
+ Q_INT16 channels;
+ Q_INT32 samplesPerSec;
+ Q_INT32 avgBytesPerSec;
+ Q_INT16 blockAlign;
+ Q_INT16 wBitsPerSample;
+};
+
+
+const int sound_buffer_size = 4096;
+
+
+class WavPluginData {
+public:
+ QFile *input;
+
+ int wavedata_remaining;
+ ChunkData chunkdata;
+ RiffChunk chunk;
+ uchar data[sound_buffer_size+32]; // +32 to handle badly aligned input data
+ int out,max;
+ int samples_due;
+ int samples;
+
+ WavPluginData() {
+ max = out = sound_buffer_size;
+ wavedata_remaining = 0;
+ samples_due = 0;
+ samples = -1;
+ }
+
+ // expands out samples to the frequency of 44kHz
+ bool add( short *output, long count, long& done, bool stereo )
+ {
+ done = 0;
+
+ if ( input == 0 ) {
+ qDebug("no input");
+ return FALSE;
+ }
+
+ while ( count ) {
+ int l,r;
+ if ( getSample(l, r) == FALSE ) {
+ qDebug("didn't get sample");
+ return FALSE;
+ }
+ samples_due += 44100;
+ while ( count && (samples_due > chunkdata.samplesPerSec) ) {
+ *output++ = l;
+ if ( stereo )
+ *output++ = r;
+ samples_due -= chunkdata.samplesPerSec;
+ count--;
+ done++;
+ }
+ }
+
+ return TRUE;
+ }
+
+ bool initialise() {
+ if ( input == 0 )
+ return FALSE;
+
+ wavedata_remaining = -1;
+
+ while ( wavedata_remaining == -1 ) {
+ // Keep reading chunks...
+ const int n = sizeof(chunk) - sizeof(chunk.data);
+ int t = input->readBlock( (char*)&chunk, n );
+ if ( t != n ) {
+ if ( t == -1 )
+ return FALSE;
+ return TRUE;
+ }
+ if ( qstrncmp(chunk.id,"data",4) == 0 ) {
+ samples = wavedata_remaining = chunk.size;
+ } else if ( qstrncmp(chunk.id,"RIFF",4) == 0 ) {
+ char d[4];
+ if ( input->readBlock(d,4) != 4 ) {
+ return FALSE;
+ }
+ if ( qstrncmp(d,"WAVE",4) != 0 ) {
+ // skip
+ if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size-4) ) {
+ return FALSE;
+ }
+ }
+ } else if ( qstrncmp(chunk.id,"fmt ",4) == 0 ) {
+ if ( input->readBlock((char*)&chunkdata,sizeof(chunkdata)) != sizeof(chunkdata) ) {
+ return FALSE;
+ }
+#define WAVE_FORMAT_PCM 1
+ if ( chunkdata.formatTag != WAVE_FORMAT_PCM ) {
+ qDebug("WAV file: UNSUPPORTED FORMAT %d",chunkdata.formatTag);
+ return FALSE;
+ }
+ } else {
+ // ignored chunk
+ if ( chunk.size > 1000000000 || !input->at(input->at()+chunk.size) ) {
+ return FALSE;
+ }
+ }
+ } // while
+
+ return TRUE;
+ }
+
+
+ // gets a sample from the file
+ bool getSample(int& l, int& r)
+ {
+ l = r = 0;
+
+ if ( input == 0 )
+ return FALSE;
+
+ if ( (wavedata_remaining < 0) || !max )
+ return FALSE;
+
+ if ( out >= max ) {
+ max = input->readBlock( (char*)data, (uint)QMIN(sound_buffer_size,wavedata_remaining) );
+
+ wavedata_remaining -= max;
+
+ out = 0;
+ if ( max <= 0 ) {
+ max = 0;
+ return TRUE;
+ }
+ }
+ if ( chunkdata.wBitsPerSample == 8 ) {
+ l = (data[out++] - 128) * 128;
+ } else {
+ l = ((short*)data)[out/2];
+ out += 2;
+ }
+ if ( chunkdata.channels == 1 ) {
+ r = l;
+ } else {
+ if ( chunkdata.wBitsPerSample == 8 ) {
+ r = (data[out++] - 128) * 128;
+ } else {
+ r = ((short*)data)[out/2];
+ out += 2;
+ }
+ }
+ return TRUE;
+ } // getSample
+
+};
+
+
+WavPlugin::WavPlugin() {
+ d = new WavPluginData;
+ d->input = 0;
+}
+
+
+WavPlugin::~WavPlugin() {
+ close();
+ delete d;
+}
+
+
+bool WavPlugin::isFileSupported( const QString& path ) {
+ debugMsg( "WavPlugin::isFileSupported" );
+
+ char *ext = strrchr( path.latin1(), '.' );
+
+ // Test file extension
+ if ( ext ) {
+ if ( strncasecmp(ext, ".raw", 4) == 0 )
+ return TRUE;
+ if ( strncasecmp(ext, ".wav", 4) == 0 )
+ return TRUE;
+ if ( strncasecmp(ext, ".wave", 4) == 0 )
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+bool WavPlugin::open( const QString& path ) {
+ debugMsg( "WavPlugin::open" );
+
+ d->max = d->out = sound_buffer_size;
+ d->wavedata_remaining = 0;
+ d->samples_due = 0;
+
+ d->input = new QFile( path );
+ if ( d->input->open(IO_ReadOnly) == FALSE ) {
+ qDebug("couldn't open file");
+ delete d->input;
+ d->input = 0;
+ return FALSE;
+ }
+
+ d->initialise();
+
+ return TRUE;
+}
+
+
+bool WavPlugin::close() {
+ debugMsg( "WavPlugin::close" );
+
+ d->input->close();
+ delete d->input;
+ d->input = 0;
+ return TRUE;
+}
+
+
+bool WavPlugin::isOpen() {
+ debugMsg( "WavPlugin::isOpen" );
+ return ( d->input != 0 );
+}
+
+
+int WavPlugin::audioStreams() {
+ debugMsg( "WavPlugin::audioStreams" );
+ return 1;
+}
+
+
+int WavPlugin::audioChannels( int ) {
+ debugMsg( "WavPlugin::audioChannels" );
+ return 2; // ### Always scale audio to stereo samples
+}
+
+
+int WavPlugin::audioFrequency( int ) {
+ debugMsg( "WavPlugin::audioFrequency" );
+ return 44100; // ### Always scale to frequency of 44100
+}
+
+
+int WavPlugin::audioSamples( int ) {
+ debugMsg( "WavPlugin::audioSamples" );
+ return d->samples * 2 / d->chunkdata.channels; // ### Scaled samples will be made stereo,
+ // Therefore if source is mono we will double the number of samples
+}
+
+
+bool WavPlugin::audioSetSample( long, int ) {
+ debugMsg( "WavPlugin::audioSetSample" );
+ return FALSE;
+}
+
+
+long WavPlugin::audioGetSample( int ) {
+ debugMsg( "WavPlugin::audioGetSample" );
+ return 0;
+}
+
+/*
+bool WavPlugin::audioReadSamples( short *, int, long, int ) {
+ debugMsg( "WavPlugin::audioReadSamples" );
+ return FALSE;
+}
+
+
+bool WavPlugin::audioReReadSamples( short *, int, long, int ) {
+ debugMsg( "WavPlugin::audioReReadSamples" );
+ return FALSE;
+}
+
+
+bool WavPlugin::audioReadMonoSamples( short *output, long samples, long& samplesMade, int ) {
+ debugMsg( "WavPlugin::audioReadMonoSamples" );
+ return !d->add( output, samples, samplesMade, FALSE );
+}
+
+
+bool WavPlugin::audioReadStereoSamples( short *output, long samples, long& samplesMade, int ) {
+ debugMsg( "WavPlugin::audioReadStereoSamples" );
+ return !d->add( output, samples, samplesMade, TRUE );
+}
+*/
+
+bool WavPlugin::audioReadSamples( short *output, int channels, long samples, long& samplesMade, int ) {
+ debugMsg( "WavPlugin::audioReadSamples" );
+ return !d->add( output, samples, samplesMade, channels != 1 );
+}
+
+double WavPlugin::getTime() {
+ debugMsg( "WavPlugin::getTime" );
+ return 0.0;
+}
+
+
diff --git a/core/multimedia/opieplayer/wavplugin/wavplugin.h b/core/multimedia/opieplayer/wavplugin/wavplugin.h
new file mode 100644
index 0000000..64635ca
--- a/dev/null
+++ b/core/multimedia/opieplayer/wavplugin/wavplugin.h
@@ -0,0 +1,97 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef WAV_PLUGIN_H
+#define WAV_PLUGIN_H
+
+
+#include <qstring.h>
+#include <qapplication.h>
+#include "mediaplayerplugininterface.h"
+
+
+class WavPluginData;
+
+
+class WavPlugin : public MediaPlayerDecoder {
+
+public:
+ WavPlugin();
+ ~WavPlugin();
+
+ const char *pluginName() { return "WavPlugin"; }
+ const char *pluginComment() { return "This is a simple plugin for playing wav files"; }
+ double pluginVersion() { return 1.0; }
+
+ bool isFileSupported( const QString& );
+ bool open( const QString& );
+ bool close();
+ bool isOpen();
+ //const QString &fileInfo() { return strInfo = qApp->translate( "MediaPlayer", "No Information Available", "media plugin text" ); }
+ const QString &fileInfo() { return strInfo = QString(""); }
+
+ // If decoder doesn't support audio then return 0 here
+ int audioStreams();
+ int audioChannels( int stream );
+ int audioFrequency( int stream );
+ int audioSamples( int stream );
+ bool audioSetSample( long sample, int stream );
+ long audioGetSample( int stream );
+ //bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream );
+ //bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream );
+ bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream );
+ //bool audioReadSamples( short *output, int channel, long samples, int stream );
+ //bool audioReReadSamples( short *output, int channel, long samples, int stream );
+
+ // If decoder doesn't support video then return 0 here
+ int videoStreams() { return 0; }
+ int videoWidth( int ) { return 0; }
+ int videoHeight( int ) { return 0; }
+ double videoFrameRate( int ) { return 0.0; }
+ int videoFrames( int ) { return 0; }
+ bool videoSetFrame( long, int ) { return FALSE; }
+ long videoGetFrame( int ) { return 0; }
+ bool videoReadFrame( unsigned char **, int, int, int, int, ColorFormat, int ) { return FALSE; }
+ bool videoReadScaledFrame( unsigned char **, int, int, int, int, int, int, ColorFormat, int ) { return FALSE; }
+ bool videoReadYUVFrame( char *, char *, char *, int, int, int, int, int ) { return FALSE; }
+
+ // Profiling
+ double getTime();
+
+ // Ignore if these aren't supported
+ bool setSMP( int ) { return FALSE; }
+ bool setMMX( bool ) { return FALSE; }
+
+ // Capabilities
+ bool supportsAudio() { return TRUE; }
+ bool supportsVideo() { return FALSE; }
+ bool supportsYUV() { return FALSE; }
+ bool supportsMMX() { return TRUE; }
+ bool supportsSMP() { return FALSE; }
+ bool supportsStereo() { return TRUE; }
+ bool supportsScaling() { return FALSE; }
+
+private:
+ WavPluginData *d;
+ QString strInfo;
+
+};
+
+
+#endif
diff --git a/core/multimedia/opieplayer/wavplugin/wavplugin.pro b/core/multimedia/opieplayer/wavplugin/wavplugin.pro
new file mode 100644
index 0000000..4663813
--- a/dev/null
+++ b/core/multimedia/opieplayer/wavplugin/wavplugin.pro
@@ -0,0 +1,10 @@
+TEMPLATE = lib
+CONFIG += qt warn_on release
+HEADERS = wavplugin.h wavpluginimpl.h
+SOURCES = wavplugin.cpp wavpluginimpl.cpp
+TARGET = wavplugin
+DESTDIR = ../../plugins/codecs
+INCLUDEPATH += $(QPEDIR)/include ..
+DEPENDPATH += ../$(QPEDIR)/include ..
+LIBS += -lqpe
+VERSION = 1.0.0
diff --git a/core/multimedia/opieplayer/wavplugin/wavpluginimpl.cpp b/core/multimedia/opieplayer/wavplugin/wavpluginimpl.cpp
new file mode 100644
index 0000000..1f7b85b
--- a/dev/null
+++ b/core/multimedia/opieplayer/wavplugin/wavpluginimpl.cpp
@@ -0,0 +1,70 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "wavplugin.h"
+#include "wavpluginimpl.h"
+
+
+WavPluginImpl::WavPluginImpl()
+ : libmadplugin(0), ref(0)
+{
+}
+
+
+WavPluginImpl::~WavPluginImpl()
+{
+ if ( libmadplugin )
+ delete libmadplugin;
+}
+
+
+MediaPlayerDecoder *WavPluginImpl::decoder()
+{
+ if ( !libmadplugin )
+ libmadplugin = new WavPlugin;
+ return libmadplugin;
+}
+
+
+MediaPlayerEncoder *WavPluginImpl::encoder()
+{
+ return NULL;
+}
+
+
+#ifndef QT_NO_COMPONENT
+
+
+QRESULT WavPluginImpl::queryInterface( const QUuid &uuid, QUnknownInterface **iface )
+{
+ *iface = 0;
+ if ( ( uuid == IID_QUnknown ) || ( uuid == IID_MediaPlayerPlugin ) )
+ *iface = this, (*iface)->addRef();
+ return QS_OK;
+}
+
+
+Q_EXPORT_INTERFACE()
+{
+ Q_CREATE_INSTANCE( WavPluginImpl )
+}
+
+
+#endif
+
diff --git a/core/multimedia/opieplayer/wavplugin/wavpluginimpl.h b/core/multimedia/opieplayer/wavplugin/wavpluginimpl.h
new file mode 100644
index 0000000..ee32f54
--- a/dev/null
+++ b/core/multimedia/opieplayer/wavplugin/wavpluginimpl.h
@@ -0,0 +1,53 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef WAV_PLUGIN_IMPL_H
+#define WAV_PLUGIN_IMPL_H
+
+
+#include "../mediaplayerplugininterface.h"
+
+
+class WavPlugin;
+
+
+class WavPluginImpl : public MediaPlayerPluginInterface
+{
+public:
+ WavPluginImpl();
+ virtual ~WavPluginImpl();
+
+#ifndef QT_NO_COMPONENT
+
+ QRESULT queryInterface( const QUuid&, QUnknownInterface** );
+ Q_REFCOUNT
+
+#endif
+
+ virtual MediaPlayerDecoder *decoder();
+ virtual MediaPlayerEncoder *encoder();
+
+private:
+ WavPlugin *libmadplugin;
+ ulong ref;
+};
+
+
+#endif
+
diff --git a/core/opie-login/.cvsignore b/core/opie-login/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/core/opie-login/.cvsignore
@@ -0,0 +1,3 @@
+moc_*
+*.moc
+Makefile
diff --git a/core/opie-login/README b/core/opie-login/README
new file mode 100644
index 0000000..ad3b298
--- a/dev/null
+++ b/core/opie-login/README
@@ -0,0 +1,78 @@
+
+Welcome to LISA System's
+
+ QDM - the Login-Dialog for QPE
+
+
+WHAT'S THIS:
+
+This small add-on for the Qtopia Environment (QPE - see
+http://qpe.sourceforge.net for further details) allows You to use your
+handheld computer running QPE and Linux with the typical Un*x user
+handling, i.e. just log in on a graphical environment, as e.g. KDM or
+XDM. This way your personal data can be easily protected against
+unwanted access from others in case you loose your machine.
+
+
+STATUS:
+
+Still in development, but should be useable.
+
+
+REQUIREMENTS:
+
+- QDM needs Linux-PAM (Pluggable Authentication Modules for Linux) for
+ proper user validation.
+
+- the /dev/fb0 device has to writeable to everyone ;-(
+
+
+INSTALLATION:
+
+Per default this little add-on is not enabled. You have to do so
+yourself for now, by setting a compile option variable called
+QT_QWS_LOGIN . Furthermore there have to be made some changes in
+taskbar/taskbar.pro :
+
+At the section HEADERS insert a line:
+ ../login/qdmdialogimpl.h \
+
+At the section SOURCES insert a line:
+ ../login/qdmdialogimpl.cpp \
+
+furthermore serte these lines:
+
+INCLUDEPATH += ../login
+DEPENDPATH += ../login
+
+INTERFACES = ../login/qdmdialog.ui
+
+For unix-login make folloing changes to a line:
+LIBS = -lqpe -lcrypt
+
+For PAM use the following:
+LIBS = -lqpe -ldl -lpam
+
+
+
+CONFIGURATION:
+
+Configuration of the 'Look' of QDM is done via Qt Designer. Just open
+the .ui file and edit the look of the dialog as you like. You can, for
+instance, change the logo pixmap. QDM should also be ready for i18n so
+far.
+
+Other configuration stuff, eg welcome string in the upper right, and
+user list can be changed in the qdm_config.h file.
+
+
+USAGE:
+
+The QDM comes up, when the QPE is started, and if the QPE is started
+as 'root'. Being started as any other user, the uid couldn't be
+changed and the login dialog wouldn't be ofg much use.
+
+
+CONTACT:
+
+http://www.lisa.de
diff --git a/core/opie-login/qdm_config.h b/core/opie-login/qdm_config.h
new file mode 100644
index 0000000..bf5b5a4
--- a/dev/null
+++ b/core/opie-login/qdm_config.h
@@ -0,0 +1,30 @@
+//-- -*- c++ -*-
+
+#ifndef _QDM_CONFIG_H
+#define _QDM_CONFIG_H
+
+/*
+ * Config file for QDM
+ */
+
+
+/** define this to enable the qdm login dialog for qpe */
+#define QT_QWS_LOGIN
+
+/** define this to let qdm use Linux-PAM */
+//define QT_QWS_LOGIN_USEPAM
+
+/** this is the list of users shown in the input-list */
+#define QDM_SHOWNUSERS static char *Shown_Users[] = { "guest", "root", "lisa", 0 };
+
+/** which command to execute when going to sleep mode */
+#define QDM_CMD_SLEEP "/sbin/shutdow","-z","now"
+
+/** which command to execute when shutting down */
+#define QDM_CMD_SHUTDOWN "/sbin/shutdow","-z","now"
+
+/** Welcome string on dialog */
+#define QDM_WELCOME_STRING "Welcome to\nmLinux [iPAQ]"
+
+
+#endif //-- _QDM_CONFIG_H
diff --git a/core/opie-login/qdmdialog.ui b/core/opie-login/qdmdialog.ui
new file mode 100644
index 0000000..c9faf6f
--- a/dev/null
+++ b/core/opie-login/qdmdialog.ui
@@ -0,0 +1,856 @@
+<!DOCTYPE UI><UI>
+<class>QDMDialog</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>QDMDialog</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>7</y>
+ <width>240</width>
+ <height>320</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>minimumSize</name>
+ <size>
+ <width>240</width>
+ <height>240</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>maximumSize</name>
+ <size>
+ <width>240</width>
+ <height>320</height>
+ </size>
+ </property>
+ <property stdset="1">
+ <name>palette</name>
+ <palette>
+ <active>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>228</red>
+ <green>228</green>
+ <blue>228</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>242</red>
+ <green>242</green>
+ <blue>242</blue>
+ </color>
+ <color>
+ <red>78</red>
+ <green>78</green>
+ <blue>78</blue>
+ </color>
+ <color>
+ <red>183</red>
+ <green>183</green>
+ <blue>183</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </active>
+ <disabled>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>228</red>
+ <green>228</green>
+ <blue>228</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>242</red>
+ <green>242</green>
+ <blue>242</blue>
+ </color>
+ <color>
+ <red>78</red>
+ <green>78</green>
+ <blue>78</blue>
+ </color>
+ <color>
+ <red>183</red>
+ <green>183</green>
+ <blue>183</blue>
+ </color>
+ <color>
+ <red>183</red>
+ <green>183</green>
+ <blue>183</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </disabled>
+ <inactive>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>228</red>
+ <green>228</green>
+ <blue>228</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>242</red>
+ <green>242</green>
+ <blue>242</blue>
+ </color>
+ <color>
+ <red>78</red>
+ <green>78</green>
+ <blue>78</blue>
+ </color>
+ <color>
+ <red>183</red>
+ <green>183</green>
+ <blue>183</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>10</red>
+ <green>95</green>
+ <blue>137</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </inactive>
+ </palette>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>QDM</string>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>label_logo</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>10</x>
+ <y>10</y>
+ <width>100</width>
+ <height>33</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>palette</name>
+ <palette>
+ <active>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>237</red>
+ <green>237</green>
+ <blue>237</blue>
+ </color>
+ <color>
+ <red>110</red>
+ <green>110</green>
+ <blue>110</blue>
+ </color>
+ <color>
+ <red>146</red>
+ <green>146</green>
+ <blue>146</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>84</red>
+ <green>112</green>
+ <blue>152</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </active>
+ <disabled>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>253</red>
+ <green>253</green>
+ <blue>253</blue>
+ </color>
+ <color>
+ <red>110</red>
+ <green>110</green>
+ <blue>110</blue>
+ </color>
+ <color>
+ <red>146</red>
+ <green>146</green>
+ <blue>146</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>128</red>
+ <green>128</green>
+ <blue>128</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>84</red>
+ <green>112</green>
+ <blue>152</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </disabled>
+ <inactive>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>220</red>
+ <green>220</green>
+ <blue>220</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>253</red>
+ <green>253</green>
+ <blue>253</blue>
+ </color>
+ <color>
+ <red>110</red>
+ <green>110</green>
+ <blue>110</blue>
+ </color>
+ <color>
+ <red>146</red>
+ <green>146</green>
+ <blue>146</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ <color>
+ <red>84</red>
+ <green>112</green>
+ <blue>152</blue>
+ </color>
+ <color>
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </inactive>
+ </palette>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Panel</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>margin</name>
+ <number>2</number>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image0</pixmap>
+ </property>
+ <property stdset="1">
+ <name>scaledContents</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>label_welcome</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>120</x>
+ <y>10</y>
+ <width>110</width>
+ <height>40</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <pointsize>14</pointsize>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Welcome to
+mLinux [iPAQ]</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignCenter</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>label_time</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>180</x>
+ <y>50</y>
+ <width>50</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>12:30:88</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>label_date</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>70</x>
+ <y>50</y>
+ <width>100</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Wed Feb 12 2001</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel5</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>20</x>
+ <y>50</y>
+ <width>50</width>
+ <height>16</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Today:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>GroupBox3</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>10</x>
+ <y>80</y>
+ <width>220</width>
+ <height>120</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>backgroundOrigin</name>
+ <enum>WidgetOrigin</enum>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Login</string>
+ </property>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PushButton3</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>160</x>
+ <y>60</y>
+ <width>50</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Clear</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>input_password</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>80</x>
+ <y>60</y>
+ <width>70</width>
+ <height>22</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>echoMode</name>
+ <enum>Password</enum>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>input_user</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>80</x>
+ <y>30</y>
+ <width>120</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>label_user</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>10</x>
+ <y>30</y>
+ <width>60</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>User</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>label_password</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>10</x>
+ <y>60</y>
+ <width>60</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Password</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>button_shutdown</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>150</x>
+ <y>90</y>
+ <width>61</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Shutdown</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>button_login</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>10</x>
+ <y>90</y>
+ <width>60</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Login</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>button_sleep</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>90</x>
+ <y>90</y>
+ <width>60</width>
+ <height>20</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Sleep</string>
+ </property>
+ </widget>
+ </widget>
+</widget>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="4080">789ced97db72e2461086effd149475e74a69413258d4d65ef880c7c022cbd8eb35a472a123c8465a09640ebb9577cffc3d033a986c2a38a9ca45bacb653ecd34bf7aba67843e9cd49eac41ede4c3d122b3b3d0adb9537b5e3bf15ea368f3eb6f9f7e1c1db78d9adea8358d5ae3f897a3e3b8e6d6943a19302234e04005d8a8c3811ea10107da40ad01073e123a70e01d502703ce086d38f00bf0b401075e13da70e03760b30e070e086d38d001b6c8804be059130e4c091d3850071aa770a04fe8c2817d609b0ca801e92e68b24be8c18109d0d1e1c021a10f07f6806e130e3409c98016d03b8303c784011c3802fa677020230ce0c00c180486236a3495e8d7697228b0ad891a2d24b6448d3a126d8d4637123d8d6227026d4dd7806b894d51a3ae44e39462eb12bd535ad82b8981a8d1ad40476b52facf129b4d4abf21d168d1d27d97e8b668f446627046a35f05ba4d83bef95262dba01a9d4b740c2aca834457543010e8e96d2aca85c49628e8ab44dba6d1cf123d87eef945a0df10057d92d87269ade612db2e15e55ea2e7d13aaf24061e65a40a84112ab6eda87bcdb56dcf7f7335984c4361cf2f7bc3669ee7450526152f8ebfed5749f8505ab9369f2cb29d2d16af7bee4d89e3385abe4765b5ceb2e9e6fbf9457079d509b3cefc6dd435d788638fbd43e5669a65dd95848bcd9e25eb7971348b62a5ff0e950d5fa6cffb674b1bc4b16df2c0d92e99bfafd2c9b2f0fc6722a68d1887af9a7bb8ca33af79e7767f6fed52b154247377b8ca4af4d6e6ea72bf125219f0ff335effe1c12aeafd3adc7671f781bd097178dd4d84f276fe72b88aaabedc4c3a62cf848b6a428c7ff98c3e3cc6b1d27b870ab7d5ebd76e678a849eca0383288eae53d82c4fe6501552bac1d2754bd746d8f6b945e377abf0038dcb2c56c52bbe1247b9c5b1f30fa8acaa2aa3bb387eb4c6c212de6ddef8309555a110975c655d4d253fc3f9ce11c96c55664369bdbf529984f5877bfa346ff0460b8ba70df555dedc431efd382ea8283bb37eae82c332ec7436ddee063db6b9280e6acab612c2f8ce8cd2ad4ab12f9471316ca8545556b761b87db84c17f5f2b9cf0b1115ef52930f0052d1d3dcfaa530b65c2e476ac59ece9fd793ce66520f569591beae27a5707e41dfe6f2afdbff2aff61959ee627f96e1ca2977b79439baeef0e775b2d11b64546c472a4e042a3b1c4d7127ab970993ada3da35553676a2f3f26923e53597e245896e5f0bf1d02ac9d8a95a64c1debf9ce64a9a53293de6892f2132fe98fd3fc8ad6af3e0f8bbbbbaae2f3347d96cf182db7270c73fda55f3cbfb4e24ee4292ffdd25e2bab9456ccf2d5d44d8a33cc7e2a5e4048332d9c2c56f5a731f387052aab9426f2486bc9d4caaf6eaa8b6f614159696e6eaec9573a35ff54a5b262951963de378c5e01ccc42f97861597cfc268f9a02e4eadf458af32830d355feb1dfffef1e80f6ca1ac19</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>button_shutdown</sender>
+ <signal>clicked()</signal>
+ <receiver>QDMDialog</receiver>
+ <slot>slot_shutdown()</slot>
+ </connection>
+ <connection>
+ <sender>button_login</sender>
+ <signal>clicked()</signal>
+ <receiver>QDMDialog</receiver>
+ <slot>slot_login()</slot>
+ </connection>
+ <connection>
+ <sender>input_password</sender>
+ <signal>returnPressed()</signal>
+ <receiver>button_login</receiver>
+ <slot>setFocus()</slot>
+ </connection>
+ <connection>
+ <sender>input_user</sender>
+ <signal>highlighted(const QString&amp;)</signal>
+ <receiver>input_password</receiver>
+ <slot>setFocus()</slot>
+ </connection>
+ <connection>
+ <sender>PushButton3</sender>
+ <signal>clicked()</signal>
+ <receiver>input_password</receiver>
+ <slot>clear()</slot>
+ </connection>
+ <connection>
+ <sender>button_sleep</sender>
+ <signal>clicked()</signal>
+ <receiver>QDMDialog</receiver>
+ <slot>slot_sleepmode()</slot>
+ </connection>
+ <slot access="public">slot_sleepmode()</slot>
+ <slot access="public">slot_login()</slot>
+ <slot access="public">slot_shutdown()</slot>
+</connections>
+<tabstops>
+ <tabstop>input_user</tabstop>
+ <tabstop>input_password</tabstop>
+ <tabstop>button_login</tabstop>
+ <tabstop>PushButton3</tabstop>
+ <tabstop>button_sleep</tabstop>
+ <tabstop>button_shutdown</tabstop>
+</tabstops>
+</UI>
diff --git a/core/opie-login/qdmdialogimpl.cpp b/core/opie-login/qdmdialogimpl.cpp
new file mode 100644
index 0000000..bb1b453
--- a/dev/null
+++ b/core/opie-login/qdmdialogimpl.cpp
@@ -0,0 +1,535 @@
+/**********************************************************************
+** Copyright (C) 2001 LISA Systems
+**
+** This file is an additional part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** For further information contact info@lisa.de
+**
+**********************************************************************/
+
+/*
+ * AUTHOR: Christian Rahn
+ * EMAIL: cdr@lisa.de
+ *
+ * $Id$
+ */
+
+#include "qdm_config.h"
+
+#ifdef QT_QWS_LOGIN
+
+#include <pwd.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <iostream.h>
+#include <assert.h>
+
+#include <qlabel.h>
+#include <qregexp.h>
+#include <qdatetime.h>
+#include <qmessagebox.h>
+#include <qcombobox.h>
+#include <qlineedit.h>
+#include <qtranslator.h>
+#include <qpeapplication.h>
+
+#include <qwsdisplay_qws.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+#include <sys/ipc.h>
+
+#include <global.h>
+
+#if defined(QT_QWS_LOGIN_USEPAM)
+extern "C" {
+#include <security/pam_appl.h>
+}
+#else
+#define _XOPEN_SOURCE
+#include <unistd.h>
+#include <crypt.h>
+#endif
+
+
+#include "qdmdialogimpl.h"
+#include "../taskbar/inputmethods.h"
+
+
+//----------------------------------------------------------------------------
+
+//-- taken from semctl man page
+#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)
+//-- union semun is defined by including <sys/sem.h>
+#else
+//-- according to X/OPEN we have to define it ourselves
+union semun {
+ int val; // value for SETVAL
+ struct semid_ds *buf; // buffer for IPC_STAT, IPC_SET
+ unsigned short int *array; // array for GETALL, SETALL
+ struct seminfo *__buf; // buffer for IPC_INFO
+};
+#endif
+
+//----------------------------------------------------------------------------
+
+static const int ShowClockFreq = 1;
+
+QDM_SHOWNUSERS;
+
+#ifdef QT_QWS_LOGIN_USEPAM
+
+static const char *_PAM_SERVICE = "xdm";
+static const char *PAM_password;
+
+typedef const struct pam_message pam_message_type;
+
+static int PAM_conv( int, pam_message_type **, struct pam_response **, void * );
+
+static struct pam_conv PAM_conversation = {
+ &PAM_conv,
+ NULL
+};
+
+//----------------------------------------------------------------------------
+
+static char *COPY_STRING( const char * s ) {
+ return (s) ? strdup(s) : (char *)NULL;
+}
+
+#define GET_MEM if (reply) realloc(reply, size);\
+ else reply = (struct pam_response *)malloc(size); \
+ if (!reply) return PAM_CONV_ERR; \
+ size += sizeof(struct pam_response)
+
+
+static int PAM_conv( int num_msg, pam_message_type **msg,
+ struct pam_response **resp, void *)
+{
+ int count = 0, replies = 0;
+ struct pam_response *reply = NULL;
+ int size = sizeof(struct pam_response);
+
+ for( count = 0; count < num_msg; count++ ) {
+ switch (msg[count]->msg_style) {
+ case PAM_PROMPT_ECHO_ON:
+ /* user name given to PAM already */
+ return PAM_CONV_ERR;
+
+ case PAM_PROMPT_ECHO_OFF:
+ /* wants password */
+ GET_MEM;
+ reply[replies].resp_retcode = PAM_SUCCESS;
+ reply[replies].resp = COPY_STRING(PAM_password);
+ replies++;
+ /* PAM frees resp */
+ break;
+ case PAM_TEXT_INFO:
+ break;
+ default:
+ /* unknown or PAM_ERROR_MSG */
+ if (reply) free (reply);
+ return PAM_CONV_ERR;
+ }
+ }
+ if (reply) *resp = reply;
+ return PAM_SUCCESS;
+}
+
+#endif
+
+
+//----------------------------------------------------------------------------
+
+QDMDialogImpl::QDMDialogImpl( QWidget* parent, const char* name, bool modal, WFlags f )
+ : QDMDialog( parent, name, modal, f )
+{
+ showTime();
+ clockTimer = startTimer( ShowClockFreq * 1000 ); //-- call timer evry min.
+ setActiveWindow();
+ setFocus();
+
+ input = new InputMethods( this );
+ input->resize( input->sizeHint() );
+ input->move( 0, height() - input->height() );
+
+ for( int i=0; Shown_Users[i]; ++i ) {
+ input_user->insertItem( Shown_Users[i] );
+ }
+ input_user->clearEdit();
+
+ label_welcome->setText( QDM_WELCOME_STRING );
+
+};
+
+
+
+QDMDialogImpl::~QDMDialogImpl()
+{
+ input->lower();
+ input->close( false );
+ input->hide();
+ delete input;
+ input = 0;
+ if( parent() ) {
+ ((QWidget*)parent())->repaint(true);
+ }
+};
+
+
+void QDMDialogImpl::accept () { };
+void QDMDialogImpl::reject () { };
+
+
+void QDMDialogImpl::showTime( void )
+{
+ label_date->setText( QDate::currentDate().toString() );
+ label_time->setText( QTime::currentTime().toString() );
+}
+
+
+void QDMDialogImpl::timerEvent( QTimerEvent * e )
+{
+ if( e->timerId() == clockTimer )
+ showTime();
+}
+
+
+//----------------------------------------------------------------------------
+
+void QDMDialogImpl::slot_sleepmode()
+{
+ const int button = QMessageBox::warning( this, "Shutdown", tr( "Do you really want to go\nto sleep mode now?" ),
+ QString::null, tr( "Cancel" ), QString::null,0,1 );
+ switch( button ) {
+ case 0:
+ done( Rejected );
+ // Global::execute( cmd_shutdown );
+ if( vfork() == 0 ) {
+ execl( QDM_CMD_SLEEP, 0 );
+ cerr << "Sleepmode: " << strerror( errno ) << endl;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+//----------------------------------------------------------------------------
+
+void QDMDialogImpl::slot_shutdown()
+{
+ const int button = QMessageBox::warning( this, "Shutdown", tr("Do you really want to shut\nthe system down now?"),
+ QString::null, tr("Cancel"), QString::null,0,1 );
+ switch( button ) {
+ case 0:
+ done( Rejected );
+ // Global::execute( cmd_shutdown );
+ if( vfork() == 0 ) {
+ execl( QDM_CMD_SHUTDOWN, 0 );
+ cerr << "Shutdown: " << strerror( errno ) << endl;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+
+
+//----------------------------------------------------------------------------
+
+void QDMDialogImpl::informBadPassword()
+{
+ QMessageBox::warning( this, tr("Password wrong"),
+ tr("The given password is incorrect") );
+}
+
+
+//----------------------------------------------------------------------------
+
+#if defined(QT_QWS_LOGIN_USEPAM)
+
+static bool pwcheck_PAM( const char *user, const char *password )
+{
+ bool pw_correct = false;
+ int pam_error;
+ int pam_return = 0;
+ pam_handle_t *pamh = 0;
+ PAM_password = password.latin1();
+
+ pam_error = pam_start( _PAM_SERVICE, user, &PAM_conversation, &pamh );
+ if( pam_error == PAM_SUCCESS ) {
+ pam_error = pam_authenticate( pamh, 0 );
+ if( pam_error == PAM_SUCCESS ) {
+ //-- password correct
+ pw_correct = true;
+ pam_return = PAM_SUCCESS;
+ } else {
+ pam_return = pam_error;
+ }
+ } else {
+ // cerr << "PAM error: " << pam_strerror( pamh, pam_error ) << endl;
+ }
+ pam_end( pamh, pam_return );
+ return pw_correct;
+}
+
+#else
+
+//----------------------------------------------------------------------------
+
+static bool pwcheck_Unix( const char *user, const char *password )
+{
+ struct passwd * pword = getpwnam( user );
+ if( pword ) {
+ if( strcmp( crypt(password, password), pword->pw_passwd) == 0 ) {
+ return true;
+ }
+ }
+ return false;
+}
+
+#endif
+
+
+
+//----------------------------------------------------------------------------
+
+void QDMDialogImpl::slot_login()
+{
+ bool pw_correct = false;
+ const char *username = input_user->currentText().latin1();
+ const char *password = input_password->text().latin1();
+
+ assert( username );
+
+#if defined(QT_QWS_LOGIN_USEPAM)
+ pw_correct = pwcheck_PAM( username, password );
+#else
+ pw_correct = pwcheck_Unix( username, password );
+#endif
+
+ if( pw_correct ) {
+ if( changePersona( username ) ) {
+ // cerr << "Password correct" << endl;
+ done( Accepted );
+ return;
+ }
+ } else {
+ // cerr << "Password incorrect" << endl;
+ }
+ informBadPassword();
+}
+
+
+//----------------------------------------------------------------------------
+
+bool QDMDialogImpl::changePersona( const char *username )
+{
+ int err;
+
+ //-- get some info on user <username>
+ struct passwd * pword;
+ pword = getpwnam( username );
+
+ if( pword == 0 )
+ return false;
+
+ gid_t gid = pword->pw_gid;
+ uid_t uid = pword->pw_uid;
+
+ //-- some very dirty hacks following
+ // extern int qws_display_id;
+ extern QString qws_qtePipeFilename();
+ extern QString qws_dataDir();
+
+
+ const QString QTEdataDir = qws_dataDir();
+ QString QTEdataDirNew = QTEdataDir;
+ QTEdataDirNew.replace( QRegExp("root"), username );
+
+ const char *qws_display_str = getenv("QWS_DISPLAY");
+
+ //-- get name of semaphore and lock
+ QString pipe = qws_qtePipeFilename();
+
+ //-- change owner of semaphore
+ key_t semkey = ftok( pipe.latin1(), 'd' );
+ int semid = semget( semkey, 0, 0 );
+ if( semid < 0 )
+ cerr << "error: semget, " << strerror( errno ) << endl;
+
+ struct shmid_ds shminfo;
+ semun arg;
+ semid_ds semidds;
+ arg.buf = & semidds;
+
+ if( semctl( semid, 0, IPC_STAT, arg ) < 0 )
+ cerr << "error: semctl stat, " << strerror( errno ) << endl;
+
+ arg.buf->sem_perm.uid = uid;
+ arg.buf->sem_perm.gid = gid;
+
+ if( semctl( semid, 0, IPC_SET, arg ) < 0 )
+ cerr << "error: semctl set, " << strerror( errno ) << endl;
+
+ //-- change owner of shared memory
+ key_t memkey = ftok( pipe.latin1(), 'm' );
+ int ramid = shmget( memkey, 0, 0 );
+ if( ramid < 0 ) cerr << "error: shmget, " << strerror( errno ) << endl;
+
+ if( shmctl( ramid, IPC_STAT, &shminfo ) < 0 )
+ cerr << "error: shmctl stat, " << strerror( errno ) << endl;
+
+ shminfo.shm_perm.uid = uid;
+ shminfo.shm_perm.gid = gid;
+
+ if( shmctl( ramid, IPC_SET, &shminfo ) < 0 )
+ cerr << "error: shmctl set, " << strerror( errno ) << endl;
+
+ //-- change owner of region manager
+ memkey = ftok( pipe.latin1(), 'r' );
+ int regionid = shmget( memkey, 0, 0 );
+ if( regionid < 0 )
+ cerr << "error: shmget, " << strerror( errno ) << endl;
+
+ if( shmctl( regionid, IPC_STAT, &shminfo ) < 0 )
+ cerr << "error: shmctl stat, " << strerror( errno ) << endl;
+
+ shminfo.shm_perm.uid = uid;
+ shminfo.shm_perm.gid = gid;
+
+ if( shmctl( regionid, IPC_SET, &shminfo ) < 0 )
+ cerr << "error: shmctl set, " << strerror( errno ) << endl;
+
+ // cerr << "ungrabbing qws display: " << qws_display_id << " on lock " << pipe << endl;
+ // QWSDisplay::ungrab();
+
+ //-- presenting socket-file to new user
+ chown( pipe.latin1(), uid, gid );
+ chown( QTEdataDir.latin1(), uid, gid );
+
+
+ //-- another dirty hack - force framebuffer to be writeable...
+ struct stat devstat;
+ if( ! stat( "/dev/fb0", &devstat ) ) {
+ if( chmod( "/dev/fb0", devstat.st_mode |S_IWOTH |S_IWUSR |S_IWGRP ) ) {
+ cerr << "chmod error: " << strerror( errno ) << endl;
+ }
+ }
+
+ err = rename( QTEdataDir, QTEdataDirNew ) ;
+ if( err < 0 ) cerr << "error: rename " << strerror(errno)
+ << " , " << QTEdataDir << " -> " << QTEdataDirNew << endl;
+
+ //
+ //-- actually change uid and gid
+ //
+ // cerr << "changing persona, uid: " << uid << " gid: " << gid << endl;
+
+ err = setgid( gid );
+ if( err != 0 ) cerr << "error: gid changePersona " << err << endl;
+
+ err = setuid( uid );
+ if( err != 0 ) cerr << "error: uid changePersona " << err << endl;
+
+
+ //-- set some environment
+ setenv( "QWS_DISPLAY", qws_display_str, true );
+ setenv( "LOGNAME", username, true );
+ setenv( "USER", username, true );
+ setenv( "HOME", pword->pw_dir, true );
+
+ // cout << "QTE data dir: " << qws_dataDir() << endl;
+
+ //-- I am reborn
+
+ return true;
+}
+
+
+
+//----------------------------------------------------------------------------
+
+bool QDMDialogImpl::login( QWidget *parent )
+{
+ //-- only when called as 'root' do login-box
+ if( getuid() != 0 )
+ return true;
+
+
+ //-- are we coming from a 'restart' ?
+ if( getenv("QDM_STARTED") )
+ return true;
+ else
+ unsetenv("QDM_STARTED");
+
+
+#ifndef QT_NO_TRANSLATION
+ QString lang = getenv( "LANG" );
+
+ QTranslator * trans = new QTranslator(qApp);
+ QString tfn = QPEApplication::qpeDir()+"/i18n/"+lang+"/login.qm";
+ if ( trans->load( tfn ))
+ qApp->installTranslator( trans );
+ else {
+ delete trans;
+ trans = 0;
+ }
+#endif
+
+ if( parent ) parent->erase();
+
+ QDMDialog *dialog = new QDMDialogImpl( parent, "Login", true //);
+ ,WStyle_NoBorder | WStyle_Customize );
+
+#if QT_VERSION >= 300
+ Q_CHECK_PTR( dialog );
+#else
+ CHECK_PTR( dialog );
+#endif
+ int result = dialog->exec();
+ delete dialog;
+
+ if( parent ) parent->erase();
+
+#ifndef QT_NO_TRANSLATION
+ if( trans ) {
+ qApp->removeTranslator( trans );
+ delete trans;
+ trans = 0;
+ }
+#endif
+
+ setenv( "QDM_STARTED", "", true );
+
+ // if( parent ) parent->erase();
+
+ //-- get all configs going
+ Global::restart();
+
+ return result;
+}
+
+
+#endif //-- QT_QWS_LOGIN
diff --git a/core/opie-login/qdmdialogimpl.h b/core/opie-login/qdmdialogimpl.h
new file mode 100644
index 0000000..d62695b
--- a/dev/null
+++ b/core/opie-login/qdmdialogimpl.h
@@ -0,0 +1,90 @@
+//-- -*- c++ -*-
+/**********************************************************************
+** Copyright (C) 2001 LISA Systems
+**
+** This file is an additional part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** For further information contact info@lisa.de
+**
+**********************************************************************/
+
+/*
+ * AUTHOR: Christian Rahn
+ * EMAIL: cdr@lisa.de
+ *
+ * $Id$
+ */
+
+#ifndef _QDM_IMPL_H
+#define _QDM_IMPL_H
+
+#include "qdm_config.h"
+
+#if defined(QT_QWS_LOGIN)
+
+#include "qdmdialog.h"
+
+class InputMethods;
+
+class QDMDialogImpl : public QDMDialog
+{
+ Q_OBJECT
+
+ public:
+ /** Pop up login dialog and do all stuff */
+ static bool login( QWidget * parent = 0 );
+
+ protected:
+ /** a protected constructor */
+ QDMDialogImpl( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags f = 0 );
+ ~QDMDialogImpl();
+
+ /** Timer for clock display */
+ void timerEvent( QTimerEvent * );
+
+ /** The Timer for the clock */
+ int clockTimer;
+
+ /** Conersation function for PAM */
+ // int PAM_conv (int num_msg, pam_message_type **msg, struct pam_response **resp, void *);
+
+ /** Just become (i.e. log in as) user <name> */
+ bool changePersona( const char *name );
+
+ /** Inform about an incorrect given password */
+ void informBadPassword();
+
+private:
+ InputMethods *input;
+
+ protected slots:
+ /** These got to be overridden so that the login dialog can't be circumvented */
+ virtual void accept ();
+ virtual void reject ();
+
+public slots:
+ /** Display the atual time and date */
+ void showTime( void );
+
+ /** login button pressed */
+ virtual void slot_login();
+
+ /** Shutdown button pressed */
+ virtual void slot_shutdown();
+
+ /** Sleep button pressed */
+ virtual void slot_sleepmode();
+};
+
+#endif //-- QT_QWS_LOGIN
+
+#endif //-- _QDM_IMPL_H
+
diff --git a/core/pim/addressbook/.cvsignore b/core/pim/addressbook/.cvsignore
new file mode 100644
index 0000000..28d87f2
--- a/dev/null
+++ b/core/pim/addressbook/.cvsignore
@@ -0,0 +1,16 @@
+moc_*
+Makefile
+abeditorbase.h
+abaddress.h
+abcompanybase.h
+abnamebase.h
+abeditorbase.cpp
+abaddress.cpp
+abcompanybase.cpp
+abnamebase.cpp
+abeditorpage2base.ui
+abeditorpage2base.h
+abeditorpage2base.cpp
+addresssettingsbase.h
+addresssettingsbase.cpp
+
diff --git a/core/pim/addressbook/Makefile.in b/core/pim/addressbook/Makefile.in
new file mode 100644
index 0000000..93c73c3
--- a/dev/null
+++ b/core/pim/addressbook/Makefile.in
@@ -0,0 +1,244 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = addressbook
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = addressbook.h \
+ abeditor.h \
+ ablabel.h \
+ abtable.h \
+ addresssettings.h
+SOURCES = main.cpp \
+ addressbook.cpp \
+ abeditor.cpp \
+ ablabel.cpp \
+ abtable.cpp \
+ addresssettings.cpp
+OBJECTS = main.o \
+ addressbook.o \
+ abeditor.o \
+ ablabel.o \
+ abtable.o \
+ addresssettings.o \
+ addresssettingsbase.o
+INTERFACES = addresssettingsbase.ui
+UICDECLS = addresssettingsbase.h
+UICIMPLS = addresssettingsbase.cpp
+SRCMOC = moc_addressbook.cpp \
+ moc_abeditor.cpp \
+ moc_ablabel.cpp \
+ moc_abtable.cpp \
+ moc_addresssettings.cpp \
+ moc_addresssettingsbase.cpp
+OBJMOC = moc_addressbook.o \
+ moc_abeditor.o \
+ moc_ablabel.o \
+ moc_abtable.o \
+ moc_addresssettings.o \
+ moc_addresssettingsbase.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake p4addressbook.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ addressbook.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h
+
+addressbook.o: addressbook.cpp \
+ abeditor.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h \
+ ablabel.h \
+ abtable.h \
+ $(QPEDIR)/include/qpe/categories.h \
+ addresssettings.h \
+ addresssettingsbase.h \
+ addressbook.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/finddialog.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/ir.h \
+ $(QPEDIR)/include/qpe/qpemessagebox.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+abeditor.o: abeditor.cpp \
+ abeditor.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h \
+ addresspicker.h \
+ $(QPEDIR)/include/qpe/categoryselect.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/qpedialog.h
+
+ablabel.o: ablabel.cpp \
+ ablabel.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h \
+ $(QPEDIR)/include/qpe/stringutil.h
+
+abtable.o: abtable.cpp \
+ $(QPEDIR)/include/qpe/categoryselect.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/stringutil.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h \
+ abtable.h \
+ $(QPEDIR)/include/qpe/categories.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h
+
+addresssettings.o: addresssettings.cpp \
+ addresssettings.h \
+ addresssettingsbase.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h
+
+addresssettingsbase.h: addresssettingsbase.ui
+ $(UIC) addresssettingsbase.ui -o $(INTERFACE_DECL_PATH)/addresssettingsbase.h
+
+addresssettingsbase.cpp: addresssettingsbase.ui
+ $(UIC) addresssettingsbase.ui -i addresssettingsbase.h -o addresssettingsbase.cpp
+
+addresssettingsbase.o: addresssettingsbase.cpp \
+ addresssettingsbase.h \
+ addresssettingsbase.ui
+
+moc_addressbook.o: moc_addressbook.cpp \
+ addressbook.h
+
+moc_abeditor.o: moc_abeditor.cpp \
+ abeditor.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h
+
+moc_ablabel.o: moc_ablabel.cpp \
+ ablabel.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h
+
+moc_abtable.o: moc_abtable.cpp \
+ abtable.h \
+ $(QPEDIR)/include/qpe/categories.h \
+ $(QPEDIR)/include/qpe/contact.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/recordfields.h
+
+moc_addresssettings.o: moc_addresssettings.cpp \
+ addresssettings.h \
+ addresssettingsbase.h
+
+moc_addresssettingsbase.o: moc_addresssettingsbase.cpp \
+ addresssettingsbase.h
+
+moc_addressbook.cpp: addressbook.h
+ $(MOC) addressbook.h -o moc_addressbook.cpp
+
+moc_abeditor.cpp: abeditor.h
+ $(MOC) abeditor.h -o moc_abeditor.cpp
+
+moc_ablabel.cpp: ablabel.h
+ $(MOC) ablabel.h -o moc_ablabel.cpp
+
+moc_abtable.cpp: abtable.h
+ $(MOC) abtable.h -o moc_abtable.cpp
+
+moc_addresssettings.cpp: addresssettings.h
+ $(MOC) addresssettings.h -o moc_addresssettings.cpp
+
+moc_addresssettingsbase.cpp: addresssettingsbase.h
+ $(MOC) addresssettingsbase.h -o moc_addresssettingsbase.cpp
+
+
diff --git a/core/pim/addressbook/abeditor.cpp b/core/pim/addressbook/abeditor.cpp
new file mode 100644
index 0000000..6354db9
--- a/dev/null
+++ b/core/pim/addressbook/abeditor.cpp
@@ -0,0 +1,619 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "abeditor.h"
+#include "addresspicker.h"
+
+#include <qpe/categoryselect.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/qpedialog.h>
+
+#include <qcombobox.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qmultilineedit.h>
+#include <qscrollview.h>
+#include <qtoolbutton.h>
+#include <qpushbutton.h>
+#include <qmainwindow.h>
+
+
+static inline bool containsAlphaNum( const QString &str );
+static inline bool constainsWhiteSpace( const QString &str );
+
+
+// helper functions, convert our comma delimited list to proper
+// file format...
+void parseEmailFrom( const QString &txt, QString &strDefaultEmail,
+ QString &strAll );
+
+// helper convert from file format to comma delimited...
+void parseEmailTo( const QString &strDefaultEmail,
+ const QString &strOtherEmail, QString &strBack );
+
+
+
+AbEditor::AbEditor( const Contact &entry, const QValueList<int> *newOrdered,
+ QStringList *slNewOrdered,
+ QWidget *parent = 0, const char *name = 0, WFlags fl = 0 )
+ : QDialog( parent, name, TRUE, fl ),
+ orderedValues( newOrdered ),
+ slOrdered( slNewOrdered )
+{
+ init();
+ initMap();
+ setEntry( entry );
+}
+
+AbEditor::~AbEditor()
+{
+}
+
+void AbEditor::init()
+{
+ middleEdit = 0;
+ QVBoxLayout *vb = new QVBoxLayout( this );
+ svPage = new QScrollView( this );
+ svPage->setHScrollBarMode( QScrollView::AlwaysOff );
+ vb->addWidget( svPage );
+ svPage->setResizePolicy( QScrollView::AutoOneFit );
+ svPage->setFrameStyle( QFrame::NoFrame );
+
+ QWidget *container = new QWidget( svPage->viewport() );
+ svPage->addChild( container );
+
+ QGridLayout *gl = new QGridLayout( container, 20, 2, 4, 2 );
+
+ QLabel *l = new QLabel( tr("First Name"), container );
+ gl->addWidget( l, 0, 0 );
+ firstEdit = new QLineEdit( container );
+ gl->addWidget( firstEdit, 0, 1 );
+
+ l = new QLabel( tr("Last Name"), container );
+ gl->addWidget( l, 1, 0 );
+ lastEdit = new QLineEdit( container );
+ gl->addWidget( lastEdit, 1, 1 );
+
+ l = new QLabel( tr("Categories"), container );
+ gl->addWidget( l, 2, 0 );
+
+ cmbCat = new CategorySelect( container );
+ gl->addWidget( cmbCat, 2, 1 );
+
+ int i;
+ bool foundGender,
+ foundNotes;
+ foundGender = foundNotes = false;
+ QStringList::ConstIterator it = slOrdered->begin();
+ for ( i = 0; it != slOrdered->end(); i++, ++it ) {
+ if ( !foundGender && *it == tr("Gender") ) {
+ foundGender = true;
+ } else if ( !foundNotes && *it == tr("Notes") ) {
+ foundNotes = true;
+ } else {
+ l = new QLabel( *it, container );
+ listName.append( l );
+ gl->addWidget( l, i + 3, 0 );
+ QLineEdit *e = new QLineEdit( container );
+ listValue.append( e );
+ gl->addWidget( e, i + 3, 1 );
+ if ( *it == tr( "Middle Name" ) )
+ middleEdit = e;
+ }
+ }
+ l = new QLabel( tr("Gender"), container );
+ gl->addWidget( l, slOrdered->count() + 3, 0 );
+ genderCombo = new QComboBox( container );
+ genderCombo->insertItem( "", 0 );
+ genderCombo->insertItem( tr( "Male" ), 1 );
+ genderCombo->insertItem( tr( "Female" ), 2 );
+ gl->addWidget( genderCombo, slOrdered->count() + 3, 1 );
+
+ dlgNote = new QDialog( this, "Note Dialog", TRUE );
+ dlgNote->setCaption( tr("Enter Note") );
+ QVBoxLayout *vbNote = new QVBoxLayout( dlgNote );
+ // lblNote = new QLabel( dlgNote );
+ // lblNote->setMinimumSize( lblNote->sizeHint() + QSize( 0, 4 ) );
+ // vbNote->addWidget( lblNote );
+ txtNote = new QMultiLineEdit( dlgNote );
+ vbNote->addWidget( txtNote );
+
+ QHBoxLayout *hb = new QHBoxLayout( vb );
+ hb->addStretch( 2 );
+ QPushButton *pb = new QPushButton( tr("Notes..."), this );
+ hb->addWidget( pb );
+ connect( pb, SIGNAL(clicked()), this, SLOT(slotNote()) );
+
+ new QPEDialogListener(this);
+}
+
+void AbEditor::initMap()
+{
+ /*
+ // since the fields and the XML fields exist, create a map
+ // between them...
+ Config cfg1( "AddressBook" );
+ Config cfg2( "AddressBook" );
+ QString strCfg1,
+ strCfg2;
+ int i;
+
+ // This stuff better exist...
+ cfg1.setGroup( "AddressFields" );
+ cfg2.setGroup( "XMLFields" );
+ i = 0;
+ strCfg1 = cfg1.readEntry( "Field" + QString::number(i), QString::null );
+ strCfg2 = cfg2.readEntry( "XMLField" + QString::number(i++),
+ QString::null );
+ while ( !strCfg1.isNull() && !strCfg2.isNull() ) {
+ mapField.insert( strCfg1, strCfg2 );
+ strCfg1 = cfg1.readEntry( "Field" + QString::number(i),
+ QString::null );
+ strCfg2 = cfg2.readEntry( "XMLField" + QString::number(i++),
+ QString::null );
+ }
+ */
+}
+
+void AbEditor::loadFields()
+{
+ QStringList::ConstIterator it;
+ QListIterator<QLabel> lit( listName );
+ for ( it = slOrdered->begin(); *lit; ++lit, ++it ) {
+ (*lit)->setText( *it );
+ }
+}
+
+void AbEditor::setEntry( const Contact &entry )
+{
+ ent = entry;
+ QListIterator<QLineEdit> it( listValue );
+ firstEdit->setText( ent.firstName() );
+ lastEdit->setText( ent.lastName() );
+ cmbCat->setCategories( ent.categories(), "Contacts", tr("Contacts") );
+
+ // ### Fix...
+ QValueList<int>::ConstIterator itVl;
+ for ( itVl = orderedValues->begin(); *it && itVl != orderedValues->end();
+ ++itVl, ++it ) {
+ switch( *itVl ) {
+ case Qtopia::Title:
+ (*it)->setText(ent.title());
+ break;
+ case Qtopia::MiddleName:
+ (*it)->setText( ent.middleName() );
+ break;
+ case Qtopia::Suffix:
+ (*it)->setText( ent.suffix() );
+ break;
+
+ // email
+ case Qtopia::DefaultEmail:
+ case Qtopia::Emails:
+ {
+ QString strDefEmail = ent.defaultEmail();
+ QString strAllEmail = ent.emails();
+ QString strFinal;
+ parseEmailTo( strDefEmail, strAllEmail, strFinal );
+ (*it)->setText( strFinal );
+ // make sure we see the "default"
+ (*it)->home( false );
+ break;
+ }
+
+ // home
+ case Qtopia::HomeStreet:
+ (*it)->setText(ent.homeStreet() );
+ break;
+ case Qtopia::HomeCity:
+ (*it)->setText( ent.homeCity() );
+ break;
+ case Qtopia::HomeState:
+ (*it)->setText( ent.homeState() );
+ break;
+ case Qtopia::HomeZip:
+ (*it)->setText( ent.homeZip() );
+ break;
+ case Qtopia::HomeCountry:
+ (*it)->setText( ent.homeCountry() );
+ break;
+ case Qtopia::HomePhone:
+ (*it)->setText( ent.homePhone() );
+ break;
+ case Qtopia::HomeFax:
+ (*it)->setText( ent.homeFax() );
+ break;
+ case Qtopia::HomeMobile:
+ (*it)->setText( ent.homeMobile() );
+ break;
+ case Qtopia::HomeWebPage:
+ (*it)->setText( ent.homeWebpage() );
+ break;
+
+ // business
+ case Qtopia::Company:
+ (*it)->setText( ent.company() );
+ break;
+ case Qtopia::BusinessStreet:
+ (*it)->setText( ent.businessStreet() );
+ break;
+ case Qtopia::BusinessCity:
+ (*it)->setText( ent.businessCity() );
+ break;
+ case Qtopia::BusinessState:
+ (*it)->setText( ent.businessState() );
+ break;
+ case Qtopia::BusinessZip:
+ (*it)->setText( ent.businessZip() );
+ break;
+ case Qtopia::BusinessCountry:
+ (*it)->setText( ent.businessCountry() );
+ break;
+ case Qtopia::BusinessWebPage:
+ (*it)->setText( ent.businessWebpage() );
+ break;
+ case Qtopia::JobTitle:
+ (*it)->setText( ent.jobTitle() );
+ break;
+ case Qtopia::Department:
+ (*it)->setText( ent.department() );
+ break;
+ case Qtopia::Office:
+ (*it)->setText( ent.office() );
+ break;
+ case Qtopia::BusinessPhone:
+ (*it)->setText( ent.businessPhone() );
+ break;
+ case Qtopia::BusinessFax:
+ (*it)->setText( ent.businessFax() );
+ break;
+ case Qtopia::BusinessMobile:
+ (*it)->setText( ent.businessMobile() );
+ break;
+ case Qtopia::BusinessPager:
+ (*it)->setText( ent.businessPager() );
+ break;
+ case Qtopia::Profession:
+ (*it)->setText( ent.profession() );
+ break;
+ case Qtopia::Assistant:
+ (*it)->setText( ent.assistant() );
+ break;
+ case Qtopia::Manager:
+ (*it)->setText( ent.manager() );
+ break;
+
+ // personal
+ case Qtopia::Spouse:
+ (*it)->setText( ent.spouse() );
+ break;
+ case Qtopia::Children:
+ (*it)->setText( ent.children() );
+ break;
+ case Qtopia::Birthday:
+ (*it)->setText( ent.birthday() );
+ break;
+ case Qtopia::Anniversary:
+ (*it)->setText( ent.anniversary() );
+ break;
+ case Qtopia::Nickname:
+ (*it)->setText( ent.nickname() );
+ break;
+
+ }
+ }
+
+ QString gender = ent.gender();
+ genderCombo->setCurrentItem( gender.toInt() );
+
+ txtNote->setText( ent.notes() );
+}
+
+void AbEditor::accept()
+{
+ if ( isEmpty() )
+ reject();
+ else {
+ saveEntry();
+ QDialog::accept();
+ }
+}
+
+bool AbEditor::isEmpty()
+{
+ // analyze all the fields and make sure there is _something_ there
+ // that warrants saving...
+ QString t = firstEdit->text();
+ if ( !t.isEmpty() && containsAlphaNum( t ) )
+ return false;
+
+ t = lastEdit->text();
+ if ( !t.isEmpty() && containsAlphaNum( t ) )
+ return false;
+
+ QListIterator<QLineEdit> it( listValue );
+ for ( ; it.current(); ++it ) {
+ t = it.current()->text();
+ if ( !t.isEmpty() && containsAlphaNum( t ) )
+ return false;
+ }
+
+ t = txtNote->text();
+ if ( !t.isEmpty() && containsAlphaNum( t ) )
+ return false;
+
+ return true;
+}
+
+void AbEditor::saveEntry()
+{
+ QString strDefaultEmail, strOtherEmail;
+
+ // determine if there has been a change in names
+ if ( ent.firstName() != firstEdit->text() ||
+ ent.lastName() != lastEdit->text()
+ || (middleEdit && ent.middleName() != middleEdit->text()) ) {
+ // set the names
+ ent.setFirstName( firstEdit->text() );
+ ent.setLastName( lastEdit->text() );
+ if ( middleEdit )
+ ent.setMiddleName( middleEdit->text() );
+ ent.setFileAs();
+ }
+
+ ent.setCategories( cmbCat->currentCategories() );
+
+ QListIterator<QLineEdit> it( listValue );
+ int i;
+ QValueList<int>::ConstIterator<int> vlIt;
+ for ( i = 0, vlIt = orderedValues->begin();
+ it.current(); ++it, ++vlIt, i++ ) {
+ switch( *vlIt ) {
+ case Qtopia::Title:
+ ent.setTitle( it.current()->text() );
+ break;
+ case Qtopia::MiddleName:
+ ent.setMiddleName( it.current()->text() );
+ break;
+ case Qtopia::Suffix:
+ ent.setSuffix( it.current()->text() );
+ break;
+// case Qtopia::Category:
+// {
+// // QStringList slCat = QStringList::split( ";", value );
+// // QValueList<int> cat;
+// // for ( QStringList::ConstIterator it = slCat.begin();
+// // it != slCat.end(); ++it )
+// // cat.append( (*it).toInt() );
+// // ent.setCategories( cat );
+// }
+// break;
+
+ // email
+ case Qtopia::DefaultEmail:
+ case Qtopia::Emails:
+ parseEmailFrom( it.current()->text(), strDefaultEmail,
+ strOtherEmail );
+ ent.setDefaultEmail( strDefaultEmail );
+ ent.setEmails( strOtherEmail );
+ break;
+
+ // home
+ case Qtopia::HomeStreet:
+ ent.setHomeStreet( it.current()->text() );
+ break;
+ case Qtopia::HomeCity:
+ ent.setHomeCity( it.current()->text() );
+ break;
+ case Qtopia::HomeState:
+ ent.setHomeState( it.current()->text() );
+ break;
+ case Qtopia::HomeZip:
+ ent.setHomeZip( it.current()->text() );
+ break;
+ case Qtopia::HomeCountry:
+ ent.setHomeCountry( it.current()->text() );
+ break;
+ case Qtopia::HomePhone:
+ ent.setHomePhone( it.current()->text() );
+ break;
+ case Qtopia::HomeFax:
+ ent.setHomeFax( it.current()->text() );
+ break;
+ case Qtopia::HomeMobile:
+ ent.setHomeMobile( it.current()->text() );
+ break;
+ case Qtopia::HomeWebPage:
+ ent.setHomeWebpage( it.current()->text() );
+ break;
+
+ // business
+ case Qtopia::Company:
+ ent.setCompany( it.current()->text() );
+ break;
+ case Qtopia::BusinessStreet:
+ ent.setBusinessStreet( it.current()->text() );
+ break;
+ case Qtopia::BusinessCity:
+ ent.setBusinessCity( it.current()->text() );
+ break;
+ case Qtopia::BusinessState:
+ ent.setBusinessState( it.current()->text() );
+ break;
+ case Qtopia::BusinessZip:
+ ent.setBusinessZip( it.current()->text() );
+ break;
+ case Qtopia::BusinessCountry:
+ ent.setBusinessCountry( it.current()->text() );
+ break;
+ case Qtopia::BusinessWebPage:
+ ent.setBusinessWebpage( it.current()->text() );
+ break;
+ case Qtopia::JobTitle:
+ ent.setJobTitle( it.current()->text() );
+ break;
+ case Qtopia::Department:
+ ent.setDepartment( it.current()->text() );
+ break;
+ case Qtopia::Office:
+ ent.setOffice( it.current()->text() );
+ break;
+ case Qtopia::BusinessPhone:
+ ent.setBusinessPhone( it.current()->text() );
+ break;
+ case Qtopia::BusinessFax:
+ ent.setBusinessFax( it.current()->text() );
+ break;
+ case Qtopia::BusinessMobile:
+ ent.setBusinessMobile( it.current()->text() );
+ break;
+ case Qtopia::BusinessPager:
+ ent.setBusinessPager( it.current()->text() );
+ break;
+ case Qtopia::Profession:
+ ent.setProfession( it.current()->text() );
+ break;
+ case Qtopia::Assistant:
+ ent.setAssistant( it.current()->text() );
+ break;
+ case Qtopia::Manager:
+ ent.setManager( it.current()->text() );
+ break;
+
+ // personal
+ case Qtopia::Spouse:
+ ent.setSpouse( it.current()->text() );
+ break;
+ case Qtopia::Children:
+ ent.setChildren( it.current()->text() );
+ break;
+ case Qtopia::Birthday:
+ ent.setBirthday( it.current()->text() );
+ break;
+ case Qtopia::Anniversary:
+ ent.setAnniversary( it.current()->text() );
+ break;
+ case Qtopia::Nickname:
+ ent.setNickname( it.current()->text() );
+ break;
+ default:
+ break;
+
+ }
+ }
+
+ int gender = genderCombo->currentItem();
+ ent.setGender( QString::number( gender ) );
+
+ QString str = txtNote->text();
+ if ( !str.isNull() )
+ ent.setNotes( str );
+}
+
+void AbEditor::slotNote()
+{
+ dlgNote->showMaximized();
+ if ( !dlgNote->exec() ) {
+ // reset the note...
+ txtNote->setText( ent.notes() );
+ }
+}
+
+void AbEditor::setNameFocus()
+{
+ firstEdit->setFocus();
+}
+
+void parseEmailFrom( const QString &txt, QString &strDefaultEmail,
+ QString &strAll )
+{
+ int where,
+ start;
+ if ( txt.isEmpty() )
+ return;
+ // find the first
+ where = txt.find( ',' );
+ if ( where < 0 ) {
+ strDefaultEmail = txt;
+ strAll = txt;
+ } else {
+ strDefaultEmail = txt.left( where ).stripWhiteSpace();
+ strAll = strDefaultEmail;
+ while ( where > -1 ) {
+ strAll.append(" ");
+ start = where;
+ where = txt.find( ',', where + 1 );
+ if ( where > - 1 )
+ strAll.append( txt.mid(start + 1, where - start - 1).stripWhiteSpace() );
+ else // grab until the end...
+ strAll.append( txt.right(txt.length() - start - 1).stripWhiteSpace() );
+ }
+ }
+}
+
+void parseEmailTo( const QString &strDefaultEmail,
+ const QString &strOtherEmail, QString &strBack )
+{
+ // create a comma dilimeted set of emails...
+ // use the power of short circuiting...
+ bool foundDefault = false;
+ QString strTmp;
+ int start = 0;
+ int where;
+ // start at the beginng.
+ strBack = strDefaultEmail;
+ where = 0;
+ while ( where > -1 ) {
+ start = where;
+ where = strOtherEmail.find( ' ', where + 1 );
+ if ( where > 0 ) {
+ strTmp = strOtherEmail.mid( start, where - start ).stripWhiteSpace();
+ } else
+ strTmp = strOtherEmail.right( strOtherEmail.length() - start ).stripWhiteSpace();
+ if ( foundDefault || strTmp != strDefaultEmail ) {
+ strBack.append( ", " );
+ strBack.append( strTmp );
+ } else
+ foundDefault = true;
+ }
+}
+
+
+static inline bool containsAlphaNum( const QString &str )
+{
+ int i,
+ count = str.length();
+ for ( i = 0; i < count; i++ )
+ if ( !str[i].isSpace() )
+ return TRUE;
+ return FALSE;
+}
+
+static inline bool constainsWhiteSpace( const QString &str )
+{
+ int i,
+ count = str.length();
+ for (i = 0; i < count; i++ )
+ if ( str[i].isSpace() )
+ return TRUE;
+ return FALSE;
+}
+
diff --git a/core/pim/addressbook/abeditor.h b/core/pim/addressbook/abeditor.h
new file mode 100644
index 0000000..9ce6704
--- a/dev/null
+++ b/core/pim/addressbook/abeditor.h
@@ -0,0 +1,79 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef ABEDITOR_H
+#define ABEDITOR_H
+
+#include <qpe/contact.h>
+
+#include <qdialog.h>
+#include <qlist.h>
+#include <qmap.h>
+#include <qstringlist.h>
+
+class QScrollView;
+class QMultiLineEdit;
+class QLineEdit;
+class QLabel;
+class QComboBox;
+class CategorySelect;
+
+class AbEditor : public QDialog
+{
+ Q_OBJECT
+public:
+ AbEditor( const Contact &entry, const QValueList<int> *newOrdedValues,
+ QStringList *slNewOrdered,
+ QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~AbEditor();
+ void loadFields();
+ void setNameFocus();
+ Contact entry() const { return ent; }
+
+public slots:
+ void slotNote();
+ void setEntry( const Contact &entry );
+
+protected slots:
+ void accept();
+
+private:
+ void init();
+ void initMap();
+ void saveEntry();
+ bool isEmpty();
+
+private:
+ QDialog *dlgNote;
+ QLabel *lblNote;
+ QMultiLineEdit *txtNote;
+ Contact ent;
+ QScrollView *svPage;
+ QLineEdit *firstEdit;
+ QLineEdit *lastEdit;
+ QLineEdit *middleEdit;
+ QComboBox *genderCombo;
+ QList<QLineEdit> listValue;
+ QList<QLabel> listName;
+ const QValueList<int> *orderedValues;
+ QStringList *slOrdered;
+ CategorySelect *cmbCat;
+};
+
+#endif
diff --git a/core/pim/addressbook/ablabel.cpp b/core/pim/addressbook/ablabel.cpp
new file mode 100644
index 0000000..3bf3e12
--- a/dev/null
+++ b/core/pim/addressbook/ablabel.cpp
@@ -0,0 +1,53 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "ablabel.h"
+
+#include <qpe/stringutil.h>
+
+#include <qregexp.h>
+#include <qstylesheet.h>
+
+AbLabel::AbLabel( QWidget *parent, const char *name )
+ : QTextView( parent, name )
+{
+}
+
+AbLabel::~AbLabel()
+{
+}
+
+void AbLabel::init( const Contact &entry )
+{
+ ent = entry;
+}
+
+void AbLabel::sync()
+{
+ QString text = ent.toRichText();
+ setText( text );
+}
+
+void AbLabel::keyPressEvent( QKeyEvent *e )
+{
+ if ( e->key() == Qt::Key_F33 ) {
+ emit okPressed();
+ }
+}
diff --git a/core/pim/addressbook/ablabel.h b/core/pim/addressbook/ablabel.h
new file mode 100644
index 0000000..cfbd999
--- a/dev/null
+++ b/core/pim/addressbook/ablabel.h
@@ -0,0 +1,50 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef ABLABEL_H
+#define ABLABEL_H
+
+#include <qpe/contact.h>
+#include <qtextview.h>
+
+class AbLabel : public QTextView
+{
+ Q_OBJECT
+
+public:
+ AbLabel( QWidget *parent, const char *name = 0 );
+ ~AbLabel();
+
+public slots:
+ void init( const Contact &entry );
+ void sync();
+
+signals:
+ void okPressed();
+
+protected:
+ void keyPressEvent( QKeyEvent * );
+
+private:
+ Contact ent;
+
+};
+
+#endif // ABLABEL_H
+
diff --git a/core/pim/addressbook/abtable.cpp b/core/pim/addressbook/abtable.cpp
new file mode 100644
index 0000000..0911edf
--- a/dev/null
+++ b/core/pim/addressbook/abtable.cpp
@@ -0,0 +1,1091 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpe/categoryselect.h>
+#include <qpe/config.h>
+#include <qpe/stringutil.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#include <qasciidict.h>
+#include <qdatetime.h>
+#include <qfile.h>
+
+#include "abtable.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <ctype.h> //toupper() for key hack
+
+static bool contactCompare( const Contact &cnt, const QRegExp &r, int category );
+
+//### qtmail/addresslist.cpp hardcodes this filename as well
+static QString journalFileName()
+{
+ QString str = getenv("HOME");
+ str +="/.abjournal";
+ return str;
+}
+
+
+
+/*!
+ \class AbTableItem abtable.h
+
+ \brief QTableItem based class for showing a field of an entry
+*/
+
+AbTableItem::AbTableItem( QTable *t, EditType et, const QString &s,
+ const QString &secondSortKey)
+ : QTableItem( t, et, s )
+{
+ // sortKey = s.lower() + QChar( '\0' ) + secondSortKey.lower();
+ sortKey = Qtopia::buildSortKey( s, secondSortKey );
+}
+
+int AbTableItem::alignment() const
+{
+ return AlignLeft|AlignVCenter;
+}
+
+QString AbTableItem::key() const
+{
+ return sortKey;
+}
+
+// A way to reset the item, without out doing a delete or a new...
+void AbTableItem::setItem( const QString &txt, const QString &secondKey )
+{
+ setText( txt );
+ sortKey = Qtopia::buildSortKey( txt, secondKey );
+
+ // sortKey = txt.lower() + QChar( '\0' ) + secondKey.lower();
+}
+
+/*!
+ \class AbPickItem abtable.h
+
+ \brief QTableItem based class for showing slection of an entry
+*/
+
+AbPickItem::AbPickItem( QTable *t ) :
+ QTableItem(t, WhenCurrent, "?")
+{
+}
+
+QWidget *AbPickItem::createEditor() const
+{
+ QComboBox* combo = new QComboBox( table()->viewport() );
+ ( (AbPickItem*)this )->cb = combo;
+ AbTable* t = static_cast<AbTable*>(table());
+ QStringList c = t->choiceNames();
+ int cur = 0;
+ for (QStringList::ConstIterator it = c.begin(); it!=c.end(); ++it) {
+ if ( *it == text() )
+ cur = combo->count();
+ combo->insertItem(*it);
+ }
+ combo->setCurrentItem(cur);
+ return combo;
+}
+
+void AbPickItem::setContentFromEditor( QWidget *w )
+{
+ if ( w->inherits("QComboBox") )
+ setText( ( (QComboBox*)w )->currentText() );
+ else
+ QTableItem::setContentFromEditor( w );
+}
+
+/*!
+ \class AbTable abtable.h
+
+ \brief QTable based class for showing a list of entries
+*/
+
+AbTable::AbTable( const QValueList<int> *order, QWidget *parent, const char *name )
+// #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR
+// : QTable( 0, 0, parent, name, TRUE ),
+// #else
+ : QTable( parent, name ),
+// #endif
+ lastSortCol( -1 ),
+ asc( TRUE ),
+ intFields( order ),
+ currFindRow( -2 ),
+ mCat( 0 )
+{
+ mCat.load( categoryFileName() );
+ setSelectionMode( NoSelection );
+ init();
+ setSorting( TRUE );
+ connect( this, SIGNAL(clicked(int,int,int,const QPoint &)),
+ this, SLOT(itemClicked(int,int)) );
+}
+
+AbTable::~AbTable()
+{
+}
+
+void AbTable::init()
+{
+ setNumRows( 0 );
+ setNumCols( 2 );
+
+ horizontalHeader()->setLabel( 0, tr( "Full Name" ));
+ horizontalHeader()->setLabel( 1, tr( "Contact" ));
+ setLeftMargin( 0 );
+ verticalHeader()->hide();
+}
+
+void AbTable::columnClicked( int col )
+{
+ if ( !sorting() )
+ return;
+
+ if ( lastSortCol == -1 )
+ lastSortCol = col;
+
+ if ( col == lastSortCol ) {
+ asc = !asc;
+ } else {
+ lastSortCol = col;
+ asc = TRUE;
+ }
+ resort();
+}
+
+void AbTable::resort()
+{
+ if ( sorting() ) {
+ if ( lastSortCol == -1 )
+ lastSortCol = 0;
+ sortColumn( lastSortCol, asc, TRUE );
+ updateVisible();
+ }
+}
+
+Contact AbTable::currentEntry()
+{
+ Contact cnt;
+ AbTableItem *abItem;
+ abItem = static_cast<AbTableItem*>(item( currentRow(), 0 ));
+ if ( abItem ) {
+ cnt = contactList[abItem];
+ }
+ return cnt;
+}
+
+void AbTable::replaceCurrentEntry( const Contact &newContact )
+{
+ int row = currentRow();
+ updateJournal( newContact, Contact::ACTION_REPLACE, row );
+ updateVisible();
+
+ journalFreeReplace( newContact, row );
+}
+
+void AbTable::deleteCurrentEntry()
+{
+ int row = currentRow();
+ AbTableItem *abItem;
+ abItem = static_cast<AbTableItem*>(item( row, 0 ));
+ Contact oldContact;
+ oldContact = contactList[abItem];
+ updateJournal( oldContact, Contact::ACTION_REMOVE, row );
+
+ // a little wasteful, but it ensure's there is only one place
+ // where we delete.
+ journalFreeRemove( row );
+ updateVisible();
+
+ if ( numRows() == 0 )
+ emit empty( TRUE );
+}
+
+void AbTable::clear()
+{
+ contactList.clear();
+ for ( int r = 0; r < numRows(); ++r ) {
+ for ( int c = 0; c < numCols(); ++c ) {
+ if ( cellWidget( r, c ) )
+ clearCellWidget( r, c );
+ clearCell( r, c );
+ }
+ }
+ setNumRows( 0 );
+}
+
+void AbTable::refresh()
+{
+ int rows = numRows();
+ QString value;
+ AbTableItem *abi;
+ for ( int r = 0; r < rows; ++r ) {
+ abi = static_cast<AbTableItem*>( item(r, 0) );
+ value = findContactContact( contactList[abi] );
+ static_cast<AbTableItem*>( item(r, 1) )->setItem( value, abi->text() );
+ }
+ resort();
+}
+
+void AbTable::keyPressEvent( QKeyEvent *e )
+{
+ char key = toupper( e->ascii() );
+
+ if ( key >= 'A' && key <= 'Z' )
+ moveTo( key );
+
+ switch( e->key() ) {
+ case Qt::Key_Space:
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ emit details();
+ break;
+ default:
+ QTable::keyPressEvent( e );
+ }
+}
+
+void AbTable::moveTo( char c )
+{
+
+ int rows = numRows();
+ QString value;
+ AbTableItem *abi;
+ int r;
+ if ( asc ) {
+ r = 0;
+ while ( r < rows-1) {
+ abi = static_cast<AbTableItem*>( item(r, 0) );
+ QChar first = abi->key()[0];
+ //### is there a bug in QChar to char comparison???
+ if ( first.row() || first.cell() >= c )
+ break;
+ r++;
+ }
+ } else {
+ //### should probably disable reverse sorting instead
+ r = rows - 1;
+ while ( r > 0 ) {
+ abi = static_cast<AbTableItem*>( item(r, 0) );
+ QChar first = abi->key()[0];
+ //### is there a bug in QChar to char comparison???
+ if ( first.row() || first.cell() >= c )
+ break;
+ r--;
+ }
+ }
+ setCurrentCell( r, currentColumn() );
+}
+
+
+QString AbTable::findContactName( const Contact &entry )
+{
+ // We use the fileAs, then company, defaultEmail
+ QString str;
+ str = entry.fileAs();
+ if ( str.isEmpty() ) {
+ str = entry.company();
+ if ( str.isEmpty() ) {
+ str = entry.defaultEmail();
+ }
+ }
+ return str;
+}
+
+QString AbTable::findContactContact( const Contact &entry )
+{
+ QString value;
+ value = "";
+ for ( QValueList<int>::ConstIterator it = intFields->begin();
+ it != intFields->end(); ++it ) {
+ switch ( *it ) {
+ default:
+ break;
+ case Qtopia::Title:
+ value = entry.title();
+ break;
+ case Qtopia::Suffix:
+ value = entry.suffix();
+ break;
+ case Qtopia::FileAs:
+ value = entry.fileAs();
+ break;
+ case Qtopia::DefaultEmail:
+ value = entry.defaultEmail();
+ case Qtopia::Emails:
+ value = entry.emails();
+ break;
+ case Qtopia::HomeStreet:
+ value = entry.homeStreet();
+ break;
+ case Qtopia::HomeCity:
+ value = entry.homeCity();
+ break;
+ case Qtopia::HomeState:
+ value = entry.homeState();
+ break;
+ case Qtopia::HomeZip:
+ value = entry.homeZip();
+ break;
+ case Qtopia::HomeCountry:
+ value = entry.homeCountry();
+ break;
+ case Qtopia::HomePhone:
+ value = entry.homePhone();
+ break;
+ case Qtopia::HomeFax:
+ value = entry.homeFax();
+ break;
+ case Qtopia::HomeMobile:
+ value = entry.homeMobile();
+ break;
+ case Qtopia::HomeWebPage:
+ value = entry.homeWebpage();
+ break;
+ case Qtopia::Company:
+ value = entry.company();
+ break;
+ case Qtopia::BusinessCity:
+ value = entry.businessCity();
+ break;
+ case Qtopia::BusinessStreet:
+ value = entry.businessStreet();
+ break;
+ case Qtopia::BusinessZip:
+ value = entry.businessZip();
+ break;
+ case Qtopia::BusinessCountry:
+ value = entry.businessCountry();
+ break;
+ case Qtopia::BusinessWebPage:
+ value = entry.businessWebpage();
+ break;
+ case Qtopia::JobTitle:
+ value = entry.jobTitle();
+ break;
+ case Qtopia::Department:
+ value = entry.department();
+ break;
+ case Qtopia::Office:
+ value = entry.office();
+ break;
+ case Qtopia::BusinessPhone:
+ value = entry.businessPhone();
+ break;
+ case Qtopia::BusinessFax:
+ value = entry.businessFax();
+ break;
+ case Qtopia::BusinessMobile:
+ value = entry.businessMobile();
+ break;
+ case Qtopia::BusinessPager:
+ value = entry.businessPager();
+ break;
+ case Qtopia::Profession:
+ value = entry.profession();
+ break;
+ case Qtopia::Assistant:
+ value = entry.assistant();
+ break;
+ case Qtopia::Manager:
+ value = entry.manager();
+ break;
+ case Qtopia::Spouse:
+ value = entry.spouse();
+ break;
+ case Qtopia::Gender:
+ value = entry.gender();
+ break;
+ case Qtopia::Birthday:
+ value = entry.birthday();
+ break;
+ case Qtopia::Anniversary:
+ value = entry.anniversary();
+ break;
+ case Qtopia::Nickname:
+ value = entry.nickname();
+ break;
+ case Qtopia::Children:
+ value = entry.children();
+ break;
+ case Qtopia::Notes:
+ value = entry.notes();
+ break;
+ }
+ if ( !value.isEmpty() )
+ break;
+ }
+ return value;
+}
+
+void AbTable::addEntry( const Contact &newCnt )
+{
+ int row = numRows();
+ setNumRows( row + 1 );
+ updateJournal( newCnt, Contact::ACTION_ADD );
+ insertIntoTable( newCnt, row );
+ setCurrentCell( row, 0 );
+ updateVisible();
+}
+
+void AbTable::updateJournal( const Contact &cnt,
+ Contact::journal_action action, int row )
+{
+ QFile f( journalFileName() );
+ if ( !f.open(IO_WriteOnly|IO_Append) )
+ return;
+ QString buf;
+ QCString str;
+ buf = "<Contact ";
+ cnt.save( buf );
+ buf += " action=\"" + QString::number( (int)action ) + "\" ";
+ if ( action == Contact::ACTION_REMOVE || action == Contact::ACTION_REPLACE)
+ buf += " actionrow=\"" + QString::number(row) + "\" ";
+ buf += "/>\n";
+ QCString cstr = buf.utf8();
+ f.writeBlock( cstr.data(), cstr.length() );
+ QCopEnvelope( "QPE/PIM", "addressbookUpdated()" );
+}
+
+bool AbTable::save( const QString &fn )
+{
+// QTime t;
+// t.start();
+
+ QString strNewFile = fn + ".new";
+ QFile f( strNewFile );
+ if ( !f.open( IO_WriteOnly|IO_Raw ) )
+ return false;
+
+ int total_written;
+ QString out;
+ out = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE Addressbook ><AddressBook>\n"
+ " <Groups>\n"
+ " </Groups>\n"
+ " <Contacts>\n";
+ QMapIterator<AbTableItem*, Contact> it;
+ for ( it = contactList.begin(); it != contactList.end(); ++it ) {
+ out += "<Contact ";
+ it.data().save( out );
+ out += "/>\n";
+ QCString cstr = out.utf8();
+ total_written = f.writeBlock( cstr.data(), cstr.length() );
+ if ( total_written != int(cstr.length()) ) {
+ f.close();
+ QFile::remove( strNewFile );
+ return false;
+ }
+ out = "";
+ }
+ out += " </Contacts>\n</AddressBook>\n";
+
+ QCString cstr = out.utf8();
+ total_written = f.writeBlock( cstr.data(), cstr.length() );
+ if ( total_written != int(cstr.length()) ) {
+ f.close();
+ QFile::remove( strNewFile );
+ return false;
+ }
+ f.close();
+
+// qDebug("saving: %d", t.elapsed() );
+
+ // move the file over, I'm just going to use the system call
+ // because, I don't feel like using QDir.
+ if ( ::rename( strNewFile.latin1(), fn.latin1() ) < 0 ) {
+ qWarning( "problem renaming file %s to %s, errno: %d",
+ strNewFile.latin1(), fn.latin1(), errno );
+ // remove the tmp file...
+ QFile::remove( strNewFile );
+ }
+ // remove the journal...
+ QFile::remove( journalFileName() );
+ return true;
+}
+
+void AbTable::load( const QString &fn )
+{
+ setSorting( false );
+ loadFile( fn, false );
+ // merge in the journal
+ if ( QFile::exists( journalFileName() ) ) {
+ loadFile( journalFileName(), true );
+ save( fn );
+ }
+ setSorting( true );
+ resort();
+}
+
+void AbTable::loadFile( const QString &strFile, bool journalFile )
+{
+// QTime t;
+// t.start();
+ QFile f( strFile );
+ if ( !f.open(IO_ReadOnly) )
+ return;
+ QList<Contact> list;
+ list.setAutoDelete( TRUE );
+ QByteArray ba = f.readAll();
+ f.close();
+ char *uc = ba.data();//(QChar *)data.unicode();
+ int len = ba.size();//data.length();
+ bool foundAction = false;
+ Contact::journal_action action;
+ bool foundKey = false;
+ int journalKey = 0;
+
+ const int JOURNALACTION = Qtopia::Notes + 1;
+ const int JOURNALROW = JOURNALACTION + 1;
+
+ // **********************************
+ // CHANGE THE SIZE OF THE DICT IF YOU ADD ANY MORE FIELDS!!!!
+ // **********************************
+ QAsciiDict<int> dict( 47 );
+ dict.setAutoDelete( TRUE );
+ dict.insert( "Uid", new int(Qtopia::AddressUid) );
+ dict.insert( "Title", new int(Qtopia::Title) );
+ dict.insert( "FirstName", new int(Qtopia::FirstName) );
+ dict.insert( "MiddleName", new int(Qtopia::MiddleName) );
+ dict.insert( "LastName", new int(Qtopia::LastName) );
+ dict.insert( "Suffix", new int(Qtopia::Suffix) );
+ dict.insert( "FileAs", new int(Qtopia::FileAs) );
+ dict.insert( "Categories", new int(Qtopia::AddressCategory) );
+ dict.insert( "DefaultEmail", new int(Qtopia::DefaultEmail) );
+ dict.insert( "Emails", new int(Qtopia::Emails) );
+ dict.insert( "HomeStreet", new int(Qtopia::HomeStreet) );
+ dict.insert( "HomeCity", new int(Qtopia::HomeCity) );
+ dict.insert( "HomeState", new int(Qtopia::HomeState) );
+ dict.insert( "HomeZip", new int(Qtopia::HomeZip) );
+ dict.insert( "HomeCountry", new int(Qtopia::HomeCountry) );
+ dict.insert( "HomePhone", new int(Qtopia::HomePhone) );
+ dict.insert( "HomeFax", new int(Qtopia::HomeFax) );
+ dict.insert( "HomeMobile", new int(Qtopia::HomeMobile) );
+ dict.insert( "HomeWebPage", new int(Qtopia::HomeWebPage) );
+ dict.insert( "Company", new int(Qtopia::Company) );
+ dict.insert( "BusinessStreet", new int(Qtopia::BusinessStreet) );
+ dict.insert( "BusinessCity", new int(Qtopia::BusinessCity) );
+ dict.insert( "BusinessState", new int(Qtopia::BusinessState) );
+ dict.insert( "BusinessZip", new int(Qtopia::BusinessZip) );
+ dict.insert( "BusinessCountry", new int(Qtopia::BusinessCountry) );
+ dict.insert( "BusinessWebPage", new int(Qtopia::BusinessWebPage) );
+ dict.insert( "JobTitle", new int(Qtopia::JobTitle) );
+ dict.insert( "Department", new int(Qtopia::Department) );
+ dict.insert( "Office", new int(Qtopia::Office) );
+ dict.insert( "BusinessPhone", new int(Qtopia::BusinessPhone) );
+ dict.insert( "BusinessFax", new int(Qtopia::BusinessFax) );
+ dict.insert( "BusinessMobile", new int(Qtopia::BusinessMobile) );
+ dict.insert( "BusinessPager", new int(Qtopia::BusinessPager) );
+ dict.insert( "Profession", new int(Qtopia::Profession) );
+ dict.insert( "Assistant", new int(Qtopia::Assistant) );
+ dict.insert( "Manager", new int(Qtopia::Manager) );
+ dict.insert( "Spouse", new int(Qtopia::Spouse) );
+ dict.insert( "Children", new int(Qtopia::Children) );
+ dict.insert( "Gender", new int(Qtopia::Gender) );
+ dict.insert( "Birthday", new int(Qtopia::Birthday) );
+ dict.insert( "Anniversary", new int(Qtopia::Anniversary) );
+ dict.insert( "Nickname", new int(Qtopia::Nickname) );
+ dict.insert( "Notes", new int(Qtopia::Notes) );
+ dict.insert( "action", new int(JOURNALACTION) );
+ dict.insert( "actionrow", new int(JOURNALROW) );
+
+ int i = 0;
+ int num = 0;
+ char *point;
+ while ( (point = strstr( uc+i, "<Contact " ) ) != NULL ) {
+ i = point - uc;
+ // if we are reading the standard file, we just need to
+ // insert info, so just say we'll do an insert...
+ action = Contact::ACTION_ADD;
+ // new Contact
+ Contact *cnt = new Contact;
+ i += 9;
+ while ( 1 ) {
+ while ( i < len && (uc[i] == ' ' || uc[i] == '\n' || uc[i] == '\r') )
+ i++;
+ if ( i >= len-2 || (uc[i] == '/' && uc[i+1] == '>') )
+ break;
+ // we have another attribute read it.
+ int j = i;
+ while ( j < len && uc[j] != '=' )
+ j++;
+ char *attr = uc+i;
+ uc[j] = '\0';
+ //qDebug("attr=%s", attr.latin1() );
+ i = ++j; // skip =
+ while ( i < len && uc[i] != '"' )
+ i++;
+ j = ++i;
+ bool haveEnt = FALSE;
+ bool haveUtf = FALSE;
+ while ( j < len && uc[j] != '"' ) {
+ if ( uc[j] == '&' )
+ haveEnt = TRUE;
+ if ( ((unsigned char)uc[j]) > 0x7f )
+ haveUtf = TRUE;
+ j++;
+ }
+
+ if ( j == i ) {
+ // empty value
+ i = j + 1;
+ continue;
+ }
+
+ QString value = haveUtf ? QString::fromUtf8( uc+i, j-i )
+ : QString::fromLatin1( uc+i, j-i );
+ if ( haveEnt )
+ value = Qtopia::plainString( value );
+ i = j + 1;
+
+ int *find = dict[ attr ];
+ if ( !find ) {
+ cnt->setCustomField(attr, value);
+ continue;
+ }
+#if 1
+ switch( *find ) {
+ case Qtopia::AddressUid:
+ cnt->setUid( value.toInt() );
+ break;
+ case Qtopia::AddressCategory:
+ cnt->setCategories( Qtopia::Record::idsFromString( value ));
+ break;
+ case JOURNALACTION:
+ action = Contact::journal_action(value.toInt());
+ break;
+ case JOURNALROW:
+ journalKey = value.toInt();
+ break;
+
+ default:
+ cnt->insert( *find, value );
+ break;
+ }
+#endif
+ }
+
+ // sadly we can't delay adding of items from the journal to get
+ // the proper effect, but then, the journal should _never_ be
+ // that huge, and recovering from a crash is not necessarily
+ // a *fast* thing.
+ switch ( action ) {
+ case Contact::ACTION_ADD:
+ if ( journalFile ) {
+ int myrows = numRows();
+ setNumRows( myrows + 1 );
+ insertIntoTable( *cnt, myrows );
+ delete cnt;
+ }
+ else
+ list.append( cnt );
+ break;
+ case Contact::ACTION_REMOVE:
+ // yup, we don't use the entry to remove the object...
+ journalFreeRemove( journalKey );
+ delete cnt;
+ break;
+ case Contact::ACTION_REPLACE:
+ journalFreeReplace( *cnt, journalKey );
+ delete cnt;
+ break;
+ default:
+ break;
+ }
+ num++;
+ foundAction = false;
+ foundKey = false;
+// if ( num % 100 == 0 ) {
+// qDebug("loading file, num=%d, t=%d", num, t.elapsed() );
+// }
+ }
+ if ( list.count() > 0 ) {
+ internalAddEntries( list );
+ }
+// qDebug("done loading %d, t=%d", num, t.elapsed() );
+
+}
+
+void AbTable::realignTable( int row )
+{
+ QTableItem *ti1,
+ *ti2;
+ int totalRows = numRows();
+ for ( int curr = row; curr < totalRows - 1; curr++ ) {
+ // the same info from the todo list still applies, but I
+ // don't think it is _too_ bad.
+ ti1 = item( curr + 1, 0 );
+ ti2 = item( curr + 1, 1 );
+ takeItem( ti1 );
+ takeItem( ti2 );
+ setItem( curr, 0, ti1 );
+ setItem( curr, 1, ti2 );
+ }
+ setNumRows( totalRows - 1 );
+ resort();
+}
+
+void AbTable::insertIntoTable( const Contact &cnt, int row )
+{
+ QString strName,
+ strContact;
+
+ strName = findContactName( cnt );
+ strContact = findContactContact( cnt );
+
+ AbTableItem *ati;
+ ati = new AbTableItem( this, QTableItem::Never, strName, strContact);
+ contactList.insert( ati, cnt );
+ setItem( row, 0, ati );
+ ati = new AbTableItem( this, QTableItem::Never, strContact, strName);
+ setItem( row, 1, ati );
+
+ //### cannot do this; table only has two columns at this point
+ // setItem( row, 2, new AbPickItem( this ) );
+
+ // resort at some point?
+}
+
+void AbTable::internalAddEntries( QList<Contact> &list )
+{
+ setUpdatesEnabled( FALSE );
+ setNumRows( list.count() );
+ int row = 0;
+ Contact *it;
+ for ( it = list.first(); it; it = list.next() )
+ insertIntoTable( *it, row++ );
+ resort();
+ setUpdatesEnabled( TRUE );
+}
+
+
+void AbTable::journalFreeReplace( const Contact &cnt, int row )
+{
+ QString strName,
+ strContact;
+ AbTableItem *ati;
+
+ strName = findContactName( cnt );
+ strContact = findContactContact( cnt );
+ ati = static_cast<AbTableItem*>(item(row, 0));
+ contactList.remove( ati );
+ ati->setItem( strName, strContact );
+ contactList.insert( ati, cnt );
+
+ ati = static_cast<AbTableItem*>(item(row, 1));
+ ati->setItem( strContact, strName );
+}
+
+void AbTable::journalFreeRemove( int row )
+{
+ AbTableItem *ati;
+ ati = static_cast<AbTableItem*>(item(row, 0));
+ if ( !ati )
+ return;
+ contactList.remove( ati );
+ realignTable( row );
+}
+
+#if QT_VERSION <= 230
+#ifndef SINGLE_APP
+void QTable::paintEmptyArea( QPainter *p, int cx, int cy, int cw, int ch )
+{
+ // Region of the rect we should draw
+ QRegion reg( QRect( cx, cy, cw, ch ) );
+ // Subtract the table from it
+ reg = reg.subtract( QRect( QPoint( 0, 0 ), tableSize() ) );
+ // And draw the rectangles (transformed as needed)
+ QArray<QRect> r = reg.rects();
+ for (unsigned int i=0; i<r.count(); i++)
+ p->fillRect( r[i], colorGroup().brush( QColorGroup::Base ) );
+}
+#endif
+#endif
+
+
+// int AbTable::rowHeight( int ) const
+// {
+// return 18;
+// }
+
+// int AbTable::rowPos( int row ) const
+// {
+// return 18*row;
+// }
+
+// int AbTable::rowAt( int pos ) const
+// {
+// return QMIN( pos/18, numRows()-1 );
+// }
+
+void AbTable::slotDoFind( const QString &findString, bool caseSensitive,
+ bool backwards, int category )
+{
+ if ( currFindRow < -1 )
+ currFindRow = currentRow() - 1;
+ clearSelection( TRUE );
+ int rows,
+ row;
+ AbTableItem *ati;
+ QRegExp r( findString );
+ r.setCaseSensitive( caseSensitive );
+ rows = numRows();
+ static bool wrapAround = true;
+
+ if ( !backwards ) {
+ for ( row = currFindRow + 1; row < rows; row++ ) {
+ ati = static_cast<AbTableItem*>( item(row, 0) );
+ if ( contactCompare( contactList[ati], r, category ) )
+ break;
+
+ }
+ } else {
+ for ( row = currFindRow - 1; row > -1; row-- ) {
+ ati = static_cast<AbTableItem*>( item(row, 0) );
+ if ( contactCompare( contactList[ati], r, category ) )
+ break;
+ }
+ }
+ if ( row >= rows || row < 0 ) {
+ if ( row < 0 )
+ currFindRow = rows;
+ else
+ currFindRow = -1;
+
+ if ( wrapAround )
+ emit signalWrapAround();
+ else
+ emit signalNotFound();
+
+ wrapAround = !wrapAround;
+ } else {
+ currFindRow = row;
+ QTableSelection foundSelection;
+ foundSelection.init( currFindRow, 0 );
+ foundSelection.expandTo( currFindRow, numCols() - 1 );
+ addSelection( foundSelection );
+ setCurrentCell( currFindRow, numCols() - 1 );
+ wrapAround = true;
+ }
+}
+
+static bool contactCompare( const Contact &cnt, const QRegExp &r, int category )
+{
+ bool returnMe;
+ QArray<int> cats;
+ cats = cnt.categories();
+
+ returnMe = false;
+ if ( (category == -1 && cats.count() == 0) || category == -2 )
+ returnMe = cnt.match( r );
+ else {
+ int i;
+ for ( i = 0; i < int(cats.count()); i++ ) {
+ if ( cats[i] == category ) {
+ returnMe = cnt.match( r );
+ break;
+ }
+ }
+ }
+ return returnMe;
+}
+
+void AbTable::fitColumns()
+{
+ int contentsWidth = visibleWidth();
+ int n = numCols();
+ int pw = n == 3 ? columnWidth(2) : 0;
+ setColumnWidth( 0, contentsWidth - contentsWidth / 2 );
+ setColumnWidth( 1, contentsWidth / 2 - pw );
+}
+
+void AbTable::show()
+{
+ fitColumns();
+ QTable::show();
+}
+
+void AbTable::setChoiceNames( const QStringList& list)
+{
+ choicenames = list;
+ if ( choicenames.isEmpty() ) {
+ // hide pick column
+ setNumCols( 2 );
+ } else {
+ // show pick column
+ setNumCols( 3 );
+ setColumnWidth( 2, fontMetrics().width(tr( "Pick" ))+8 );
+ horizontalHeader()->setLabel( 2, tr( "Pick" ));
+ }
+ fitColumns();
+}
+
+void AbTable::itemClicked(int,int col)
+{
+ if ( col == 2 ) {
+ return;
+ } else {
+ emit details();
+ }
+}
+
+QStringList AbTable::choiceNames() const
+{
+ return choicenames;
+}
+
+void AbTable::setChoiceSelection(int /*index*/, const QStringList& /*list*/)
+{
+ /* ######
+
+ QString selname = choicenames.at(index);
+ for (each row) {
+ Contact *c = contactForRow(row);
+ if ( list.contains(c->email) ) {
+ list.remove(c->email);
+ setText(row, 2, selname);
+ }
+ }
+ for (remaining list items) {
+ Contact *c = new contact(item);
+ setText(newrow, 2, selname);
+ }
+
+ */
+}
+
+QStringList AbTable::choiceSelection(int /*index*/) const
+{
+ QStringList r;
+ /* ######
+
+ QString selname = choicenames.at(index);
+ for (each row) {
+ Contact *c = contactForRow(row);
+ if ( text(row,2) == selname ) {
+ r.append(c->email);
+ }
+ }
+
+ */
+ return r;
+}
+
+void AbTable::setShowCategory( const QString &c )
+{
+ showCat = c;
+ updateVisible();
+}
+
+QString AbTable::showCategory() const
+{
+ return showCat;
+}
+
+
+QStringList AbTable::categories()
+{
+ mCat.load( categoryFileName() );
+ QStringList categoryList = mCat.labels( "Contacts" );
+ return categoryList;
+}
+
+void AbTable::updateVisible()
+{
+ int visible,
+ totalRows,
+ id,
+ totalCats,
+ it,
+ row;
+ bool hide;
+ AbTableItem *ati;
+ Contact *cnt;
+ visible = 0;
+
+ setPaintingEnabled( FALSE );
+
+ totalRows = numRows();
+ id = mCat.id( "Contacts", showCat );
+ QArray<int> cats;
+ for ( row = 0; row < totalRows; row++ ) {
+ ati = static_cast<AbTableItem*>( item(row, 0) );
+ cnt = &contactList[ati];
+ cats = cnt->categories();
+ hide = false;
+ if ( !showCat.isEmpty() ) {
+ if ( showCat == tr( "Unfiled" ) ) {
+ if ( cats.count() > 0 )
+ hide = true;
+ } else {
+ // do some comparing
+ if ( !hide ) {
+ hide = true;
+ totalCats = int(cats.count());
+ for ( it = 0; it < totalCats; it++ ) {
+ if ( cats[it] == id ) {
+ hide = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if ( hide ) {
+ if ( currentRow() == row )
+ setCurrentCell( -1, 0 );
+ if ( rowHeight(row) > 0 )
+ hideRow( row );
+ } else {
+ if ( rowHeight(row) == 0 ) {
+ showRow( row );
+ adjustRow( row );
+ }
+ visible++;
+ }
+ }
+ if ( !visible )
+ setCurrentCell( -1, 0 );
+
+ setPaintingEnabled( TRUE );
+}
+
+
+void AbTable::setPaintingEnabled( bool e )
+{
+ if ( e != enablePainting ) {
+ if ( !enablePainting ) {
+ enablePainting = true;
+ rowHeightChanged( 0 );
+ viewport()->update();
+ } else {
+ enablePainting = false;
+ }
+ }
+}
+
+void AbTable::rowHeightChanged( int row )
+{
+ if ( enablePainting )
+ QTable::rowHeightChanged( row );
+}
diff --git a/core/pim/addressbook/abtable.h b/core/pim/addressbook/abtable.h
new file mode 100644
index 0000000..9b96997
--- a/dev/null
+++ b/core/pim/addressbook/abtable.h
@@ -0,0 +1,140 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef ABTABLE_H
+#define ABTABLE_H
+
+#include <qpe/categories.h>
+#include <qpe/contact.h>
+
+#include <qmap.h>
+#include <qtable.h>
+#include <qstringlist.h>
+#include <qcombobox.h>
+
+class AbTableItem : public QTableItem
+{
+public:
+ AbTableItem( QTable *t, EditType et, const QString &s,
+ const QString &secondSortKey);
+ QString entryKey() const;
+ void setEntryKey( const QString & k );
+ virtual int alignment() const;
+ virtual QString key() const;
+ void setItem( const QString &txt, const QString &secondKey );
+
+private:
+ QString sortKey;
+};
+
+class AbPickItem : public QTableItem
+{
+public:
+ AbPickItem( QTable *t );
+
+ QWidget *createEditor() const;
+ void setContentFromEditor( QWidget *w );
+
+private:
+ QGuardedPtr<QComboBox> cb;
+};
+
+class AbTable : public QTable
+{
+ Q_OBJECT
+
+public:
+ AbTable( const QValueList<int> *ordered, QWidget *parent, const char *name=0 );
+ ~AbTable();
+ // NEW
+ void addEntry( const Contact &newContact );
+ Contact currentEntry();
+ void replaceCurrentEntry( const Contact &newContact );
+
+ void init();
+
+ void deleteCurrentEntry();
+ void clear();
+ void clearFindRow() { currFindRow = -2; }
+ void loadFields();
+ void refresh();
+ bool save( const QString &fn );
+ void load( const QString &fn );
+
+ // addresspicker mode
+ void setChoiceNames( const QStringList& list);
+ QStringList choiceNames() const;
+ void setChoiceSelection(int index, const QStringList& list);
+ QStringList choiceSelection(int index) const;
+ void setShowCategory( const QString &c );
+ QString showCategory() const;
+ QStringList categories();
+
+ void show();
+ void setPaintingEnabled( bool e );
+
+public slots:
+ void slotDoFind( const QString &str, bool caseSensitive, bool backwards,
+ int category );
+signals:
+ void empty( bool );
+ void details();
+ void signalNotFound();
+ void signalWrapAround();
+
+protected:
+ virtual void keyPressEvent( QKeyEvent *e );
+
+// int rowHeight( int ) const;
+// int rowPos( int row ) const;
+// virtual int rowAt( int pos ) const;
+
+
+protected slots:
+ void moveTo( char );
+ virtual void columnClicked( int col );
+ void itemClicked(int,int col);
+ void rowHeightChanged( int row );
+
+private:
+ void loadFile( const QString &strFile, bool journalFile );
+ void fitColumns();
+ void resort();
+ void updateJournal( const Contact &contact, Contact::journal_action action,
+ int row = -1 );
+ void insertIntoTable( const Contact &contact, int row );
+ void internalAddEntries( QList<Contact> &list );
+ QString findContactName( const Contact &entry );
+ QString findContactContact( const Contact &entry );
+ void journalFreeReplace( const Contact &cnt, int row );
+ void journalFreeRemove( int row );
+ void realignTable( int );
+ void updateVisible();
+ int lastSortCol;
+ bool asc;
+ QMap<AbTableItem*, Contact> contactList;
+ const QValueList<int> *intFields;
+ int currFindRow;
+ QString showCat;
+ QStringList choicenames;
+ bool enablePainting;
+ Categories mCat;
+};
+#endif // ABTABLE_H
diff --git a/core/pim/addressbook/addressbook.cpp b/core/pim/addressbook/addressbook.cpp
new file mode 100644
index 0000000..b694e4f
--- a/dev/null
+++ b/core/pim/addressbook/addressbook.cpp
@@ -0,0 +1,829 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "abeditor.h"
+#include "ablabel.h"
+#include "abtable.h"
+#include "addresssettings.h"
+#include "addressbook.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/config.h>
+#include <qpe/contact.h>
+#include <qpe/finddialog.h>
+#include <qpe/global.h>
+#include <qpe/resource.h>
+#include <qpe/ir.h>
+#include <qpe/qpemessagebox.h>
+#include <qpe/qcopenvelope_qws.h>
+
+#include <qaction.h>
+#include <qdialog.h>
+#include <qdir.h>
+#include <qfile.h>
+#include <qimage.h>
+#include <qlayout.h>
+#include <qpe/qpemenubar.h>
+#include <qmessagebox.h>
+#include <qpixmap.h>
+#include <qpopupmenu.h>
+#include <qpe/qpetoolbar.h>
+#include <qstringlist.h>
+#include <qtoolbutton.h>
+#include <qwhatsthis.h>
+
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <qdatetime.h>
+
+static QString addressbookOldXMLFilename()
+{
+ QString filename = QPEApplication::documentDir() + "addressbook.xml";
+ return filename;
+}
+
+static QString addressbookXMLFilename()
+{
+ QString filename = Global::applicationFileName("addressbook",
+ "addressbook.xml");
+ return filename;
+}
+
+static QString addressbookPersonalVCardName()
+{
+ QString filename = Global::applicationFileName("addressbook",
+ "businesscard.vcf");
+ return filename;
+}
+
+
+AddressbookWindow::AddressbookWindow( QWidget *parent, const char *name,
+ WFlags f )
+ : QMainWindow( parent, name, f ),
+ abEditor(0),
+ bAbEditFirstTime(TRUE),
+ syncing(FALSE)
+{
+ initFields();
+
+ setCaption( tr("Contacts") );
+ setIcon( Resource::loadPixmap( "AddressBook" ) );
+
+ setToolBarsMovable( FALSE );
+
+ // Create Toolbars
+
+ QPEToolBar *bar = new QPEToolBar( this );
+ bar->setHorizontalStretchable( TRUE );
+
+ QPEMenuBar *mbList = new QPEMenuBar( bar );
+ mbList->setMargin( 0 );
+
+ QPopupMenu *edit = new QPopupMenu( this );
+ mbList->insertItem( tr( "Contact" ), edit );
+
+ listTools = new QPEToolBar( this, "list operations" );
+
+
+ QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ), QString::null,
+ 0, this, 0 );
+ actionNew = a;
+ connect( a, SIGNAL( activated() ), this, SLOT( slotListNew() ) );
+ a->addTo( edit );
+ a->addTo( listTools );
+
+ a = new QAction( tr( "Edit" ), Resource::loadPixmap( "edit" ), QString::null,
+ 0, this, 0 );
+ actionEdit = a;
+ connect( a, SIGNAL( activated() ), this, SLOT( slotViewEdit() ) );
+ a->addTo( edit );
+ a->addTo( listTools );
+
+ a = new QAction( tr( "Delete" ), Resource::loadPixmap( "trash" ), QString::null,
+ 0, this, 0 );
+ actionTrash = a;
+ connect( a, SIGNAL( activated() ), this, SLOT( slotListDelete() ) );
+ a->addTo( edit );
+ a->addTo( listTools );
+
+ a = new QAction( tr( "Find" ), Resource::loadPixmap( "mag" ),
+ QString::null, 0, this, 0 );
+ actionFind = a;
+ connect( a, SIGNAL(activated()), this, SLOT(slotFind()) );
+ a->addTo( edit );
+ a->addTo( listTools );
+
+
+ a = new QAction( tr( "Write Mail To" ), Resource::loadPixmap( "qtmail/reply" ),
+ QString::null, 0, this, 0 );
+ a->setEnabled( FALSE );
+ actionMail = a;
+ connect( a, SIGNAL( activated() ), this, SLOT( writeMail() ) );
+ a->addTo( edit );
+ a->addTo( listTools );
+
+
+
+ if ( Ir::supported() ) {
+ a = new QAction( tr ("Beam Entry" ), Resource::loadPixmap( "beam" ), QString::null,
+ 0, this, 0 );
+ actionBeam = a;
+ connect( a, SIGNAL( activated() ), this, SLOT( slotBeam() ) );
+ a->addTo( edit );
+ a->addTo( listTools );
+ }
+
+ edit->insertSeparator();
+
+ a = new QAction( tr("My Personal Details"), QString::null, 0, 0, 0, TRUE );
+ actionPersonal = a;
+ connect( a, SIGNAL( activated() ), this, SLOT( slotPersonalView() ) );
+ a->addTo( edit );
+
+
+ a = new QAction( tr( "Arrange Edit Fields"), QString::null, 0, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( slotSettings() ) );
+ a->addTo( edit );
+
+ // Create Views
+
+ // This is safe to call without checking to see if it exists...
+ // not to mention it also does the necessary stuff for the
+ // journaling...
+ QString str = addressbookXMLFilename();
+ if ( str.isNull() ) {
+ QMessageBox::warning( this, tr("Out of Space"),
+ tr("There is not enough space to create\n"
+ "neccessary startup files.\n"
+ "\nFree up some space before\nentering data!")
+ );
+ }
+
+ abList = new AbTable( &orderedFields, this, "table" );
+ abList->setHScrollBarMode( QScrollView::AlwaysOff );
+ connect( abList, SIGNAL( empty( bool ) ),
+ this, SLOT( listIsEmpty( bool ) ) );
+ connect( abList, SIGNAL( details() ),
+ this, SLOT( slotListView() ) );
+ connect( abList, SIGNAL(currentChanged(int,int)),
+ this, SLOT(slotUpdateToolbar()) );
+
+ mView = 0;
+
+ abList->load( addressbookXMLFilename() );
+ if ( QFile::exists(addressbookOldXMLFilename()) ) {
+ abList->load( addressbookOldXMLFilename() );
+ QFile::remove(addressbookOldXMLFilename());
+ }
+
+ catMenu = new QPopupMenu( this );
+ catMenu->setCheckable( TRUE );
+ connect( catMenu, SIGNAL(activated(int)), this, SLOT(slotSetCategory(int)) );
+ populateCategories();
+
+ mbList->insertItem( tr("View"), catMenu );
+ setCentralWidget( abList );
+
+ // qDebug("adressbook contrsuction: t=%d", t.elapsed() );
+}
+
+void AddressbookWindow::setDocument( const QString &filename )
+{
+ if ( filename.find(".vcf") != int(filename.length()) - 4 ) return;
+
+ QValueList<Contact> cl = Contact::readVCard( filename );
+ for( QValueList<Contact>::Iterator it = cl.begin(); it != cl.end(); ++it ) {
+// QString msg = tr("You received a vCard for\n%1.\nDo You want to add it to your\naddressbook?")
+// .arg( (*it).fullName() );
+// if ( QMessageBox::information( this, tr("received contact"), msg, QMessageBox::Ok, QMessageBox::Cancel ) ==
+// QMessageBox::Ok ) {
+ abList->addEntry( *it );
+// }
+ }
+
+}
+
+void AddressbookWindow::resizeEvent( QResizeEvent *e )
+{
+ QMainWindow::resizeEvent( e );
+
+ if ( centralWidget() == abList )
+ showList();
+ else if ( centralWidget() == mView )
+ showView();
+}
+
+AddressbookWindow::~AddressbookWindow()
+{
+}
+
+void AddressbookWindow::slotUpdateToolbar()
+{
+ Contact ce = abList->currentEntry();
+ actionMail->setEnabled( !ce.defaultEmail().isEmpty() );
+}
+
+void AddressbookWindow::showList()
+{
+ if ( mView ) mView->hide();
+ setCentralWidget( abList );
+ abList->show();
+ // update our focues... (or use a stack widget!);
+ abList->setFocus();
+}
+
+void AddressbookWindow::showView()
+{
+ if ( abList->numRows() > 0 ) {
+ abList->hide();
+ setCentralWidget( abView() );
+ mView->show();
+ mView->setFocus();
+ }
+}
+
+void AddressbookWindow::slotListNew()
+{
+ Contact cnt;
+ if( !syncing ) {
+ if ( abEditor )
+ abEditor->setEntry( cnt );
+ abView()->init( cnt );
+ editEntry( NewEntry );
+ } else {
+ QMessageBox::warning(this, tr("Contacts"),
+ tr("Can not edit data, currently syncing"));
+ }
+}
+
+void AddressbookWindow::slotListView()
+{
+ abView()->init( abList->currentEntry() );
+ mView->sync();
+ showView();
+}
+
+void AddressbookWindow::slotListDelete()
+{
+ if(!syncing) {
+ Contact tmpEntry = abList->currentEntry();
+
+ // get a name, do the best we can...
+ QString strName = tmpEntry.fullName();
+ if ( strName.isEmpty() ) {
+ strName = tmpEntry.company();
+ if ( strName.isEmpty() )
+ strName = "No Name";
+ }
+
+
+ if ( QPEMessageBox::confirmDelete( this, tr( "Contacts" ),
+ strName ) ) {
+ abList->deleteCurrentEntry();
+ showList();
+ }
+ } else {
+ QMessageBox::warning( this, tr("Contacts"),
+ tr("Can not edit data, currently syncing") );
+ }
+}
+
+void AddressbookWindow::slotViewBack()
+{
+ showList();
+}
+
+void AddressbookWindow::slotViewEdit()
+{
+ if(!syncing) {
+ if (actionPersonal->isOn()) {
+ editPersonal();
+ } else {
+ if ( !bAbEditFirstTime )
+ abEditor->setEntry( abList->currentEntry() );
+ editEntry( EditEntry );
+ }
+ } else {
+ QMessageBox::warning( this, tr("Contacts"),
+ tr("Can not edit data, currently syncing") );
+ }
+}
+
+
+
+void AddressbookWindow::writeMail()
+{
+ Contact c = abList->currentEntry();
+ QString name = c.fileAs();
+ QString email = c.defaultEmail();
+ QCopEnvelope e("QPE/Application/qtmail", "writeMail(QString,QString)");
+ e << name << email;
+}
+
+
+
+
+static const char * beamfile = "/tmp/obex/contact.vcf";
+
+void AddressbookWindow::slotBeam()
+{
+ QString filename;
+ Contact c;
+ if ( actionPersonal->isOn() ) {
+ filename = addressbookPersonalVCardName();
+ if (!QFile::exists(filename))
+ return; // can't beam a non-existent file
+ c = Contact::readVCard( filename )[0];
+ } else {
+ unlink( beamfile ); // delete if exists
+ c = abList->currentEntry();
+ mkdir("/tmp/obex/", 0755);
+ Contact::writeVCard( beamfile, c );
+ filename = beamfile;
+ }
+ Ir *ir = new Ir( this );
+ connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
+ QString description = c.fullName();
+ ir->send( filename, description, "text/x-vCard" );
+}
+
+void AddressbookWindow::beamDone( Ir *ir )
+{
+ delete ir;
+ unlink( beamfile );
+}
+
+
+static void parseName( const QString& name, QString *first, QString *middle,
+ QString * last )
+{
+
+ int comma = name.find ( "," );
+ QString rest;
+ if ( comma > 0 ) {
+ *last = name.left( comma );
+ comma++;
+ while ( comma < int(name.length()) && name[comma] == ' ' )
+ comma++;
+ rest = name.mid( comma );
+ } else {
+ int space = name.findRev( ' ' );
+ *last = name.mid( space+1 );
+ rest = name.left( space );
+ }
+ int space = rest.find( ' ' );
+ if ( space <= 0 ) {
+ *first = rest;
+ } else {
+ *first = rest.left( space );
+ *middle = rest.mid( space+1 );
+ }
+
+}
+
+
+void AddressbookWindow::appMessage(const QCString &msg, const QByteArray &data)
+{
+ if (msg == "editPersonal()") {
+ editPersonal();
+ } else if (msg == "editPersonalAndClose()") {
+ editPersonal();
+ close();
+ } else if ( msg == "addContact(QString,QString)" ) {
+ QDataStream stream(data,IO_ReadOnly);
+ QString name, email;
+ stream >> name >> email;
+
+ Contact cnt;
+ QString fn, mn, ln;
+ parseName( name, &fn, &mn, &ln );
+ // qDebug( " %s - %s - %s", fn.latin1(), mn.latin1(), ln.latin1() );
+ cnt.setFirstName( fn );
+ cnt.setMiddleName( mn );
+ cnt.setLastName( ln );
+ cnt.setEmails( email );
+ cnt.setDefaultEmail( email );
+ cnt.setFileAs();
+
+ if ( bAbEditFirstTime ) {
+ abEditor = new AbEditor( cnt, &orderedFields, &slOrderedFields,
+ this, "editor" );
+ bAbEditFirstTime = FALSE;
+ } else {
+ abEditor->setEntry( cnt );
+ }
+ abView()->init( cnt );
+ editEntry( NewEntry );
+
+
+
+ }
+#if 0
+ else if (msg == "pickAddresses(QCString,QCString,QStringList,...)" ) {
+ QDataStream stream(data,IO_ReadOnly);
+ QCString ch,m;
+ QStringList types;
+ stream >> ch >> m >> types;
+ AddressPicker picker(abList,this,0,TRUE);
+ picker.showMaximized();
+ picker.setChoiceNames(types);
+ int i=0;
+ for (QStringList::ConstIterator it = types.begin(); it!=types.end(); ++it) {
+ QStringList sel;
+ stream >> sel;
+ picker.setSelection(i++,sel);
+ }
+ picker.showMaximized();
+ picker.exec();
+
+ // ###### note: contacts may have been added - save here!
+
+ setCentralWidget(abList);
+ QCopEnvelope e(ch,m);
+ i=0;
+ for (QStringList::ConstIterator it = types.begin(); it!=types.end(); ++it) {
+ QStringList sel = picker.selection(i++);
+ e << sel;
+ }
+ }
+#endif
+
+}
+
+void AddressbookWindow::editPersonal()
+{
+ QString filename = addressbookPersonalVCardName();
+ Contact me;
+ if (QFile::exists(filename))
+ me = Contact::readVCard( filename )[0];
+ if (bAbEditFirstTime) {
+ abEditor = new AbEditor( me, &orderedFields, &slOrderedFields,
+ this, "editor" );
+ // don't create a new editor every time
+ bAbEditFirstTime = FALSE;
+ } else
+ abEditor->setEntry( me );
+
+ abEditor->setCaption(tr("Edit My Personal Details"));
+ abEditor->showMaximized();
+
+ // fix the foxus...
+ abEditor->setNameFocus();
+ if ( abEditor->exec() ) {
+ setFocus();
+ Contact new_personal = abEditor->entry();
+ QString fname = addressbookPersonalVCardName();
+ Contact::writeVCard( fname, new_personal );
+ abView()->init(new_personal);
+ abView()->sync();
+ }
+ abEditor->setCaption( tr("Edit Address") );
+}
+
+void AddressbookWindow::slotPersonalView()
+{
+ if (!actionPersonal->isOn()) {
+ // we just turned it off
+ setCaption( tr("Contacts") );
+ actionNew->setEnabled(TRUE);
+ actionTrash->setEnabled(TRUE);
+ actionFind->setEnabled(TRUE);
+ slotUpdateToolbar(); // maybe some of the above could be moved there
+ showList();
+ return;
+ }
+
+ // XXX need to disable some QActions.
+ actionNew->setEnabled(FALSE);
+ actionTrash->setEnabled(FALSE);
+ actionFind->setEnabled(FALSE);
+ actionMail->setEnabled(FALSE);
+
+ setCaption( tr("Contacts - My Personal Details") );
+ QString filename = addressbookPersonalVCardName();
+ Contact me;
+ if (QFile::exists(filename))
+ me = Contact::readVCard( filename )[0];
+
+ abView()->init( me );
+ abView()->sync();
+ abList->hide();
+ setCentralWidget( abView() );
+ mView->show();
+ mView->setFocus();
+}
+
+void AddressbookWindow::editEntry( EntryMode entryMode )
+{
+ Contact entry;
+ if ( bAbEditFirstTime ) {
+ abEditor = new AbEditor( entry, &orderedFields, &slOrderedFields,
+ this, "editor" );
+ bAbEditFirstTime = FALSE;
+ if ( entryMode == EditEntry )
+ abEditor->setEntry( abList->currentEntry() );
+ }
+ // other things may chane the caption.
+ abEditor->setCaption( tr("Edit Address") );
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ abEditor->showMaximized();
+#endif
+ // fix the foxus...
+ abEditor->setNameFocus();
+ if ( abEditor->exec() ) {
+ setFocus();
+ if ( entryMode == NewEntry ) {
+ Contact insertEntry = abEditor->entry();
+ insertEntry.assignUid();
+ abList->addEntry( insertEntry );
+ } else {
+ Contact replaceEntry = abEditor->entry();
+ if ( !replaceEntry.isValidUid() )
+ replaceEntry.assignUid();
+ abList->replaceCurrentEntry( replaceEntry );
+ }
+ }
+ populateCategories();
+ showList();
+}
+
+void AddressbookWindow::listIsEmpty( bool empty )
+{
+ if ( !empty ) {
+ deleteButton->setEnabled( TRUE );
+ }
+}
+
+void AddressbookWindow::reload()
+{
+ syncing = FALSE;
+ abList->clear();
+ abList->load( addressbookXMLFilename() );
+}
+
+void AddressbookWindow::flush()
+{
+ syncing = TRUE;
+ abList->save( addressbookXMLFilename() );
+}
+
+
+void AddressbookWindow::closeEvent( QCloseEvent *e )
+{
+ if ( centralWidget() == mView ) {
+ if (actionPersonal->isOn()) {
+ // pretend we clicked it off
+ actionPersonal->setOn(FALSE);
+ slotPersonalView();
+ } else {
+ showList();
+ }
+ e->ignore();
+ return;
+ }
+
+ if(syncing) {
+ /* shouldn't we save, I hear you say? well its already been set
+ so that an edit can not occur during a sync, and we flushed
+ at the start of the sync, so there is no need to save
+ Saving however itself would cause problems. */
+ e->accept();
+ return;
+ }
+//################## shouldn't always save
+ if ( save() )
+ e->accept();
+ else
+ e->ignore();
+}
+
+/*
+ Returns TRUE if it is OK to exit
+ */
+
+bool AddressbookWindow::save()
+{
+ QString str = addressbookXMLFilename();
+ if ( str.isNull() ) {
+ if ( QMessageBox::critical( 0, tr("Out of space"),
+ tr("Unable to save information.\n"
+ "Free up some space\n"
+ "and try again.\n"
+ "\nQuit anyway?"),
+ QMessageBox::Yes|QMessageBox::Escape,
+ QMessageBox::No|QMessageBox::Default )
+ != QMessageBox::No )
+ return TRUE;
+ else
+ return FALSE;
+ } else {
+ if ( !abList->save( str ) ) {
+ if ( QMessageBox::critical( 0, tr( "Out of space" ),
+ tr("Unable to save information.\n"
+ "Free up some space\n"
+ "and try again.\n"
+ "\nQuit anyway?"),
+ QMessageBox::Yes|QMessageBox::Escape,
+ QMessageBox::No|QMessageBox::Default )
+ != QMessageBox::No )
+ return TRUE;
+ else
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void AddressbookWindow::slotSettings()
+{
+ AddressSettings frmSettings( this );
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ frmSettings.showMaximized();
+#endif
+
+ if ( frmSettings.exec() ) {
+ allFields.clear();
+ orderedFields.clear();
+ slOrderedFields.clear();
+ initFields();
+ if ( abEditor )
+ abEditor->loadFields();
+ abList->refresh();
+ }
+}
+
+
+void AddressbookWindow::initFields()
+{
+ // we really don't need the things from the configuration, anymore
+ // only thing that is important are the important categories. So,
+ // Call the contact functions that correspond to these old functions...
+
+ QStringList xmlFields = Contact::fields();
+ QStringList visibleFields = Contact::trfields();
+ xmlFields.remove( "Title" );
+ visibleFields.remove( tr("Name Title") );
+ visibleFields.remove( tr("Notes") );
+
+ int i,
+ version;
+ Config cfg( "AddressBook" );
+ QString zn;
+
+ // ### Write a function to keep this from happening again...
+ QStringList::ConstIterator it;
+ for ( i = 0, it = xmlFields.begin(); it != xmlFields.end(); ++it, i++ ) {
+ allFields.append( i + 3 );
+ }
+
+ cfg.setGroup( "Version" );
+ version = cfg.readNumEntry( "version" );
+ i = 0;
+ if ( version >= ADDRESSVERSION ) {
+
+ cfg.setGroup( "ImportantCategory" );
+
+ zn = cfg.readEntry( "Category" + QString::number(i), QString::null );
+ while ( !zn.isNull() ) {
+ if ( zn.contains( tr("Work") ) || zn.contains( tr("Mb") ) ) {
+ slOrderedFields.clear();
+ break;
+ }
+ slOrderedFields.append( zn );
+ zn = cfg.readEntry( "Category" + QString::number(++i), QString::null );
+ }
+ } else {
+ QString str;
+ str = getenv("HOME");
+ str += "/Settings/AddressBook.conf";
+ QFile::remove( str );
+ }
+ if ( slOrderedFields.count() > 0 ) {
+ for( QStringList::ConstIterator it = slOrderedFields.begin();
+ it != slOrderedFields.end(); ++it ) {
+ QValueList<int>::ConstIterator itVl;
+ QStringList::ConstIterator itVis;
+ itVl = allFields.begin();
+ for ( itVis = visibleFields.begin();
+ itVis != visibleFields.end() && itVl != allFields.end();
+ ++itVis, ++itVl ) {
+ if ( *it == *itVis && itVl != allFields.end() ) {
+ orderedFields.append( *itVl );
+ }
+ }
+ }
+ } else {
+ QValueList<int>::ConstIterator it;
+ for ( it = allFields.begin(); it != allFields.end(); ++it )
+ orderedFields.append( *it );
+
+ slOrderedFields = visibleFields;
+ orderedFields.remove( Qtopia::AddressUid );
+ orderedFields.remove( Qtopia::Title );
+ orderedFields.remove( Qtopia::Groups );
+ orderedFields.remove( Qtopia::AddressCategory );
+ orderedFields.remove( Qtopia::FirstName );
+ orderedFields.remove( Qtopia::LastName );
+ orderedFields.remove( Qtopia::DefaultEmail );
+ orderedFields.remove( Qtopia::FileAs );
+ orderedFields.remove( Qtopia::Notes );
+ orderedFields.remove( Qtopia::Gender );
+ slOrderedFields.remove( tr("Name Title") );
+ slOrderedFields.remove( tr("First Name") );
+ slOrderedFields.remove( tr("Last Name") );
+ slOrderedFields.remove( tr("File As") );
+ slOrderedFields.remove( tr("Default Email") );
+ slOrderedFields.remove( tr("Notes") );
+ slOrderedFields.remove( tr("Gender") );
+
+ }
+}
+
+
+AbLabel *AddressbookWindow::abView()
+{
+ if ( !mView ) {
+ mView = new AbLabel( this, "viewer" );
+ mView->init( Contact() );
+ connect( mView, SIGNAL( okPressed() ), this, SLOT( slotListView() ) );
+ }
+ return mView;
+}
+
+void AddressbookWindow::slotFind()
+{
+ if ( centralWidget() == abView() )
+ showList();
+ FindDialog frmFind( "Contacts", this );
+ QObject::connect( &frmFind, SIGNAL(signalFindClicked(const QString &, bool, bool, int)), abList, SLOT(slotDoFind( const QString&,bool,bool,int)));
+ QObject::connect( abList, SIGNAL(signalNotFound()), &frmFind, SLOT(slotNotFound()) );
+ QObject::connect( abList, SIGNAL(signalWrapAround()), &frmFind, SLOT(slotWrapAround()) );
+ frmFind.exec();
+ if ( abList->numSelections() )
+ abList->clearSelection();
+ abList->clearFindRow();
+}
+
+void AddressbookWindow::slotSetCategory( int c )
+{
+ if ( c <= 0 )
+ return;
+ for ( unsigned int i = 1; i < catMenu->count(); i++ )
+ catMenu->setItemChecked( i, c == (int)i );
+ if ( c == 1 ) {
+ abList->setShowCategory( QString::null );
+ setCaption( tr("Contacts") + " - " + tr ( "All" ) );
+ } else if ( c == (int)catMenu->count() ) {
+ abList->setShowCategory( tr( "Unfiled" ) );
+ setCaption( tr("Contacts") + " - " + tr( "Unfiled" ) );
+ } else {
+ QString cat = abList->categories()[c - 2];
+ abList->setShowCategory( cat );
+ setCaption( tr("Contacts") + " - " + cat );
+ }
+}
+
+void AddressbookWindow::populateCategories()
+{
+ catMenu->clear();
+
+ int id,
+ rememberId;
+ id = 1;
+ catMenu->insertItem( tr( "All" ), id++ );
+ QStringList categories = abList->categories();
+ categories.append( tr( "Unfiled" ) );
+ for ( QStringList::Iterator it = categories.begin();
+ it != categories.end(); ++it ) {
+ catMenu->insertItem( *it, id );
+ if ( *it == abList->showCategory() )
+ rememberId = id;
+ ++id;
+ }
+ if ( abList->showCategory().isEmpty() )
+ slotSetCategory( 1 );
+ else
+ slotSetCategory( rememberId );
+}
diff --git a/core/pim/addressbook/addressbook.cw b/core/pim/addressbook/addressbook.cw
new file mode 100644
index 0000000..452df36
--- a/dev/null
+++ b/core/pim/addressbook/addressbook.cw
@@ -0,0 +1,26 @@
+<!DOCTYPE CW><CW>
+<customwidgets>
+ <customwidget>
+ <class>AbLineEdit</class>
+ <header location="local">ablineedit.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <pixmap>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </pixmap>
+ </customwidget>
+ <customwidget>
+ <class>AbMultiLineEdit</class>
+ <header location="local">abmultilineedit.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <pixmap>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </pixmap>
+ </customwidget>
+</customwidgets>
+</CW>
diff --git a/core/pim/addressbook/addressbook.h b/core/pim/addressbook/addressbook.h
new file mode 100644
index 0000000..9694465
--- a/dev/null
+++ b/core/pim/addressbook/addressbook.h
@@ -0,0 +1,99 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef Addressbook_H
+#define Addressbook_H
+
+#include <qmainwindow.h>
+
+class AbEditor;
+class AbLabel;
+class AbTable;
+class QPEToolBar;
+class QPopupMenu;
+class QToolButton;
+class QDialog;
+class Ir;
+class QAction;
+
+class AddressbookWindow: public QMainWindow
+{
+ Q_OBJECT
+public:
+ AddressbookWindow( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ ~AddressbookWindow();
+
+protected:
+ void resizeEvent( QResizeEvent * e );
+ void showList();
+ void showView();
+ enum EntryMode { NewEntry=0, EditEntry };
+ void editPersonal();
+ void editEntry( EntryMode );
+ void closeEvent( QCloseEvent *e );
+ bool save();
+
+public slots:
+ void flush();
+ void reload();
+ void appMessage(const QCString &, const QByteArray &);
+ void setDocument( const QString & );
+
+private slots:
+ void slotListNew();
+ void slotListView();
+ void slotListDelete();
+ void slotViewBack();
+ void slotViewEdit();
+ void slotPersonalView();
+ void listIsEmpty( bool );
+ void slotSettings();
+ void writeMail();
+ void slotBeam();
+ void beamDone( Ir * );
+ void slotFind();
+ void slotSetCategory( int );
+ void slotUpdateToolbar();
+
+private:
+ void initFields(); // inititialize our fields...
+ AbLabel *abView();
+ void populateCategories();
+
+ QPopupMenu *catMenu;
+ QPEToolBar *listTools;
+ QToolButton *deleteButton;
+ QValueList<int> allFields,
+ orderedFields;
+ QStringList slOrderedFields;
+ enum Panes { paneList=0, paneView, paneEdit };
+ AbEditor *abEditor;
+ AbLabel *mView;
+ AbTable *abList;
+
+ QAction *actionNew, *actionEdit, *actionTrash, *actionFind, *actionBeam,
+ *actionPersonal, *actionMail;
+
+ bool bAbEditFirstTime;
+ int viewMargin;
+
+ bool syncing;
+};
+
+#endif
diff --git a/core/pim/addressbook/addressbook.pro b/core/pim/addressbook/addressbook.pro
new file mode 100644
index 0000000..8d3401d
--- a/dev/null
+++ b/core/pim/addressbook/addressbook.pro
@@ -0,0 +1,22 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = addressbook.h \
+ abeditor.h \
+ ablabel.h \
+ abtable.h \
+ addresssettings.h
+SOURCES = main.cpp \
+ addressbook.cpp \
+ abeditor.cpp \
+ ablabel.cpp \
+ abtable.cpp \
+ addresssettings.cpp
+INTERFACES = addresssettingsbase.ui
+
+TARGET = addressbook
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TRANSLATIONS = ../i18n/de/addressbook.ts
diff --git a/core/pim/addressbook/addresspicker.cpp b/core/pim/addressbook/addresspicker.cpp
new file mode 100644
index 0000000..79c4d43
--- a/dev/null
+++ b/core/pim/addressbook/addresspicker.cpp
@@ -0,0 +1,52 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "addresspicker.h"
+#include "abtable.h"
+
+#include <qlayout.h>
+
+/*!
+ \a tab is reparented for use in the picker. Take it back out if you want
+ to regain ownership.
+*/
+AddressPicker::AddressPicker(AbTable* tab, QWidget* parent, const char* name, bool modal) :
+ QDialog(parent,name,modal)
+{
+ QVBoxLayout* vb = new QVBoxLayout(this);
+ tab->reparent(this,QPoint(0,0));
+ table = tab;
+ vb->addWidget(table);
+}
+
+void AddressPicker::setChoiceNames(const QStringList& list)
+{
+ table->setChoiceNames(list);
+}
+
+void AddressPicker::setSelection(int index, const QStringList& list)
+{
+ table->setChoiceSelection(index,list);
+}
+
+QStringList AddressPicker::selection(int index) const
+{
+ return table->choiceSelection(index);
+}
diff --git a/core/pim/addressbook/addresspicker.h b/core/pim/addressbook/addresspicker.h
new file mode 100644
index 0000000..8a57479
--- a/dev/null
+++ b/core/pim/addressbook/addresspicker.h
@@ -0,0 +1,39 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef AddressPicker_H
+#define AddressPicker_H
+
+#include <qdialog.h>
+
+class AbTable;
+
+class AddressPicker : public QDialog {
+public:
+ AddressPicker(AbTable* table, QWidget* parent, const char* name=0, bool modal=FALSE);
+
+ void setChoiceNames(const QStringList&);
+ void setSelection(int index, const QStringList&);
+ QStringList selection(int index) const;
+
+private:
+ AbTable* table;
+};
+
+#endif
diff --git a/core/pim/addressbook/addresssettings.cpp b/core/pim/addressbook/addresssettings.cpp
new file mode 100644
index 0000000..e7c2210
--- a/dev/null
+++ b/core/pim/addressbook/addresssettings.cpp
@@ -0,0 +1,136 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+
+#include "addresssettings.h"
+
+#include <qpe/config.h>
+#include <qpe/contact.h>
+
+#include <qfile.h>
+#include <qlistbox.h>
+
+#include <stdlib.h>
+
+AddressSettings::AddressSettings( QWidget *parent, const char *name )
+ : AddressSettingsBase( parent, name, TRUE )
+{
+ init();
+}
+
+AddressSettings::~AddressSettings()
+{
+}
+
+void AddressSettings::init()
+{
+ QStringList slFields = Contact::trfields();
+ // Make this match what is in initFields
+ slFields.remove( tr("Name Title") );
+ slFields.remove( tr("First Name") );
+ slFields.remove( tr("Last Name") );
+ slFields.remove( tr("File As") );
+ slFields.remove( tr("Default Email") );
+ slFields.remove( tr("Notes") );
+ slFields.remove( tr("Gender") );
+
+
+ for( QStringList::Iterator it = slFields.begin();
+ it != slFields.end(); ++it ) {
+ fieldListBox->insertItem( *it );
+ }
+
+ Config cfg( "AddressBook" );
+
+ cfg.setGroup( "Version" );
+ int version;
+ version = cfg.readNumEntry( "version" );
+ if ( version >= ADDRESSVERSION ) {
+ int i = 0;
+ int p = 0;
+ cfg.setGroup( "ImportantCategory" );
+ QString zn = cfg.readEntry( "Category" + QString::number(i),
+ QString::null );
+ while ( !zn.isNull() ) {
+ for ( int m = i; m < (int)fieldListBox->count(); m++ ) {
+ if ( fieldListBox->text( m ) == zn ) {
+ if ( m != p ) {
+ fieldListBox->removeItem( m );
+ fieldListBox->insertItem( zn, p );
+ }
+ p++;
+ break;
+ }
+ }
+ zn = cfg.readEntry( "Category" + QString::number(++i),
+ QString::null );
+ }
+
+ fieldListBox->setCurrentItem( 0 );
+ } else {
+ QString str;
+ str = getenv("HOME");
+
+ str += "/Settings/AddressBook.conf";
+ QFile::remove( str );
+ }
+}
+
+void AddressSettings::itemUp()
+{
+ int i = fieldListBox->currentItem();
+ if ( i > 0 ) {
+ QString item = fieldListBox->currentText();
+ fieldListBox->removeItem( i );
+ fieldListBox->insertItem( item, i-1 );
+ fieldListBox->setCurrentItem( i-1 );
+ }
+}
+
+void AddressSettings::itemDown()
+{
+ int i = fieldListBox->currentItem();
+ if ( i < (int)fieldListBox->count() - 1 ) {
+ QString item = fieldListBox->currentText();
+ fieldListBox->removeItem( i );
+ fieldListBox->insertItem( item, i+1 );
+ fieldListBox->setCurrentItem( i+1 );
+ }
+}
+
+void AddressSettings::accept()
+{
+ save();
+ QDialog::accept();
+}
+
+
+void AddressSettings::save()
+{
+ Config cfg( "AddressBook" );
+ cfg.setGroup( "Version" );
+ // *** To change the version change it here...
+ cfg.writeEntry( "version", QString::number(ADDRESSVERSION) );
+ cfg.setGroup( "ImportantCategory" );
+
+ for ( int i = 0; i < (int)fieldListBox->count(); i++ ) {
+ cfg.writeEntry( "Category"+QString::number(i), fieldListBox->text(i) );
+ }
+}
diff --git a/core/pim/addressbook/addresssettings.h b/core/pim/addressbook/addresssettings.h
new file mode 100644
index 0000000..0fdfa77
--- a/dev/null
+++ b/core/pim/addressbook/addresssettings.h
@@ -0,0 +1,47 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef _ADDRESSSETTINGS_H_
+#define _ADDRESSSETTINGS_H_
+
+#include <qlist.h>
+#include <qstringlist.h>
+#include "addresssettingsbase.h"
+
+const int ADDRESSVERSION = 3;
+
+class AddressSettings : public AddressSettingsBase
+{
+ Q_OBJECT
+public:
+ AddressSettings( QWidget *parent = 0, const char *name = 0 );
+ ~AddressSettings();
+
+protected:
+ void accept();
+ virtual void itemUp();
+ virtual void itemDown();
+
+private:
+ void init();
+ void save();
+};
+
+#endif // _ADDRESSSETTINGS_H_
diff --git a/core/pim/addressbook/addresssettingsbase.ui b/core/pim/addressbook/addresssettingsbase.ui
new file mode 100644
index 0000000..bd3b85b
--- a/dev/null
+++ b/core/pim/addressbook/addresssettingsbase.ui
@@ -0,0 +1,170 @@
+<!DOCTYPE UI><UI>
+<class>AddressSettingsBase</class>
+<comment>/**********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+**********************************************************************/</comment>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>AddressSettingsBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>244</width>
+ <height>207</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Arrange Edit Fields</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>6</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="1" column="0" rowspan="3" colspan="1" >
+ <class>QListBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>fieldListBox</cstring>
+ </property>
+ </widget>
+ <widget row="0" column="0" rowspan="1" colspan="2" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblExplain</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>MShape</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>MShadow</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Select the field order:</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>upButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Up</string>
+ </property>
+ <property stdset="1">
+ <name>autoRepeat</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>downButton</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Down</string>
+ </property>
+ <property stdset="1">
+ <name>autoRepeat</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <spacer row="3" column="1" >
+ <property>
+ <name>name</name>
+ <cstring>Spacer2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>upButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AddressSettingsBase</receiver>
+ <slot>itemUp()</slot>
+ </connection>
+ <connection>
+ <sender>downButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AddressSettingsBase</receiver>
+ <slot>itemDown()</slot>
+ </connection>
+ <slot access="protected">itemUp()</slot>
+ <slot access="protected">itemDown()</slot>
+</connections>
+</UI>
diff --git a/core/pim/addressbook/main.cpp b/core/pim/addressbook/main.cpp
new file mode 100644
index 0000000..2ea1819
--- a/dev/null
+++ b/core/pim/addressbook/main.cpp
@@ -0,0 +1,41 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qt Palmtop Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "addressbook.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/qcopenvelope_qws.h>
+#include <qstring.h>
+
+int main( int argc, char ** argv )
+{
+ QPEApplication a( argc, argv );
+
+ AddressbookWindow mw;
+ QObject::connect( &a, SIGNAL( flush() ), &mw, SLOT( flush() ) );
+ QObject::connect( &a, SIGNAL( reload() ), &mw, SLOT( reload() ) );
+ QObject::connect( &a, SIGNAL( appMessage(const QCString &, const QByteArray &) ),
+ &mw, SLOT( appMessage(const QCString &, const QByteArray &) ) );
+
+ mw.setCaption( AddressbookWindow::tr("Contacts") );
+ a.showMainDocumentWidget(&mw);
+
+ return a.exec();
+}
diff --git a/core/pim/addressbook/qpe-addressbook.control b/core/pim/addressbook/qpe-addressbook.control
new file mode 100644
index 0000000..cca98f3
--- a/dev/null
+++ b/core/pim/addressbook/qpe-addressbook.control
@@ -0,0 +1,9 @@
+Files: bin/addressbook apps/Applications/addressbook.desktop
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Contacts
+ A simple addressbook for the Qtopia environment.
diff --git a/core/pim/datebook/.cvsignore b/core/pim/datebook/.cvsignore
new file mode 100644
index 0000000..4ba477d
--- a/dev/null
+++ b/core/pim/datebook/.cvsignore
@@ -0,0 +1,12 @@
+moc_*
+Makefile
+dateentry.h
+datebookdayheader.h
+dateentry.cpp
+datebookdayheader.cpp
+datebookweekheader.cpp
+datebookweekheader.h
+datebooksettingsbase.h
+datebooksettingsbase.cpp
+repeatentrybase.cpp
+repeatentrybase.h
diff --git a/core/pim/datebook/Makefile.in b/core/pim/datebook/Makefile.in
new file mode 100644
index 0000000..bdc69dc
--- a/dev/null
+++ b/core/pim/datebook/Makefile.in
@@ -0,0 +1,385 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = datebook
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = datebookday.h \
+ datebook.h \
+ dateentryimpl.h \
+ datebookdayheaderimpl.h \
+ datebooksettings.h \
+ datebookweek.h \
+ datebookweekheaderimpl.h \
+ repeatentry.h
+SOURCES = main.cpp \
+ datebookday.cpp \
+ datebook.cpp \
+ dateentryimpl.cpp \
+ datebookdayheaderimpl.cpp \
+ datebooksettings.cpp \
+ datebookweek.cpp \
+ datebookweekheaderimpl.cpp \
+ repeatentry.cpp
+OBJECTS = main.o \
+ datebookday.o \
+ datebook.o \
+ dateentryimpl.o \
+ datebookdayheaderimpl.o \
+ datebooksettings.o \
+ datebookweek.o \
+ datebookweekheaderimpl.o \
+ repeatentry.o \
+ dateentry.o \
+ datebookdayheader.o \
+ datebooksettingsbase.o \
+ datebookweekheader.o \
+ repeatentrybase.o
+INTERFACES = dateentry.ui \
+ datebookdayheader.ui \
+ datebooksettingsbase.ui \
+ datebookweekheader.ui \
+ repeatentrybase.ui
+UICDECLS = dateentry.h \
+ datebookdayheader.h \
+ datebooksettingsbase.h \
+ datebookweekheader.h \
+ repeatentrybase.h
+UICIMPLS = dateentry.cpp \
+ datebookdayheader.cpp \
+ datebooksettingsbase.cpp \
+ datebookweekheader.cpp \
+ repeatentrybase.cpp
+SRCMOC = moc_datebookday.cpp \
+ moc_datebook.cpp \
+ moc_dateentryimpl.cpp \
+ moc_datebookdayheaderimpl.cpp \
+ moc_datebookweek.cpp \
+ moc_datebookweekheaderimpl.cpp \
+ moc_repeatentry.cpp \
+ moc_dateentry.cpp \
+ moc_datebookdayheader.cpp \
+ moc_datebooksettingsbase.cpp \
+ moc_datebookweekheader.cpp \
+ moc_repeatentrybase.cpp
+OBJMOC = moc_datebookday.o \
+ moc_datebook.o \
+ moc_dateentryimpl.o \
+ moc_datebookdayheaderimpl.o \
+ moc_datebookweek.o \
+ moc_datebookweekheaderimpl.o \
+ moc_repeatentry.o \
+ moc_dateentry.o \
+ moc_datebookdayheader.o \
+ moc_datebooksettingsbase.o \
+ moc_datebookweekheader.o \
+ moc_repeatentrybase.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake datebook.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ datebook.h \
+ $(QPEDIR)/include/qpe/datebookdb.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+datebookday.o: datebookday.cpp \
+ datebookday.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ datebookdayheaderimpl.h \
+ datebookdayheader.h \
+ $(QPEDIR)/include/qpe/datebookdb.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/timestring.h \
+ $(QPEDIR)/include/qpe/qpedebug.h
+
+datebook.o: datebook.cpp \
+ datebook.h \
+ $(QPEDIR)/include/qpe/datebookdb.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ datebookday.h \
+ datebooksettings.h \
+ datebooksettingsbase.h \
+ datebookweek.h \
+ dateentryimpl.h \
+ dateentry.h \
+ $(QPEDIR)/include/qpe/datebookmonth.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/qpedebug.h \
+ $(QPEDIR)/include/qpe/finddialog.h \
+ $(QPEDIR)/include/qpe/ir.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ $(QPEDIR)/include/qpe/qpemessagebox.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/sound.h \
+ $(QPEDIR)/include/qpe/timestring.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h \
+ $(QPEDIR)/include/qpe/tzselect.h \
+ $(QPEDIR)/include/qpe/xmlreader.h
+
+dateentryimpl.o: dateentryimpl.cpp \
+ dateentryimpl.h \
+ dateentry.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ repeatentry.h \
+ repeatentrybase.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/categoryselect.h \
+ $(QPEDIR)/include/qpe/datebookmonth.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/timeconversion.h \
+ $(QPEDIR)/include/qpe/timestring.h \
+ $(QPEDIR)/include/qpe/tzselect.h
+
+datebookdayheaderimpl.o: datebookdayheaderimpl.cpp \
+ datebookdayheaderimpl.h \
+ datebookdayheader.h \
+ $(QPEDIR)/include/qpe/datebookmonth.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/timestring.h
+
+datebooksettings.o: datebooksettings.cpp \
+ datebooksettings.h \
+ datebooksettingsbase.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+datebookweek.o: datebookweek.cpp \
+ datebookweek.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ datebookweekheaderimpl.h \
+ datebookweekheader.h \
+ $(QPEDIR)/include/qpe/calendar.h \
+ $(QPEDIR)/include/qpe/datebookdb.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/timestring.h
+
+datebookweekheaderimpl.o: datebookweekheaderimpl.cpp \
+ datebookweekheaderimpl.h \
+ datebookweekheader.h
+
+repeatentry.o: repeatentry.cpp \
+ repeatentry.h \
+ repeatentrybase.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/datebookmonth.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/timestring.h
+
+dateentry.h: dateentry.ui
+ $(UIC) dateentry.ui -o $(INTERFACE_DECL_PATH)/dateentry.h
+
+dateentry.cpp: dateentry.ui
+ $(UIC) dateentry.ui -i dateentry.h -o dateentry.cpp
+
+datebookdayheader.h: datebookdayheader.ui
+ $(UIC) datebookdayheader.ui -o $(INTERFACE_DECL_PATH)/datebookdayheader.h
+
+datebookdayheader.cpp: datebookdayheader.ui
+ $(UIC) datebookdayheader.ui -i datebookdayheader.h -o datebookdayheader.cpp
+
+datebooksettingsbase.h: datebooksettingsbase.ui
+ $(UIC) datebooksettingsbase.ui -o $(INTERFACE_DECL_PATH)/datebooksettingsbase.h
+
+datebooksettingsbase.cpp: datebooksettingsbase.ui
+ $(UIC) datebooksettingsbase.ui -i datebooksettingsbase.h -o datebooksettingsbase.cpp
+
+datebookweekheader.h: datebookweekheader.ui
+ $(UIC) datebookweekheader.ui -o $(INTERFACE_DECL_PATH)/datebookweekheader.h
+
+datebookweekheader.cpp: datebookweekheader.ui
+ $(UIC) datebookweekheader.ui -i datebookweekheader.h -o datebookweekheader.cpp
+
+repeatentrybase.h: repeatentrybase.ui
+ $(UIC) repeatentrybase.ui -o $(INTERFACE_DECL_PATH)/repeatentrybase.h
+
+repeatentrybase.cpp: repeatentrybase.ui
+ $(UIC) repeatentrybase.ui -i repeatentrybase.h -o repeatentrybase.cpp
+
+dateentry.o: dateentry.cpp
+
+datebookdayheader.o: datebookdayheader.cpp
+
+datebooksettingsbase.o: datebooksettingsbase.cpp
+
+datebookweekheader.o: datebookweekheader.cpp
+
+repeatentrybase.o: repeatentrybase.cpp
+
+moc_datebookday.o: moc_datebookday.cpp \
+ datebookday.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h
+
+moc_datebook.o: moc_datebook.cpp \
+ datebook.h \
+ $(QPEDIR)/include/qpe/datebookdb.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h
+
+moc_dateentryimpl.o: moc_dateentryimpl.cpp \
+ dateentryimpl.h \
+ dateentry.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h
+
+moc_datebookdayheaderimpl.o: moc_datebookdayheaderimpl.cpp \
+ datebookdayheaderimpl.h \
+ datebookdayheader.h
+
+moc_datebookweek.o: moc_datebookweek.cpp \
+ datebookweek.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h
+
+moc_datebookweekheaderimpl.o: moc_datebookweekheaderimpl.cpp \
+ datebookweekheaderimpl.h \
+ datebookweekheader.h
+
+moc_repeatentry.o: moc_repeatentry.cpp \
+ repeatentry.h \
+ repeatentrybase.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h
+
+moc_dateentry.o: moc_dateentry.cpp \
+ dateentry.h
+
+moc_datebookdayheader.o: moc_datebookdayheader.cpp \
+ datebookdayheader.h
+
+moc_datebooksettingsbase.o: moc_datebooksettingsbase.cpp \
+ datebooksettingsbase.h
+
+moc_datebookweekheader.o: moc_datebookweekheader.cpp \
+ datebookweekheader.h
+
+moc_repeatentrybase.o: moc_repeatentrybase.cpp \
+ repeatentrybase.h
+
+moc_datebookday.cpp: datebookday.h
+ $(MOC) datebookday.h -o moc_datebookday.cpp
+
+moc_datebook.cpp: datebook.h
+ $(MOC) datebook.h -o moc_datebook.cpp
+
+moc_dateentryimpl.cpp: dateentryimpl.h
+ $(MOC) dateentryimpl.h -o moc_dateentryimpl.cpp
+
+moc_datebookdayheaderimpl.cpp: datebookdayheaderimpl.h
+ $(MOC) datebookdayheaderimpl.h -o moc_datebookdayheaderimpl.cpp
+
+moc_datebookweek.cpp: datebookweek.h
+ $(MOC) datebookweek.h -o moc_datebookweek.cpp
+
+moc_datebookweekheaderimpl.cpp: datebookweekheaderimpl.h
+ $(MOC) datebookweekheaderimpl.h -o moc_datebookweekheaderimpl.cpp
+
+moc_repeatentry.cpp: repeatentry.h
+ $(MOC) repeatentry.h -o moc_repeatentry.cpp
+
+moc_dateentry.cpp: dateentry.h
+ $(MOC) dateentry.h -o moc_dateentry.cpp
+
+moc_datebookdayheader.cpp: datebookdayheader.h
+ $(MOC) datebookdayheader.h -o moc_datebookdayheader.cpp
+
+moc_datebooksettingsbase.cpp: datebooksettingsbase.h
+ $(MOC) datebooksettingsbase.h -o moc_datebooksettingsbase.cpp
+
+moc_datebookweekheader.cpp: datebookweekheader.h
+ $(MOC) datebookweekheader.h -o moc_datebookweekheader.cpp
+
+moc_repeatentrybase.cpp: repeatentrybase.h
+ $(MOC) repeatentrybase.h -o moc_repeatentrybase.cpp
+
+
diff --git a/core/pim/datebook/datebook.cpp b/core/pim/datebook/datebook.cpp
new file mode 100644
index 0000000..6ec6cc2
--- a/dev/null
+++ b/core/pim/datebook/datebook.cpp
@@ -0,0 +1,854 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+**********************************************************************/
+
+#include "datebook.h"
+#include "datebookday.h"
+#include "datebooksettings.h"
+#include "datebookweek.h"
+#include "dateentryimpl.h"
+
+#include <qpe/datebookmonth.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/config.h>
+#include <qpe/qpedebug.h>
+#include <qpe/event.h>
+#include <qpe/finddialog.h>
+#include <qpe/ir.h>
+#include <qpe/qpemenubar.h>
+#include <qpe/qpemessagebox.h>
+#include <qpe/resource.h>
+#include <qpe/sound.h>
+#include <qpe/timestring.h>
+#include <qpe/qpetoolbar.h>
+#include <qpe/tzselect.h>
+#include <qpe/xmlreader.h>
+
+#include <qaction.h>
+#include <qcopchannel_qws.h>
+#include <qdatetime.h>
+#include <qdialog.h>
+#include <qfile.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qmessagebox.h>
+#include <qpopupmenu.h>
+#include <qpushbutton.h>
+#include <qtextcodec.h>
+#include <qtextstream.h>
+#include <qtl.h>
+#include <qwidgetstack.h>
+#include <qwindowsystem_qws.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <stdlib.h>
+
+#define DAY 1
+#define WEEK 2
+#define MONTH 3
+
+
+DateBook::DateBook( QWidget *parent, const char *, WFlags f )
+ : QMainWindow( parent, "datebook", f ),
+ aPreset( FALSE ),
+ presetTime( -1 ),
+ startTime( 8 ), // an acceptable default
+ syncing(FALSE),
+ inSearch(FALSE)
+{
+ QTime t;
+ t.start();
+ db = new DateBookDB;
+ qDebug("loading db t=%d", t.elapsed() );
+ loadSettings();
+ setCaption( tr("Calendar") );
+ setIcon( Resource::loadPixmap( "datebook_icon" ) );
+
+ setToolBarsMovable( FALSE );
+
+ QPEToolBar *bar = new QPEToolBar( this );
+ bar->setHorizontalStretchable( TRUE );
+
+ QPEMenuBar *mb = new QPEMenuBar( bar );
+ mb->setMargin( 0 );
+
+ QPEToolBar *sub_bar = new QPEToolBar(this);
+
+ QPopupMenu *view = new QPopupMenu( this );
+ QPopupMenu *settings = new QPopupMenu( this );
+
+ mb->insertItem( tr( "View" ), view );
+ mb->insertItem( tr( "Settings" ), settings );
+
+ QActionGroup *g = new QActionGroup( this );
+ g->setExclusive( TRUE );
+
+ QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) );
+ a->addTo( sub_bar );
+
+ a = new QAction( tr( "Day" ), Resource::loadPixmap( "day" ), QString::null, 0, g, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( viewDay() ) );
+ a->addTo( sub_bar );
+ a->addTo( view );
+ a->setToggleAction( TRUE );
+ a->setOn( TRUE );
+ dayAction = a;
+ a = new QAction( tr( "Week" ), Resource::loadPixmap( "week" ), QString::null, 0, g, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( viewWeek() ) );
+ a->addTo( sub_bar );
+ a->addTo( view );
+ a->setToggleAction( TRUE );
+ weekAction = a;
+ a = new QAction( tr( "Month" ), Resource::loadPixmap( "month" ), QString::null, 0, g, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( viewMonth() ) );
+ a->addTo( sub_bar );
+ a->addTo( view );
+ a->setToggleAction( TRUE );
+ monthAction = a;
+
+ a = new QAction( tr( "Find" ), Resource::loadPixmap( "mag" ), QString::null, 0, g, 0 );
+ connect( a, SIGNAL(activated()), this, SLOT(slotFind()) );
+ a->addTo( sub_bar );
+
+ a = new QAction( tr( "Today" ), QString::null, 0, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( slotToday() ) );
+ a->addTo( view );
+
+ a = new QAction( tr( "Alarm and Start Time..." ), QString::null, 0, 0 );
+ connect( a, SIGNAL( activated() ), this, SLOT( slotSettings() ) );
+ a->addTo( settings );
+
+ views = new QWidgetStack( this );
+ setCentralWidget( views );
+
+ dayView = 0;
+ weekView = 0;
+ monthView = 0;
+
+ viewDay();
+ connect( qApp, SIGNAL(clockChanged(bool)),
+ this, SLOT(changeClock(bool)) );
+ connect( qApp, SIGNAL(weekChanged(bool)),
+ this, SLOT(changeWeek(bool)) );
+
+#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
+ connect( qApp, SIGNAL(appMessage(const QCString&, const QByteArray&)),
+ this, SLOT(appMessage(const QCString&, const QByteArray&)) );
+#endif
+
+ // listen on QPE/System
+#if defined(Q_WS_QWS)
+#if !defined(QT_NO_COP)
+ QCopChannel *channel = new QCopChannel( "QPE/System", this );
+ connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
+ this, SLOT(receive(const QCString&, const QByteArray&)) );
+#endif
+#endif
+
+ qDebug("done t=%d", t.elapsed() );
+
+}
+
+void DateBook::receive( const QCString &msg, const QByteArray &data )
+{
+ QDataStream stream( data, IO_ReadOnly );
+ if ( msg == "timeChange(QString)" ) {
+ // update active view!
+ if ( dayAction->isOn() )
+ viewDay();
+ else if ( weekAction->isOn() )
+ viewWeek();
+ else if ( monthAction->isOn() )
+ viewMonth();
+ }
+}
+
+DateBook::~DateBook()
+{
+}
+
+void DateBook::slotSettings()
+{
+ DateBookSettings frmSettings( ampm, this );
+ frmSettings.setStartTime( startTime );
+ frmSettings.setAlarmPreset( aPreset, presetTime );
+#if defined (Q_WS_QWS) || defined(_WS_QWS_)
+ frmSettings.showMaximized();
+#endif
+
+ if ( frmSettings.exec() ) {
+ aPreset = frmSettings.alarmPreset();
+ presetTime = frmSettings.presetTime();
+ startTime = frmSettings.startTime();
+ if ( dayView )
+ dayView->setStartViewTime( startTime );
+ if ( weekView )
+ weekView->setStartViewTime( startTime );
+ saveSettings();
+
+ // make the change obvious
+ if ( views->visibleWidget() ) {
+ if ( views->visibleWidget() == dayView )
+ dayView->redraw();
+ else if ( views->visibleWidget() == weekView )
+ weekView->redraw();
+ }
+ }
+}
+
+void DateBook::fileNew()
+{
+ slotNewEventFromKey("");
+}
+
+QString DateBook::checkEvent(const Event &e)
+{
+ /* check if overlaps with itself */
+ bool checkFailed = FALSE;
+
+ /* check the next 12 repeats. should catch most problems */
+ QDate current_date = e.start().date();
+ Event previous = e;
+ for(int i = 0; i < 12; i++)
+ {
+ QDateTime next;
+ if (!nextOccurance(previous, current_date.addDays(1), next)) {
+ break; // no more repeats
+ }
+ if(next < previous.end()) {
+ checkFailed = TRUE;
+ break;
+ }
+ current_date = next.date();
+ }
+
+ if(checkFailed)
+ return tr("Event duration is potentially longer\n"
+ "than interval between repeats.");
+
+ return QString::null;
+}
+
+QDate DateBook::currentDate()
+{
+ QDate d = QDate::currentDate();
+
+ if ( dayView && views->visibleWidget() == dayView ) {
+ d = dayView->date();
+ } else if ( weekView && views->visibleWidget() == weekView ) {
+ d = weekView->date();
+ } else if ( monthView && views->visibleWidget() == monthView ) {
+ d = monthView->selectedDate();
+ }
+
+ return d;
+}
+
+void DateBook::viewDay()
+{
+ initDay();
+ dayAction->setOn( TRUE );
+ QDate d = currentDate();
+ dayView->setDate( d );
+ views->raiseWidget( dayView );
+ dayView->redraw();
+}
+
+void DateBook::viewWeek()
+{
+ initWeek();
+ weekAction->setOn( TRUE );
+ QDate d = currentDate();
+ weekView->setDate( d );
+ views->raiseWidget( weekView );
+ weekView->redraw();
+}
+
+void DateBook::viewMonth()
+{
+ initMonth();
+ monthAction->setOn( TRUE );
+ QDate d = currentDate();
+ monthView->setDate( d.year(), d.month(), d.day() );
+ views->raiseWidget( monthView );
+ monthView->redraw();
+}
+
+void DateBook::editEvent( const Event &e )
+{
+ if (syncing) {
+ QMessageBox::warning( this, tr("Calendar"),
+ tr( "Can not edit data, currently syncing") );
+ return;
+ }
+
+ // workaround added for text input.
+ QDialog editDlg( this, 0, TRUE );
+ DateEntry *entry;
+ editDlg.setCaption( tr("Edit Event") );
+ QVBoxLayout *vb = new QVBoxLayout( &editDlg );
+ QScrollView *sv = new QScrollView( &editDlg, "scrollview" );
+ sv->setResizePolicy( QScrollView::AutoOneFit );
+ // KLUDGE!!!
+ sv->setHScrollBarMode( QScrollView::AlwaysOff );
+ vb->addWidget( sv );
+ entry = new DateEntry( onMonday, e, ampm, &editDlg, "editor" );
+ entry->timezone->setEnabled( FALSE );
+ sv->addChild( entry );
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ editDlg.showMaximized();
+#endif
+ while (editDlg.exec() ) {
+ Event newEv = entry->event();
+ QString error = checkEvent(newEv);
+ if (!error.isNull()) {
+ if (QMessageBox::warning(this, "error box",
+ error, "Fix it", "Continue", 0, 0, 1) == 0)
+ continue;
+ }
+ db->editEvent(e, newEv);
+ emit newEvent();
+ break;
+ }
+}
+
+void DateBook::removeEvent( const Event &e )
+{
+ if (syncing) {
+ QMessageBox::warning( this, tr("Calendar"),
+ tr( "Can not edit data, currently syncing") );
+ return;
+ }
+
+ QString strName = e.description();
+
+ if ( !QPEMessageBox::confirmDelete( this, tr( "Calendar" ),strName ) )
+ return;
+
+ db->removeEvent( e );
+ if ( views->visibleWidget() == dayView && dayView )
+ dayView->redraw();
+}
+
+void DateBook::addEvent( const Event &e )
+{
+ QDate d = e.start().date();
+ initDay();
+ dayView->setDate( d );
+}
+
+void DateBook::showDay( int year, int month, int day )
+{
+ initDay();
+ dayView->setDate( year, month, day );
+ views->raiseWidget( dayView );
+ dayAction->setOn( TRUE );
+}
+
+void DateBook::initDay()
+{
+ if ( !dayView ) {
+ dayView = new DateBookDay( ampm, onMonday, db, views, "day view" );
+ views->addWidget( dayView, DAY );
+ dayView->setStartViewTime( startTime );
+ connect( this, SIGNAL( newEvent() ),
+ dayView, SLOT( redraw() ) );
+ connect( dayView, SIGNAL( newEvent() ),
+ this, SLOT( fileNew() ) );
+ connect( dayView, SIGNAL( removeEvent( const Event & ) ),
+ this, SLOT( removeEvent( const Event & ) ) );
+ connect( dayView, SIGNAL( editEvent( const Event & ) ),
+ this, SLOT( editEvent( const Event & ) ) );
+ connect( dayView, SIGNAL( beamEvent( const Event & ) ),
+ this, SLOT( beamEvent( const Event & ) ) );
+ connect( dayView, SIGNAL(sigNewEvent(const QString &)),
+ this, SLOT(slotNewEventFromKey(const QString &)) );
+ }
+}
+
+void DateBook::initWeek()
+{
+ if ( !weekView ) {
+ weekView = new DateBookWeek( ampm, onMonday, db, views, "week view" );
+ weekView->setStartViewTime( startTime );
+ views->addWidget( weekView, WEEK );
+ connect( weekView, SIGNAL( showDate( int, int, int ) ),
+ this, SLOT( showDay( int, int, int ) ) );
+ connect( this, SIGNAL( newEvent() ),
+ weekView, SLOT( redraw() ) );
+ }
+ //But also get it right: the year that we display can be different
+ //from the year of the current date. So, first find the year
+ //number of the current week.
+
+ int yearNumber, totWeeks;
+ calcWeek( currentDate(), totWeeks, yearNumber, onMonday );
+
+ QDate d = QDate( yearNumber, 12, 31 );
+ calcWeek( d, totWeeks, yearNumber, onMonday );
+
+ while ( totWeeks == 1 ) {
+ d = d.addDays( -1 );
+ calcWeek( d, totWeeks, yearNumber, onMonday );
+ }
+ if ( totWeeks != weekView->totalWeeks() )
+ weekView->setTotalWeeks( totWeeks );
+}
+
+void DateBook::initMonth()
+{
+ if ( !monthView ) {
+ monthView = new DateBookMonth( views, "month view", FALSE, db );
+ views->addWidget( monthView, MONTH );
+ connect( monthView, SIGNAL( dateClicked( int, int, int ) ),
+ this, SLOT( showDay( int, int, int ) ) );
+ connect( this, SIGNAL( newEvent() ),
+ monthView, SLOT( redraw() ) );
+ qApp->processEvents();
+ }
+}
+
+void DateBook::loadSettings()
+{
+ {
+ Config config( "qpe" );
+ config.setGroup("Time");
+ ampm = config.readBoolEntry( "AMPM", TRUE );
+ onMonday = config.readBoolEntry( "MONDAY" );
+ }
+
+ {
+ Config config("DateBook");
+ config.setGroup("Main");
+ startTime = config.readNumEntry("startviewtime", 8);
+ aPreset = config.readBoolEntry("alarmpreset");
+ presetTime = config.readNumEntry("presettime");
+ }
+}
+
+void DateBook::saveSettings()
+{
+ Config config( "qpe" );
+ Config configDB( "DateBook" );
+ configDB.setGroup( "Main" );
+ configDB.writeEntry("startviewtime",startTime);
+ configDB.writeEntry("alarmpreset",aPreset);
+ configDB.writeEntry("presettime",presetTime);
+}
+
+void DateBook::appMessage(const QCString& msg, const QByteArray& data)
+{
+ bool needShow = FALSE;
+ if ( msg == "alarm(QDateTime,int)" ) {
+ QDataStream ds(data,IO_ReadOnly);
+ QDateTime when; int warn;
+ ds >> when >> warn;
+
+ // check to make it's okay to continue,
+ // this is the case that the time was set ahead, and
+ // we are forced given a stale alarm...
+ QDateTime current = QDateTime::currentDateTime();
+ if ( current.time().hour() != when.time().hour()
+ && current.time().minute() != when.time().minute() )
+ return;
+
+ QValueList<EffectiveEvent> list = db->getEffectiveEvents(when.addSecs(warn*60));
+ if ( list.count() > 0 ) {
+ QString msg;
+ bool bSound = FALSE;
+ int stopTimer = 0;
+ bool found = FALSE;
+ for ( QValueList<EffectiveEvent>::ConstIterator it=list.begin();
+ it!=list.end(); ++it ) {
+ if ( (*it).event().hasAlarm() ) {
+ found = TRUE;
+ msg += "<CENTER><B>" + (*it).description() + "</B>"
+ + "<BR>" + (*it).location() + "<BR>"
+ + TimeString::dateString((*it).event().start(),ampm)
+ + (warn
+ ? tr(" (in " + QString::number(warn)
+ + tr(" minutes)"))
+ : QString(""))
+ + "<BR>"
+ + (*it).notes() + "</CENTER>";
+ if ( (*it).event().alarmSound() != Event::Silent ) {
+ bSound = TRUE;
+ }
+ }
+ }
+ if ( found ) {
+ if ( bSound ) {
+ Sound::soundAlarm();
+ stopTimer = startTimer( 5000 );
+ }
+
+ QDialog dlg( this, 0, TRUE );
+ QVBoxLayout *vb = new QVBoxLayout( &dlg );
+ QScrollView *view = new QScrollView( &dlg, "scrollView");
+ view->setResizePolicy( QScrollView::AutoOneFit );
+ vb->addWidget( view );
+ QLabel *lblMsg = new QLabel( msg, &dlg );
+ view->addChild( lblMsg );
+ QPushButton *cmdOk = new QPushButton( tr("OK"), &dlg );
+ connect( cmdOk, SIGNAL(clicked()), &dlg, SLOT(accept()) );
+ vb->addWidget( cmdOk );
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ dlg.showMaximized();
+#endif
+ needShow = dlg.exec();
+
+ if ( bSound )
+ killTimer( stopTimer );
+ }
+ }
+ } else if ( msg == "nextView()" ) {
+ QWidget* cur = views->visibleWidget();
+ if ( cur ) {
+ if ( cur == dayView )
+ viewWeek();
+ else if ( cur == weekView )
+ viewMonth();
+ else if ( cur == monthView )
+ viewDay();
+ needShow = TRUE;
+ }
+ }
+ if ( needShow ) {
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ showMaximized();
+#else
+ show();
+#endif
+ raise();
+ QPEApplication::setKeepRunning();
+ setActiveWindow();
+ }
+}
+
+void DateBook::reload()
+{
+ db->reload();
+ if ( dayAction->isOn() )
+ viewDay();
+ else if ( weekAction->isOn() )
+ viewWeek();
+ else if ( monthAction->isOn() )
+ viewMonth();
+ syncing = FALSE;
+}
+
+void DateBook::flush()
+{
+ syncing = TRUE;
+ db->save();
+}
+
+void DateBook::timerEvent( QTimerEvent *e )
+{
+ static int stop = 0;
+ if ( stop < 10 ) {
+ Sound::soundAlarm();
+ stop++;
+ } else {
+ stop = 0;
+ killTimer( e->timerId() );
+ }
+}
+
+void DateBook::changeClock( bool newClock )
+{
+ ampm = newClock;
+ // repaint the affected objects...
+ if (dayView) dayView->redraw();
+ if (weekView) weekView->redraw();
+}
+
+void DateBook::changeWeek( bool m )
+{
+ /* no need to redraw, each widget catches. Do need to
+ store though for widgets we haven't made yet */
+ onMonday = m;
+}
+
+void DateBook::slotToday()
+{
+ // we need to view today
+ QDate dt = QDate::currentDate();
+ showDay( dt.year(), dt.month(), dt.day() );
+}
+
+void DateBook::closeEvent( QCloseEvent *e )
+{
+ if(syncing) {
+ /* no need to save, did that at flush */
+ e->accept();
+ return;
+ }
+
+ // save settings will generate it's own error messages, no
+ // need to do checking ourselves.
+ saveSettings();
+ if ( db->save() )
+ e->accept();
+ else {
+ if ( QMessageBox::critical( this, tr( "Out of space" ),
+ tr("Calendar was unable to save\n"
+ "your changes.\n"
+ "Free up some space and try again.\n"
+ "\nQuit anyway?"),
+ QMessageBox::Yes|QMessageBox::Escape,
+ QMessageBox::No|QMessageBox::Default )
+ != QMessageBox::No )
+ e->accept();
+ else
+ e->ignore();
+ }
+}
+
+// Entering directly from the "keyboard"
+void DateBook::slotNewEventFromKey( const QString &str )
+{
+ if (syncing) {
+ QMessageBox::warning( this, tr("Calendar"),
+ tr( "Can not edit data, currently syncing") );
+ return;
+ }
+
+ // We get to here from a key pressed in the Day View
+ // So we can assume some things. We want the string
+ // passed in to be part of the description.
+ QDateTime start, end;
+ if ( views->visibleWidget() == dayView ) {
+ dayView->selectedDates( start, end );
+ } else if ( views->visibleWidget() == monthView ) {
+ QDate d = monthView->selectedDate();
+ start = end = d;
+ start.setTime( QTime( 10, 0 ) );
+ end.setTime( QTime( 12, 0 ) );
+ } else if ( views->visibleWidget() == weekView ) {
+ QDate d = weekView->date();
+ start = end = d;
+ start.setTime( QTime( 10, 0 ) );
+ end.setTime( QTime( 12, 0 ) );
+ }
+
+ // argh! This really needs to be encapsulated in a class
+ // or function.
+ QDialog newDlg( this, 0, TRUE );
+ newDlg.setCaption( DateEntryBase::tr("New Event") );
+ DateEntry *e;
+ QVBoxLayout *vb = new QVBoxLayout( &newDlg );
+ QScrollView *sv = new QScrollView( &newDlg );
+ sv->setResizePolicy( QScrollView::AutoOneFit );
+ sv->setFrameStyle( QFrame::NoFrame );
+ sv->setHScrollBarMode( QScrollView::AlwaysOff );
+ vb->addWidget( sv );
+
+ Event ev;
+ ev.setDescription( str );
+ // When the new gui comes in, change this...
+ ev.setLocation( tr("(Unknown)") );
+ ev.setStart( start );
+ ev.setEnd( end );
+
+ e = new DateEntry( onMonday, ev, ampm, &newDlg );
+ e->setAlarmEnabled( aPreset, presetTime, Event::Loud );
+ sv->addChild( e );
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ newDlg.showMaximized();
+#endif
+ while (newDlg.exec()) {
+ ev = e->event();
+ ev.assignUid();
+ QString error = checkEvent( ev );
+ if ( !error.isNull() ) {
+ if ( QMessageBox::warning( this, tr("Error!"),
+ error, tr("Fix it"), tr("Continue"), 0, 0, 1 ) == 0 )
+ continue;
+ }
+ db->addEvent( ev );
+ emit newEvent();
+ break;
+ }
+}
+
+void DateBook::setDocument( const QString &filename )
+{
+ if ( filename.find(".vcs") != int(filename.length()) - 4 ) return;
+
+ QValueList<Event> tl = Event::readVCalendar( filename );
+ for( QValueList<Event>::Iterator it = tl.begin(); it != tl.end(); ++it ) {
+ db->addEvent( *it );
+ }
+}
+
+static const char * beamfile = "/tmp/obex/event.vcs";
+
+void DateBook::beamEvent( const Event &e )
+{
+ qDebug("trying to beamn");
+ unlink( beamfile ); // delete if exists
+ mkdir("/tmp/obex/", 0755);
+ Event::writeVCalendar( beamfile, e );
+ Ir *ir = new Ir( this );
+ connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
+ QString description = e.description();
+ ir->send( beamfile, description, "text/x-vCalendar" );
+}
+
+void DateBook::beamDone( Ir *ir )
+{
+ delete ir;
+ unlink( beamfile );
+}
+
+void DateBook::slotFind()
+{
+ // move it to the day view...
+ viewDay();
+ FindDialog frmFind( "Calendar", this );
+ frmFind.setUseDate( true );
+ frmFind.setDate( currentDate() );
+ QObject::connect( &frmFind,
+ SIGNAL(signalFindClicked(const QString&, const QDate&,
+ bool, bool, int)),
+ this,
+ SLOT(slotDoFind(const QString&, const QDate&,
+ bool, bool, int)) );
+ QObject::connect( this,
+ SIGNAL(signalNotFound()),
+ &frmFind,
+ SLOT(slotNotFound()) );
+ QObject::connect( this,
+ SIGNAL(signalWrapAround()),
+ &frmFind,
+ SLOT(slotWrapAround()) );
+ frmFind.exec();
+ inSearch = false;
+}
+
+bool catComp( QArray<int> cats, int category )
+{
+ bool returnMe;
+ int i,
+ count;
+
+ count = int(cats.count());
+ returnMe = false;
+ if ( (category == -1 && count == 0) || category == -2 )
+ returnMe = true;
+ else {
+ for ( i = 0; i < count; i++ ) {
+ if ( category == cats[i] ) {
+ returnMe = true;
+ break;
+ }
+ }
+ }
+ return returnMe;
+}
+
+
+void DateBook::slotDoFind( const QString& txt, const QDate &dt,
+ bool caseSensitive, bool /*backwards*/,
+ int category )
+{
+ QDateTime dtEnd( QDate(3001, 1, 1), QTime(0, 0, 0) ),
+ next;
+
+ QRegExp r( txt );
+ r.setCaseSensitive( caseSensitive );
+
+
+ static Event rev,
+ nonrev;
+ if ( !inSearch ) {
+ rev.setStart( QDateTime(QDate(1960, 1, 1), QTime(0, 0, 0)) );
+ nonrev.setStart( rev.start() );
+ inSearch = true;
+ }
+ static QDate searchDate = dt;
+ static bool wrapAround = true;
+ bool candidtate;
+ candidtate = false;
+
+ QValueList<Event> repeats = db->getRawRepeats();
+
+ // find the candidate for the first repeat that matches...
+ QValueListConstIterator<Event> it;
+ QDate start = dt;
+ for ( it = repeats.begin(); it != repeats.end(); ++it ) {
+ if ( catComp( (*it).categories(), category ) ) {
+ while ( nextOccurance( *it, start, next ) ) {
+ if ( next < dtEnd ) {
+ if ( (*it).match( r ) && !(next <= rev.start()) ) {
+ rev = *it;
+ dtEnd = next;
+ rev.setStart( next );
+ candidtate = true;
+ wrapAround = true;
+ start = dt;
+ break;
+ } else
+ start = next.date().addDays( 1 );
+ }
+ }
+ }
+ }
+
+ // now the for first non repeat...
+ QValueList<Event> nonRepeats = db->getNonRepeatingEvents( dt, dtEnd.date() );
+ qHeapSort( nonRepeats.begin(), nonRepeats.end() );
+ for ( it = nonRepeats.begin(); it != nonRepeats.end(); ++it ) {
+ if ( catComp( (*it).categories(), category ) ) {
+ if ( (*it).start() < dtEnd ) {
+ if ( (*it).match( r ) && !(*it <= nonrev) ) {
+ nonrev = *it;
+ dtEnd = nonrev.start();
+ candidtate = true;
+ wrapAround = true;
+ break;
+ }
+ }
+ }
+ }
+ if ( candidtate ) {
+ dayView->setStartViewTime( dtEnd.time().hour() );
+ dayView->setDate( dtEnd.date().year(), dtEnd.date().month(),
+ dtEnd.date().day() );
+ } else {
+ if ( wrapAround ) {
+ emit signalWrapAround();
+ rev.setStart( QDateTime(QDate(1960, 1, 1), QTime(0, 0, 0)) );
+ nonrev.setStart( rev.start() );
+ } else
+ emit signalNotFound();
+ wrapAround = !wrapAround;
+ }
+}
diff --git a/core/pim/datebook/datebook.h b/core/pim/datebook/datebook.h
new file mode 100644
index 0000000..44627bb
--- a/dev/null
+++ b/core/pim/datebook/datebook.h
@@ -0,0 +1,111 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef DATEBOOK_H
+#define DATEBOOK_H
+
+#include <qpe/datebookdb.h>
+
+#include <qmainwindow.h>
+
+class QAction;
+class QWidgetStack;
+class DateBookDay;
+class DateBookWeek;
+class DateBookMonth;
+class Event;
+class QDate;
+class Ir;
+
+class DateBook : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ DateBook( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ ~DateBook();
+
+signals:
+ void newEvent();
+ void signalNotFound();
+ void signalWrapAround();
+
+protected:
+ QDate currentDate();
+ void timerEvent( QTimerEvent *e );
+ void closeEvent( QCloseEvent *e );
+
+public slots:
+ void flush();
+ void reload();
+
+private slots:
+ void fileNew();
+ void slotSettings();
+ void slotToday(); // view today
+ void changeClock( bool newClock );
+ void changeWeek( bool newDay );
+ void appMessage(const QCString& msg, const QByteArray& data);
+ // handle key events in the day view...
+ void slotNewEventFromKey( const QString &str );
+ void slotFind();
+ void slotDoFind( const QString &, const QDate &, bool, bool, int );
+
+ void viewDay();
+ void viewWeek();
+ void viewMonth();
+
+ void showDay( int y, int m, int d );
+
+ void editEvent( const Event &e );
+ void removeEvent( const Event &e );
+
+ void receive( const QCString &msg, const QByteArray &data );
+ void setDocument( const QString & );
+ void beamEvent( const Event &e );
+ void beamDone( Ir *ir );
+
+private:
+ void addEvent( const Event &e );
+ void initDay();
+ void initWeek();
+ void initMonth();
+ void loadSettings();
+ void saveSettings();
+
+private:
+ DateBookDB *db;
+ QWidgetStack *views;
+ DateBookDay *dayView;
+ DateBookWeek *weekView;
+ DateBookMonth *monthView;
+ QAction *dayAction, *weekAction, *monthAction;
+ bool aPreset; // have everything set to alarm?
+ int presetTime; // the standard time for the alarm
+ int startTime;
+ bool ampm;
+ bool onMonday;
+
+ bool syncing;
+ bool inSearch;
+
+ QString checkEvent(const Event &);
+};
+
+#endif
diff --git a/core/pim/datebook/datebook.pro b/core/pim/datebook/datebook.pro
new file mode 100644
index 0000000..17c02ec
--- a/dev/null
+++ b/core/pim/datebook/datebook.pro
@@ -0,0 +1,36 @@
+TEMPLATE = app
+CONFIG += qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+
+HEADERS = datebookday.h \
+ datebook.h \
+ dateentryimpl.h \
+ datebookdayheaderimpl.h \
+ datebooksettings.h \
+ datebookweek.h \
+ datebookweekheaderimpl.h \
+ repeatentry.h
+
+SOURCES = main.cpp \
+ datebookday.cpp \
+ datebook.cpp \
+ dateentryimpl.cpp \
+ datebookdayheaderimpl.cpp \
+ datebooksettings.cpp \
+ datebookweek.cpp \
+ datebookweekheaderimpl.cpp \
+ repeatentry.cpp
+
+INTERFACES = dateentry.ui \
+ datebookdayheader.ui \
+ datebooksettingsbase.ui \
+ datebookweekheader.ui \
+ repeatentrybase.ui
+
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TARGET = datebook
+
+TRANSLATIONS = ../i18n/de/datebook.ts
diff --git a/core/pim/datebook/datebookday.cpp b/core/pim/datebook/datebookday.cpp
new file mode 100644
index 0000000..d5daab2
--- a/dev/null
+++ b/core/pim/datebook/datebookday.cpp
@@ -0,0 +1,553 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "datebookday.h"
+#include "datebookdayheaderimpl.h"
+
+#include <qpe/datebookdb.h>
+#include <qpe/resource.h>
+#include <qpe/event.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/timestring.h>
+#include <qpe/qpedebug.h>
+
+#include <qheader.h>
+#include <qdatetime.h>
+#include <qpainter.h>
+#include <qsimplerichtext.h>
+#include <qpopupmenu.h>
+#include <qtextcodec.h>
+#include <qpalette.h>
+
+DateBookDayView::DateBookDayView( bool whichClock, QWidget *parent,
+ const char *name )
+ : QTable( 24, 1, parent, name ),
+ ampm( whichClock )
+{
+ enableClipper(TRUE);
+ setTopMargin( 0 );
+ horizontalHeader()->hide();
+ setLeftMargin(38);
+ setColumnStretchable( 0, TRUE );
+ setHScrollBarMode( QScrollView::AlwaysOff );
+ verticalHeader()->setPalette(white);
+ verticalHeader()->setResizeEnabled(FALSE);
+ setSelectionMode( Single );
+
+ // get rid of being able to edit things...
+ QTableItem *tmp;
+ int row;
+ for ( row = 0; row < numRows(); row++ ) {
+ tmp = new QTableItem( this, QTableItem::Never, QString::null);
+ setItem( row, 0, tmp );
+ }
+ initHeader();
+ QObject::connect( qApp, SIGNAL(clockChanged(bool)),
+ this, SLOT(slotChangeClock(bool)) );
+}
+
+void DateBookDayView::initHeader()
+{
+ QString strTmp;
+ for ( int i = 0; i < 24; ++i ) {
+ if ( ampm ) {
+ if ( i == 0 )
+ strTmp = QString::number(12) + ":00";
+ else if ( i == 12 )
+ strTmp = QString::number(12) + tr(":00p");
+ else if ( i > 12 )
+ strTmp = QString::number( i - 12 ) + tr(":00p");
+ else
+ strTmp = QString::number(i) + ":00";
+ } else {
+ if ( i < 10 )
+ strTmp = "0" + QString::number(i) + ":00";
+ else
+ strTmp = QString::number(i) + ":00";
+ }
+ strTmp = strTmp.rightJustify( 6, ' ' );
+ verticalHeader()->setLabel( i, strTmp );
+ setRowStretchable( i, FALSE );
+ }
+}
+
+void DateBookDayView::slotChangeClock( bool newClock )
+{
+ ampm = newClock;
+ initHeader();
+}
+
+bool DateBookDayView::whichClock() const
+{
+ return ampm;
+}
+
+void DateBookDayView::moveUp()
+{
+ scrollBy(0, -20);
+}
+
+void DateBookDayView::moveDown()
+{
+ scrollBy(0, 20);
+}
+
+void DateBookDayView::paintCell( QPainter *p, int, int, const QRect &cr, bool )
+{
+ int w = cr.width();
+ int h = cr.height();
+ p->fillRect( 0, 0, w, h, colorGroup().brush( QColorGroup::Base ) );
+ if ( showGrid() ) {
+ // Draw our lines
+ int x2 = w - 1;
+ int y2 = h - 1;
+ QPen pen( p->pen() );
+ p->setPen( colorGroup().mid() );
+ p->drawLine( x2, 0, x2, y2 );
+ p->drawLine( 0, y2, x2, y2 );
+ p->setPen( pen );
+ }
+}
+
+void DateBookDayView::paintFocus( QPainter *, const QRect & )
+{
+}
+
+
+void DateBookDayView::resizeEvent( QResizeEvent *e )
+{
+ QTable::resizeEvent( e );
+ columnWidthChanged( 0 );
+ emit sigColWidthChanged();
+}
+
+void DateBookDayView::keyPressEvent( QKeyEvent *e )
+{
+ QString txt = e->text();
+ if ( !txt.isNull() && txt[0] > ' ' && e->key() < 0x1000 ) {
+ // we this is some sort of thing we know about...
+ e->accept();
+ emit sigCapturedKey( txt );
+ } else {
+ // I don't know what this key is, do you?
+ e->ignore();
+ }
+}
+
+
+//===========================================================================
+
+DateBookDay::DateBookDay( bool ampm, bool startOnMonday,
+ DateBookDB *newDb, QWidget *parent,
+ const char *name )
+ : QVBox( parent, name ),
+ currDate( QDate::currentDate() ),
+ db( newDb ),
+ startTime( 0 )
+{
+ widgetList.setAutoDelete( true );
+ header = new DateBookDayHeader( startOnMonday, this, "day header" );
+ header->setDate( currDate.year(), currDate.month(), currDate.day() );
+ view = new DateBookDayView( ampm, this, "day view" );
+ connect( header, SIGNAL( dateChanged( int, int, int ) ),
+ this, SLOT( dateChanged( int, int, int ) ) );
+ connect( view, SIGNAL( sigColWidthChanged() ),
+ this, SLOT( slotColWidthChanged() ) );
+ connect( qApp, SIGNAL(weekChanged(bool)),
+ this, SLOT(slotWeekChanged(bool)) );
+ connect( view, SIGNAL(sigCapturedKey(const QString &)),
+ this, SIGNAL(sigNewEvent(const QString&)) );
+}
+
+void DateBookDay::selectedDates( QDateTime &start, QDateTime &end )
+{
+ start.setDate( currDate );
+ end.setDate( currDate );
+
+ int sh=99,eh=-1;
+
+ int n = dayView()->numSelections();
+
+ for (int i=0; i<n; i++) {
+ QTableSelection sel = dayView()->selection( i );
+ sh = QMIN(sh,sel.topRow());
+ eh = QMAX(sh,sel.bottomRow()+1);
+ }
+ if (sh > 23 || eh < 1) {
+ sh=8;
+ eh=9;
+ }
+
+ start.setTime( QTime( sh, 0, 0 ) );
+ end.setTime( QTime( eh, 0, 0 ) );
+}
+
+void DateBookDay::setDate( int y, int m, int d )
+{
+ header->setDate( y, m, d );
+}
+
+void DateBookDay::setDate( QDate d)
+{
+ header->setDate( d.year(), d.month(), d.day() );
+}
+
+void DateBookDay::dateChanged( int y, int m, int d )
+{
+ QDate date( y, m, d );
+ if ( currDate == date )
+ return;
+ currDate.setYMD( y, m, d );
+ relayoutPage();
+ dayView()->clearSelection();
+ QTableSelection ts;
+ ts.init( startTime, 0 );
+ ts.expandTo( startTime, 0 );
+ dayView()->addSelection( ts );
+}
+
+void DateBookDay::redraw()
+{
+ if ( isUpdatesEnabled() )
+ relayoutPage();
+}
+
+void DateBookDay::getEvents()
+{
+ widgetList.clear();
+
+ QValueList<EffectiveEvent> eventList = db->getEffectiveEvents( currDate,
+ currDate );
+ QValueListIterator<EffectiveEvent> it;
+ for ( it = eventList.begin(); it != eventList.end(); ++it ) {
+ DateBookDayWidget* w = new DateBookDayWidget( *it, this );
+ connect( w, SIGNAL( deleteMe( const Event & ) ),
+ this, SIGNAL( removeEvent( const Event & ) ) );
+ connect( w, SIGNAL( editMe( const Event & ) ),
+ this, SIGNAL( editEvent( const Event & ) ) );
+ connect( w, SIGNAL( beamMe( const Event & ) ),
+ this, SIGNAL( beamEvent( const Event & ) ) );
+ widgetList.append( w );
+ }
+}
+
+static int place( const DateBookDayWidget *item, bool *used, int maxn )
+{
+ int place = 0;
+ int start = item->event().start().hour();
+ QTime e = item->event().end();
+ int end = e.hour();
+ if ( e.minute() < 5 )
+ end--;
+ if ( end < start )
+ end = start;
+ while ( place < maxn ) {
+ bool free = TRUE;
+ int s = start;
+ while( s <= end ) {
+ if ( used[10*s+place] ) {
+ free = FALSE;
+ break;
+ }
+ s++;
+ }
+ if ( free ) break;
+ place++;
+ }
+ if ( place == maxn ) {
+ return -1;
+ }
+ while( start <= end ) {
+ used[10*start+place] = TRUE;
+ start++;
+ }
+ return place;
+}
+
+
+void DateBookDay::relayoutPage( bool fromResize )
+{
+ setUpdatesEnabled( FALSE );
+ if ( !fromResize )
+ getEvents(); // no need we already have them!
+
+ int wCount = widgetList.count();
+ int wid = view->columnWidth(0)-1;
+ int n = 1;
+
+ if ( wCount < 20 ) {
+ for ( int i = 0; i < wCount; ) {
+ DateBookDayWidget *w = widgetList.at(i);
+ int x = 0;
+ int xp = 0;
+ QRect geom = w->geometry();
+ geom.setX( x );
+ geom.setWidth( wid );
+ while ( xp < n && intersects( w, geom ) ) {
+ x += wid;
+ xp++;
+ geom.moveBy( wid, 0 );
+ }
+ if ( xp >= n ) {
+ n++;
+ wid = ( view->columnWidth(0)-1 ) / n;
+ i = 0;
+ } else {
+ w->setGeometry( geom );
+ i++;
+ }
+ }
+ view->setContentsPos( 0, startTime * view->rowHeight(0) );
+ } else {
+
+
+ int hours[24];
+ memset( hours, 0, 24*sizeof( int ) );
+ bool overFlow = FALSE;
+ for ( int i = 0; i < wCount; i++ ) {
+ DateBookDayWidget *w = widgetList.at(i);
+ int start = w->event().start().hour();
+ QTime e = w->event().end();
+ int end = e.hour();
+ if ( e.minute() < 5 )
+ end--;
+ if ( end < start )
+ end = start;
+ while( start <= end ) {
+ hours[start]++;
+ if ( hours[start] >= 10 )
+ overFlow = TRUE;
+ ++start;
+ }
+ if ( overFlow )
+ break;
+ }
+ for ( int i = 0; i < 24; i++ ) {
+ n = QMAX( n, hours[i] );
+ }
+ wid = ( view->columnWidth(0)-1 ) / n;
+
+ bool used[24*10];
+ memset( used, FALSE, 24*10*sizeof( bool ) );
+
+ for ( int i = 0; i < wCount; i++ ) {
+ DateBookDayWidget *w = widgetList.at(i);
+ int xp = place( w, used, n );
+ if ( xp != -1 ) {
+ QRect geom = w->geometry();
+ geom.setX( xp*wid );
+ geom.setWidth( wid );
+ w->setGeometry( geom );
+ }
+ }
+ view->setContentsPos( 0, startTime * view->rowHeight(0) );
+ }
+ setUpdatesEnabled( TRUE );
+ return;
+}
+
+DateBookDayWidget *DateBookDay::intersects( const DateBookDayWidget *item, const QRect &geom )
+{
+ int i = 0;
+ DateBookDayWidget *w = widgetList.at(i);
+ int wCount = widgetList.count();
+ while ( i < wCount && w != item ) {
+ if ( w->geometry().intersects( geom ) ) {
+ return w;
+ }
+ w = widgetList.at(++i);
+ }
+
+ return 0;
+}
+
+
+QDate DateBookDay::date() const
+{
+ return currDate;
+}
+
+void DateBookDay::setStartViewTime( int startHere )
+{
+ startTime = startHere;
+ dayView()->clearSelection();
+ QTableSelection ts;
+ ts.init( startTime, 0 );
+ ts.expandTo( startTime, 0 );
+ dayView()->addSelection( ts );
+}
+
+int DateBookDay::startViewTime() const
+{
+ return startTime;
+}
+
+void DateBookDay::slotWeekChanged( bool bStartOnMonday )
+{
+ header->setStartOfWeek( bStartOnMonday );
+ // redraw();
+}
+
+void DateBookDay::keyPressEvent(QKeyEvent *e)
+{
+ switch(e->key()) {
+ case Key_Up:
+ view->moveUp();
+ break;
+ case Key_Down:
+ view->moveDown();
+ break;
+ case Key_Left:
+ setDate(QDate(currDate).addDays(-1));
+ break;
+ case Key_Right:
+ setDate(QDate(currDate).addDays(1));
+ break;
+ default:
+ e->ignore();
+ }
+}
+
+//===========================================================================
+
+DateBookDayWidget::DateBookDayWidget( const EffectiveEvent &e,
+ DateBookDay *db )
+ : QWidget( db->dayView()->viewport() ), ev( e ), dateBook( db )
+{
+ bool whichClock = db->dayView()->whichClock();
+
+ // why would someone use "<"? Oh well, fix it up...
+ // I wonder what other things may be messed up...
+ QString strDesc = ev.description();
+ int where = strDesc.find( "<" );
+ while ( where != -1 ) {
+ strDesc.remove( where, 1 );
+ strDesc.insert( where, "&#60;" );
+ where = strDesc.find( "<", where );
+ }
+
+ QString strCat;
+ // ### Fix later...
+// QString strCat = ev.category();
+// where = strCat.find( "<" );
+// while ( where != -1 ) {
+// strCat.remove( where, 1 );
+// strCat.insert( where, "&#60;" );
+// where = strCat.find( "<", where );
+// }
+
+ QString strNote = ev.notes();
+ where = strNote.find( "<" );
+ while ( where != -1 ) {
+ strNote.remove( where, 1 );
+ strNote.insert( where, "&#60;" );
+ where = strNote.find( "<", where );
+ }
+
+ text = "<b>" + strDesc + "</b><br>" + "<i>"
+ + strCat + "</i>"
+ + "<br><b>" + tr("Start") + "</b>: ";
+
+
+ if ( e.startDate() != ev.date() ) {
+ // multi-day event. Show start date
+ text += TimeString::longDateString( e.startDate() );
+ } else {
+ // Show start time.
+ text += TimeString::timeString( ev.start(), whichClock, FALSE );
+ }
+
+ text += "<br><b>" + tr("End") + "</b>: ";
+ if ( e.endDate() != ev.date() ) {
+ // multi-day event. Show end date
+ text += TimeString::longDateString( e.endDate() );
+ } else {
+ // Show end time.
+ text += TimeString::timeString( ev.end(), whichClock, FALSE );
+ }
+ text += "<br><br>" + strNote;
+ setBackgroundMode( PaletteBase );
+
+ QTime s = ev.start();
+ QTime e = ev.end();
+ int y = s.hour()*60+s.minute();
+ int h = e.hour()*60+e.minute()-y;
+ int rh = dateBook->dayView()->rowHeight(0);
+ y = y*rh/60;
+ h = h*rh/60;
+ if ( h < 3 )
+ h = 3;
+ geom.setY( y );
+ geom.setHeight( h );
+}
+
+DateBookDayWidget::~DateBookDayWidget()
+{
+}
+
+void DateBookDayWidget::paintEvent( QPaintEvent *e )
+{
+ QPainter p( this );
+ p.setPen( QColor(100, 100, 100) );
+ p.setBrush( QColor( 255, 240, 230 ) ); // based on priority?
+ p.drawRect(rect());
+
+ int y = 0;
+ int d = 0;
+
+ if ( ev.event().hasAlarm() ) {
+ p.drawPixmap( width() - 16, 0, Resource::loadPixmap( "bell" ) );
+ y = 20;
+ d = 20;
+ }
+
+ if ( ev.event().hasRepeat() ) {
+ p.drawPixmap( width() - 16, y, Resource::loadPixmap( "repeat" ) );
+ d = 20;
+ }
+
+ QSimpleRichText rt( text, font() );
+ rt.setWidth( geom.width() - d - 6 );
+ rt.draw( &p, 3, 0, e->region(), colorGroup() );
+}
+
+void DateBookDayWidget::mousePressEvent( QMouseEvent *e )
+{
+ QPopupMenu m;
+ m.insertItem( tr( "Edit" ), 1 );
+ m.insertItem( tr( "Delete" ), 2 );
+ m.insertItem( tr( "Beam" ), 3 );
+ int r = m.exec( e->globalPos() );
+ if ( r == 1 ) {
+ emit editMe( ev.event() );
+ } else if ( r == 2 ) {
+ emit deleteMe( ev.event() );
+ } else if ( r == 3 ) {
+ emit beamMe( ev.event() );
+ }
+}
+
+void DateBookDayWidget::setGeometry( const QRect &r )
+{
+ geom = r;
+ setFixedSize( r.width()+1, r.height()+1 );
+ dateBook->dayView()->moveChild( this, r.x(), r.y()-1 );
+ show();
+}
diff --git a/core/pim/datebook/datebookday.h b/core/pim/datebook/datebookday.h
new file mode 100644
index 0000000..531fded
--- a/dev/null
+++ b/core/pim/datebook/datebookday.h
@@ -0,0 +1,138 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef DATEBOOKDAY_H
+#define DATEBOOKDAY_H
+
+#include <qpe/event.h>
+
+#include <qdatetime.h>
+#include <qtable.h>
+#include <qvbox.h>
+#include <qlist.h>
+
+class DateBookDayHeader;
+class DateBookDB;
+class QDateTime;
+class QMouseEvent;
+class QPaintEvent;
+class QResizeEvent;
+
+class DateBookDayView : public QTable
+{
+ Q_OBJECT
+public:
+ DateBookDayView( bool hourClock, QWidget *parent, const char *name );
+ bool whichClock() const;
+
+public slots:
+ void moveUp();
+ void moveDown();
+
+signals:
+ void sigColWidthChanged();
+ void sigCapturedKey( const QString &txt );
+protected slots:
+ void slotChangeClock( bool );
+protected:
+ virtual void paintCell( QPainter *p, int row, int col, const QRect &cr, bool selected );
+ virtual void paintFocus( QPainter *p, const QRect &cr );
+ virtual void resizeEvent( QResizeEvent *e );
+ void keyPressEvent( QKeyEvent *e );
+ void initHeader();
+private:
+ bool ampm;
+};
+
+class DateBookDay;
+class DateBookDayWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ DateBookDayWidget( const EffectiveEvent &e, DateBookDay *db );
+ ~DateBookDayWidget();
+
+ const QRect &geometry() { return geom; }
+ void setGeometry( const QRect &r );
+
+ const EffectiveEvent &event() const { return ev; }
+
+signals:
+ void deleteMe( const Event &e );
+ void editMe( const Event &e );
+ void beamMe( const Event &e );
+
+protected:
+ void paintEvent( QPaintEvent *e );
+ void mousePressEvent( QMouseEvent *e );
+
+private:
+ const EffectiveEvent ev;
+ DateBookDay *dateBook;
+ QString text;
+ QRect geom;
+};
+
+class DateBookDay : public QVBox
+{
+ Q_OBJECT
+
+public:
+ DateBookDay( bool ampm, bool startOnMonday, DateBookDB *newDb,
+ QWidget *parent, const char *name );
+ void selectedDates( QDateTime &start, QDateTime &end );
+ QDate date() const;
+ DateBookDayView *dayView() const { return view; }
+ void setStartViewTime( int startHere );
+ int startViewTime() const;
+
+public slots:
+ void setDate( int y, int m, int d );
+ void setDate( QDate );
+ void redraw();
+ void slotWeekChanged( bool bStartOnMonday );
+
+signals:
+ void removeEvent( const Event& );
+ void editEvent( const Event& );
+ void beamEvent( const Event& );
+ void newEvent();
+ void sigNewEvent( const QString & );
+
+protected slots:
+ void keyPressEvent(QKeyEvent *);
+
+private slots:
+ void dateChanged( int y, int m, int d );
+ void slotColWidthChanged() { relayoutPage(); };
+
+private:
+ void getEvents();
+ void relayoutPage( bool fromResize = false );
+ DateBookDayWidget *intersects( const DateBookDayWidget *item, const QRect &geom );
+ QDate currDate;
+ DateBookDayView *view;
+ DateBookDayHeader *header;
+ DateBookDB *db;
+ QList<DateBookDayWidget> widgetList;
+ int startTime;
+};
+
+#endif
diff --git a/core/pim/datebook/datebookdayheader.ui b/core/pim/datebook/datebookdayheader.ui
new file mode 100644
index 0000000..8bc284f
--- a/dev/null
+++ b/core/pim/datebook/datebookdayheader.ui
@@ -0,0 +1,424 @@
+<!DOCTYPE UI><UI>
+<class>DateBookDayHeaderBase</class>
+<comment>/**********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+**********************************************************************/</comment>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>DateBookDayHeaderBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>249</width>
+ <height>26</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Form1</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>back</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image0</pixmap>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRepeat</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>false</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>date</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property stdset="1">
+ <name>autoRepeat</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QButtonGroup</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>grpDays</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>NoFrame</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Plain</enum>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>exclusive</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>1</number>
+ </property>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>M</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>T</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>W</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay4</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>T</string>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap></pixmap>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRepeat</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay5</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>F</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay6</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>S</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay7</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>S</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>toolTip</name>
+ <string></string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>forward</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image1</pixmap>
+ </property>
+ <property stdset="1">
+ <name>autoRepeat</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoRaise</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+</widget>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="582">789c6dcfcd4e843010c0f13b4fd1d01b31bb6cb325211b1f41e3d1c4789876a60bcbd7aeae07637c773b6d5985d870e0f7ef50605b88e7a707516cb3f72b5c5b2b6c036fa2c08f61f87c79bdffcaf2dd5ef0558b5d7e97e51b61c5e33412df4b7f2fcbb09896a94ab557817063cd744cad74a915734aac35308740d018d9332d5ab0c8ec1229f2c2448d156a661b489ee1ab4e4cf2a08a790e24020abb0dd355442eec8e914e45526215790c749e8e89891069125de466b1fe14295705ccaa5863e2d05cc01894925b2a7e8217dd8a631eb169fd509af10fd1a9ebfbdf32008d9d0c07cd274f70ee162773ba2cdfee935c977ffe6b2edf87ec07796f81cd</data>
+ </image>
+ <image>
+ <name>image1</name>
+ <data format="XPM.GZ" length="627">789c7dcfc94ec3301006e07b9ec28a6f114a13cbb1a8108f00e28884387819676993340b07847877329ea8697a60ec83bfdf232f8784bdbfbdb0e4104db39e6bcb6ca54796b8afb6fdfef87cfe89e25cb2650ac1f2f8218a5366d96bdf01aef9b2e65928a4458a0c07b25c29890352e63293e19c53a0968f52230159e8c22981744495133552097554a1f982b4ce6aeb9013d215165c81ec894e109b4070ca85378f2b35f18c04050214b20d04d010762ba457003eecd6442f88f34a45f4817ea147762b35d1acf4c47457d784737d9f18ebee1363614bf852c6f812b6c460f90abb6e93ba694ed7c49fdbaeee2f76b83da71ba772e0db5d9ccf4b07dfdd5e858edd9b2948fff9d796fc3e457f660e8d47</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>forward</sender>
+ <signal>clicked()</signal>
+ <receiver>DateBookDayHeaderBase</receiver>
+ <slot>goForward()</slot>
+ </connection>
+ <connection>
+ <sender>back</sender>
+ <signal>clicked()</signal>
+ <receiver>DateBookDayHeaderBase</receiver>
+ <slot>goBack()</slot>
+ </connection>
+ <connection>
+ <sender>grpDays</sender>
+ <signal>clicked(int)</signal>
+ <receiver>DateBookDayHeaderBase</receiver>
+ <slot>setDay( int )</slot>
+ </connection>
+ <slot access="public">goBack()</slot>
+ <slot access="public">goForward()</slot>
+ <slot access="public">setDate( int, int, int )</slot>
+ <slot access="public">setDay( int )</slot>
+</connections>
+</UI>
diff --git a/core/pim/datebook/datebookdayheaderimpl.cpp b/core/pim/datebook/datebookdayheaderimpl.cpp
new file mode 100644
index 0000000..fbcb3d2
--- a/dev/null
+++ b/core/pim/datebook/datebookdayheaderimpl.cpp
@@ -0,0 +1,181 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "datebookdayheaderimpl.h"
+
+#include <qpe/datebookmonth.h>
+#include <qpe/timestring.h>
+
+#include <qbuttongroup.h>
+#include <qpopupmenu.h>
+#include <qstringlist.h>
+#include <qtimer.h>
+#include <qtoolbutton.h>
+
+/*
+ * Constructs a DateBookDayHeader which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+DateBookDayHeader::DateBookDayHeader( bool useMonday,
+ QWidget* parent, const char* name )
+ : DateBookDayHeaderBase( parent, name ),
+ bUseMonday( useMonday )
+{
+ connect(date,SIGNAL(pressed()),this,SLOT(pickDate()));
+
+ setupNames();
+
+ setBackgroundMode( PaletteButton );
+ grpDays->setBackgroundMode( PaletteButton );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+DateBookDayHeader::~DateBookDayHeader()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+void DateBookDayHeader::setStartOfWeek( bool onMonday )
+{
+ bUseMonday = onMonday;
+ setupNames();
+ setDate( currDate.year(), currDate.month(), currDate.day() );
+}
+
+void DateBookDayHeader::setupNames()
+{
+ if ( bUseMonday ) {
+ cmdDay1->setText( DateBookDayHeaderBase::tr("Monday").left(1) );
+ cmdDay2->setText( DateBookDayHeaderBase::tr("Tuesday").left(1) );
+ cmdDay3->setText( DateBookDayHeaderBase::tr("Wednesday").left(1) );
+ cmdDay4->setText( DateBookDayHeaderBase::tr("Thursday").left(1) );
+ cmdDay5->setText( DateBookDayHeaderBase::tr("Friday").left(1) );
+ cmdDay6->setText( DateBookDayHeaderBase::tr("Saturday").left(1) );
+ cmdDay7->setText( DateBookDayHeaderBase::tr("Sunday").left(1) );
+ } else {
+ cmdDay1->setText( DateBookDayHeaderBase::tr("Sunday").left(1) );
+ cmdDay2->setText( DateBookDayHeaderBase::tr("Monday").left(1) );
+ cmdDay3->setText( DateBookDayHeaderBase::tr("Tuesday").left(1) );
+ cmdDay4->setText( DateBookDayHeaderBase::tr("Wednesday").left(1) );
+ cmdDay5->setText( DateBookDayHeaderBase::tr("Thursday").left(1) );
+ cmdDay6->setText( DateBookDayHeaderBase::tr("Friday").left(1) );
+ cmdDay7->setText( DateBookDayHeaderBase::tr("Saturday").left(1) );
+ }
+}
+
+
+void DateBookDayHeader::pickDate()
+{
+ static QPopupMenu *m1 = 0;
+ static DateBookMonth *picker = 0;
+ if ( !m1 ) {
+ m1 = new QPopupMenu( this );
+ picker = new DateBookMonth( m1, 0, TRUE );
+ m1->insertItem( picker );
+ connect( picker, SIGNAL( dateClicked( int, int, int ) ),
+ this, SLOT( setDate( int, int, int ) ) );
+ connect( m1, SIGNAL( aboutToHide() ),
+ this, SLOT( gotHide() ) );
+ }
+ picker->setDate( currDate.year(), currDate.month(), currDate.day() );
+ m1->popup(mapToGlobal(date->pos()+QPoint(0,date->height())));
+ picker->setFocus();
+}
+
+void DateBookDayHeader::gotHide()
+{
+ // we have to redo the button...
+ date->setDown( false );
+}
+
+/*
+ * public slot
+ */
+void DateBookDayHeader::goBack()
+{
+ currDate = currDate.addDays( -1 );
+ setDate( currDate.year(), currDate.month(), currDate.day() );
+}
+/*
+ * public slot
+ */
+void DateBookDayHeader::goForward()
+{
+ currDate = currDate.addDays( 1 );
+ setDate( currDate.year(), currDate.month(), currDate.day() );
+}
+
+
+/*
+ * public slot
+ */
+void DateBookDayHeader::setDate( int y, int m, int d )
+{
+ currDate.setYMD( y, m, d );
+ date->setText( TimeString::shortDate( currDate ) );
+
+ int iDayOfWeek = currDate.dayOfWeek();
+ // cleverly adjust the day depending on how we start the week
+ if ( bUseMonday )
+ iDayOfWeek--;
+ else {
+ if ( iDayOfWeek == 7 ) // Sunday
+ iDayOfWeek = 0;
+ }
+ grpDays->setButton( iDayOfWeek );
+ emit dateChanged( y, m, d );
+}
+
+/*
+ * public slot
+ */
+void DateBookDayHeader::setDay( int day )
+{
+ int realDay;
+ int dayOfWeek = currDate.dayOfWeek();
+
+ // a little adjustment is needed...
+ if ( bUseMonday )
+ realDay = day + 1 ;
+ else if ( !bUseMonday && day == 0 ) // sunday
+ realDay = 7;
+ else
+ realDay = day;
+ // special cases first...
+ if ( realDay == 7 && !bUseMonday ) {
+ while ( currDate.dayOfWeek() != realDay )
+ currDate = currDate.addDays( -1 );
+ } else if ( !bUseMonday && dayOfWeek == 7 && dayOfWeek > realDay ) {
+ while ( currDate.dayOfWeek() != realDay )
+ currDate = currDate.addDays( 1 );
+ } else if ( dayOfWeek < realDay ) {
+ while ( currDate.dayOfWeek() < realDay )
+ currDate = currDate.addDays( 1 );
+ } else if ( dayOfWeek > realDay ) {
+ while ( currDate.dayOfWeek() > realDay )
+ currDate = currDate.addDays( -1 );
+ }
+ // update the date...
+ setDate( currDate.year(), currDate.month(), currDate.day() );
+}
diff --git a/core/pim/datebook/datebookdayheaderimpl.h b/core/pim/datebook/datebookdayheaderimpl.h
new file mode 100644
index 0000000..43f3a93
--- a/dev/null
+++ b/core/pim/datebook/datebookdayheaderimpl.h
@@ -0,0 +1,57 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef DATEBOOKDAYHEADER_H
+#define DATEBOOKDAYHEADER_H
+#include "datebookdayheader.h"
+
+#include <qdatetime.h>
+
+class DateBookDayHeader : public DateBookDayHeaderBase
+{
+ Q_OBJECT
+
+public:
+ DateBookDayHeader( bool bUseMonday, QWidget* parent = 0,
+ const char* name = 0 );
+ ~DateBookDayHeader();
+ void setStartOfWeek( bool onMonday );
+
+public slots:
+ void goBack();
+ void goForward();
+ void setDate( int, int, int );
+ void setDay( int );
+ void gotHide();
+
+signals:
+ void dateChanged( int y, int m, int d );
+
+private slots:
+ void pickDate();
+
+
+private:
+ QDate currDate;
+ bool bUseMonday;
+ void setupNames();
+
+};
+
+#endif // DATEBOOKDAYHEADER_H
diff --git a/core/pim/datebook/datebooksettings.cpp b/core/pim/datebook/datebooksettings.cpp
new file mode 100644
index 0000000..c5d8ac1
--- a/dev/null
+++ b/core/pim/datebook/datebooksettings.cpp
@@ -0,0 +1,135 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "datebooksettings.h"
+
+#include <qpe/qpeapplication.h>
+
+#include <qspinbox.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+
+DateBookSettings::DateBookSettings( bool whichClock, QWidget *parent,
+ const char *name, bool modal, WFlags fl )
+ : DateBookSettingsBase( parent, name, modal, fl ),
+ ampm( whichClock )
+{
+ init();
+ QObject::connect( qApp, SIGNAL( clockChanged( bool ) ),
+ this, SLOT( slotChangeClock( bool ) ) );
+}
+
+DateBookSettings::~DateBookSettings()
+{
+}
+
+void DateBookSettings::setStartTime( int newStartViewTime )
+{
+ if ( ampm ) {
+ if ( newStartViewTime >= 12 ) {
+ newStartViewTime %= 12;
+ if ( newStartViewTime == 0 )
+ newStartViewTime = 12;
+ spinStart->setSuffix( tr(":00 PM") );
+ }
+ else if ( newStartViewTime == 0 ) {
+ newStartViewTime = 12;
+ spinStart->setSuffix( tr(":00 AM") );
+ }
+ oldtime = newStartViewTime;
+ }
+ spinStart->setValue( newStartViewTime );
+}
+
+int DateBookSettings::startTime() const
+{
+ int returnMe = spinStart->value();
+ if ( ampm ) {
+ if ( returnMe != 12 && spinStart->suffix().contains(tr("PM"), FALSE) )
+ returnMe += 12;
+ else if (returnMe == 12 && spinStart->suffix().contains(tr("AM"), TRUE))
+ returnMe = 0;
+ }
+ return returnMe;
+}
+
+
+void DateBookSettings::setAlarmPreset( bool bAlarm, int presetTime )
+{
+ chkAlarmPreset->setChecked( bAlarm );
+ if ( presetTime >=5 )
+ spinPreset->setValue( presetTime );
+}
+
+bool DateBookSettings::alarmPreset() const
+{
+ return chkAlarmPreset->isChecked();
+}
+
+int DateBookSettings::presetTime() const
+{
+ return spinPreset->value();
+}
+
+
+void DateBookSettings::slot12Hour( int i )
+{
+ if ( ampm ) {
+ if ( spinStart->suffix().contains( tr("AM"), FALSE ) ) {
+ if ( oldtime == 12 && i == 11 || oldtime == 11 && i == 12 )
+ spinStart->setSuffix( tr(":00 PM") );
+ } else {
+ if ( oldtime == 12 && i == 11 || oldtime == 11 && i == 12 )
+ spinStart->setSuffix( tr(":00 AM") );
+ }
+ oldtime = i;
+ }
+}
+
+void DateBookSettings::init()
+{
+ if ( ampm ) {
+ spinStart->setMinValue( 1 );
+ spinStart->setMaxValue( 12 );
+ spinStart->setValue( 12 );
+ spinStart->setSuffix( tr(":00 AM") );
+ oldtime = 12;
+ } else {
+ spinStart->setMinValue( 0 );
+ spinStart->setMaxValue( 23 );
+ spinStart->setSuffix( tr(":00") );
+ }
+}
+
+void DateBookSettings::slotChangeClock( bool whichClock )
+{
+ int saveMe;
+ saveMe = spinStart->value();
+ if ( ampm && spinStart->suffix().contains( tr("AM"), FALSE ) ) {
+ if ( saveMe == 12 )
+ saveMe = 0;
+ } else if ( ampm && spinStart->suffix().contains( tr("PM"), FALSE ) ) {
+ if ( saveMe != 12 )
+ saveMe += 12;
+ }
+ ampm = whichClock;
+ init();
+ setStartTime( saveMe );
+}
diff --git a/core/pim/datebook/datebooksettings.h b/core/pim/datebook/datebooksettings.h
new file mode 100644
index 0000000..ee9f39c
--- a/dev/null
+++ b/core/pim/datebook/datebooksettings.h
@@ -0,0 +1,48 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef DATEBOOKSETTINGS_H
+#define DATEBOOKSETTINGS_H
+#include "datebooksettingsbase.h"
+
+class DateBookSettings : public DateBookSettingsBase
+{
+public:
+ DateBookSettings( bool whichClock, QWidget *parent = 0,
+ const char *name = 0, bool modal = TRUE, WFlags = 0 );
+ ~DateBookSettings();
+ void setStartTime( int newStartViewTime );
+ int startTime() const;
+ void setAlarmPreset( bool bAlarm, int presetTime );
+ bool alarmPreset() const;
+ int presetTime() const;
+ void setAlarmType( int alarmType );
+ int alarmType() const;
+
+private slots:
+ void slot12Hour( int );
+ void slotChangeClock( bool );
+
+private:
+ void init();
+ bool ampm;
+ int oldtime;
+};
+#endif
diff --git a/core/pim/datebook/datebooksettingsbase.ui b/core/pim/datebook/datebooksettingsbase.ui
new file mode 100644
index 0000000..0f40773
--- a/dev/null
+++ b/core/pim/datebook/datebooksettingsbase.ui
@@ -0,0 +1,232 @@
+<!DOCTYPE UI><UI>
+<class>DateBookSettingsBase</class>
+<comment>**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+**********************************************************************</comment>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>DateBookSettingsBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>232</width>
+ <height>290</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Preferences</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>1</number>
+ </property>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>fraStart</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Box</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Start viewing events</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout1</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblStartTime</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Start Time:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinStart</cstring>
+ </property>
+ <property stdset="1">
+ <name>suffix</name>
+ <string>:00</string>
+ </property>
+ <property stdset="1">
+ <name>wrapping</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>23</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>fraAlarm</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Alarm Settings</string>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout6</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>chkAlarmPreset</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Alarm Preset</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinPreset</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>suffix</name>
+ <string> minutes</string>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>180</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>lineStep</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>5</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>chkAlarmPreset</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>spinPreset</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>spinStart</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>DateBookSettingsBase</receiver>
+ <slot>slot12Hour( int )</slot>
+ </connection>
+ <slot access="public">slotChangeClock( bool )</slot>
+ <slot access="public">slot12Hour( int )</slot>
+</connections>
+</UI>
diff --git a/core/pim/datebook/datebookweek.cpp b/core/pim/datebook/datebookweek.cpp
new file mode 100644
index 0000000..e9fcc39
--- a/dev/null
+++ b/core/pim/datebook/datebookweek.cpp
@@ -0,0 +1,687 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "datebookweek.h"
+#include "datebookweekheaderimpl.h"
+
+#include <qpe/calendar.h>
+#include <qpe/datebookdb.h>
+#include <qpe/event.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/timestring.h>
+
+#include <qdatetime.h>
+#include <qheader.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qpainter.h>
+#include <qpopupmenu.h>
+#include <qtimer.h>
+#include <qspinbox.h>
+#include <qstyle.h>
+
+//-----------------------------------------------------------------
+
+
+DateBookWeekItem::DateBookWeekItem( const EffectiveEvent e )
+ : ev( e )
+{
+ // with the current implementation change the color for all day events
+ if ( ev.event().type() == Event::AllDay && !ev.event().hasAlarm() ) {
+ c = Qt::green;
+ } else {
+ c = ev.event().hasAlarm() ? Qt::red : Qt::blue;
+ }
+}
+
+void DateBookWeekItem::setGeometry( int x, int y, int w, int h )
+{
+ r.setRect( x, y, w, h );
+}
+
+
+//------------------=---------------------------------------------
+
+DateBookWeekView::DateBookWeekView( bool ap, bool startOnMonday,
+ QWidget *parent, const char *name )
+ : QScrollView( parent, name ), ampm( ap ), bOnMonday( startOnMonday ),
+ showingEvent( false )
+{
+ items.setAutoDelete( true );
+
+ viewport()->setBackgroundMode( PaletteBase );
+
+ header = new QHeader( this );
+ header->addLabel( "" );
+
+ header->setMovingEnabled( false );
+ header->setResizeEnabled( false );
+ header->setClickEnabled( false, 0 );
+ initNames();
+
+
+ connect( header, SIGNAL(clicked(int)), this, SIGNAL(showDay(int)) );
+
+ QObject::connect(qApp, SIGNAL(clockChanged(bool)),
+ this, SLOT(slotChangeClock(bool)));
+
+ QFontMetrics fm( font() );
+ rowHeight = fm.height()+2;
+
+ resizeContents( width(), 24*rowHeight );
+}
+
+void DateBookWeekView::initNames()
+{
+ static bool bFirst = true;
+ if ( bFirst ) {
+ if ( bOnMonday ) {
+ header->addLabel( tr("M", "Monday" ) );
+ header->addLabel( tr("T", "Tuesday") );
+ header->addLabel( tr("W", "Wednesday" ) );
+ header->addLabel( tr("T", "Thursday" ) );
+ header->addLabel( tr("F", "Friday" ) );
+ header->addLabel( tr("S", "Saturday" ) );
+ header->addLabel( tr("S", "Sunday" ) );
+ } else {
+ header->addLabel( tr("S", "Sunday" ) );
+ header->addLabel( tr("M", "Monday") );
+ header->addLabel( tr("T", "Tuesday") );
+ header->addLabel( tr("W", "Wednesday" ) );
+ header->addLabel( tr("T", "Thursday" ) );
+ header->addLabel( tr("F", "Friday" ) );
+ header->addLabel( tr("S", "Saturday" ) );
+ }
+ bFirst = false;
+ } else {
+ // we are change things...
+ if ( bOnMonday ) {
+ header->setLabel( 1, tr("M", "Monday") );
+ header->setLabel( 2, tr("T", "Tuesday") );
+ header->setLabel( 3, tr("W", "Wednesday" ) );
+ header->setLabel( 4, tr("T", "Thursday" ) );
+ header->setLabel( 5, tr("F", "Friday" ) );
+ header->setLabel( 6, tr("S", "Saturday" ) );
+ header->setLabel( 7, tr("S", "Sunday" ) );
+ } else {
+ header->setLabel( 1, tr("S", "Sunday" ) );
+ header->setLabel( 2, tr("M", "Monday") );
+ header->setLabel( 3, tr("T", "Tuesday") );
+ header->setLabel( 4, tr("W", "Wednesday" ) );
+ header->setLabel( 5, tr("T", "Thursday" ) );
+ header->setLabel( 6, tr("F", "Friday" ) );
+ header->setLabel( 7, tr("S", "Saturday" ) );
+ }
+ }
+}
+
+
+
+void DateBookWeekView::showEvents( QValueList<EffectiveEvent> &ev )
+{
+ items.clear();
+ QValueListIterator<EffectiveEvent> it;
+ for ( it = ev.begin(); it != ev.end(); ++it ) {
+ DateBookWeekItem *i = new DateBookWeekItem( *it );
+ positionItem( i );
+ items.append( i );
+ }
+ viewport()->update();
+}
+
+void DateBookWeekView::moveToHour( int h )
+{
+ int offset = h*rowHeight;
+ setContentsPos( 0, offset );
+}
+
+void DateBookWeekView::keyPressEvent( QKeyEvent *e )
+{
+ e->ignore();
+}
+
+void DateBookWeekView::slotChangeClock( bool c )
+{
+ ampm = c;
+ viewport()->update();
+}
+
+static inline int db_round30min( int m )
+{
+ if ( m < 15 )
+ m = 0;
+ else if ( m < 45 )
+ m = 1;
+ else
+ m = 2;
+
+ return m;
+}
+
+void DateBookWeekView::alterDay( int day )
+{
+ if ( !bOnMonday ) {
+ day--;
+ }
+ emit showDay( day );
+}
+
+void DateBookWeekView::positionItem( DateBookWeekItem *i )
+{
+ const int Width = 8;
+ const EffectiveEvent ev = i->event();
+
+ // 30 minute intervals
+ int y = ev.start().hour() * 2;
+ y += db_round30min( ev.start().minute() );
+ if ( y > 47 )
+ y = 47;
+ y = y * rowHeight / 2;
+
+ int h;
+ if ( ev.event().type() == Event::AllDay ) {
+ h = 48;
+ y = 0;
+ } else {
+ h = ( ev.end().hour() - ev.start().hour() ) * 2;
+ h += db_round30min( ev.end().minute() - ev.start().minute() );
+ if ( h < 1 ) h = 1;
+ }
+ h = h * rowHeight / 2;
+
+ int dow = ev.date().dayOfWeek();
+ if ( !bOnMonday ) {
+ if ( dow == 7 )
+ dow = 1;
+ else
+ dow++;
+ }
+ int x = header->sectionPos( dow ) - 1;
+ int xlim = header->sectionPos( dow ) + header->sectionSize( dow );
+ DateBookWeekItem *isect = 0;
+ do {
+ i->setGeometry( x, y, Width, h );
+ isect = intersects( i );
+ x += Width - 1;
+ } while ( isect && x < xlim );
+}
+
+DateBookWeekItem *DateBookWeekView::intersects( const DateBookWeekItem *item )
+{
+ QRect geom = item->geometry();
+
+ // We allow the edges to overlap
+ geom.moveBy( 1, 1 );
+ geom.setSize( geom.size()-QSize(2,2) );
+
+ QListIterator<DateBookWeekItem> it(items);
+ for ( ; it.current(); ++it ) {
+ DateBookWeekItem *i = it.current();
+ if ( i != item ) {
+ if ( i->geometry().intersects( geom ) ) {
+ return i;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void DateBookWeekView::contentsMousePressEvent( QMouseEvent *e )
+{
+ QListIterator<DateBookWeekItem> it(items);
+ for ( ; it.current(); ++it ) {
+ DateBookWeekItem *i = it.current();
+ if ( i->geometry().contains( e->pos() ) ) {
+ showingEvent = true;
+ emit signalShowEvent( i->event() );
+ break;
+ }
+ }
+}
+
+void DateBookWeekView::contentsMouseReleaseEvent( QMouseEvent *e )
+{
+ if ( showingEvent ) {
+ showingEvent = false;
+ emit signalHideEvent();
+ } else {
+ int d = header->sectionAt( e->pos().x() );
+ if ( d > 0 ) {
+// if ( !bOnMonday )
+// d--;
+ emit showDay( d );
+ }
+ }
+}
+
+void DateBookWeekView::drawContents( QPainter *p, int cx, int cy, int cw, int ch )
+{
+ QRect ur( cx, cy, cw, ch );
+ p->setPen( lightGray );
+ for ( int i = 1; i <= 7; i++ )
+ p->drawLine( header->sectionPos(i)-2, cy, header->sectionPos(i)-2, cy+ch );
+
+ p->setPen( black );
+ for ( int t = 0; t < 24; t++ ) {
+ int y = t*rowHeight;
+ if ( QRect( 1, y, 20, rowHeight ).intersects( ur ) ) {
+ QString s;
+ if ( ampm ) {
+ if ( t == 0 )
+ s = QString::number( 12 );
+ else if ( t == 12 )
+ s = QString::number(12) + tr( "p" );
+ else if ( t > 12 ) {
+ if ( t - 12 < 10 )
+ s = " ";
+ else
+ s = "";
+ s += QString::number( t - 12 ) + tr("p");
+ } else {
+ if ( 12 - t < 3 )
+ s = "";
+ else
+ s = " ";
+ s += QString::number( t );
+ }
+ } else {
+ s = QString::number( t );
+ if ( s.length() == 1 )
+ s.prepend( "0" );
+ }
+ p->drawText( 1, y+p->fontMetrics().ascent()+1, s );
+ }
+ }
+
+ QListIterator<DateBookWeekItem> it(items);
+ for ( ; it.current(); ++it ) {
+ DateBookWeekItem *i = it.current();
+ if ( i->geometry().intersects( ur ) ) {
+ p->setBrush( i->color() );
+ p->drawRect( i->geometry() );
+ }
+ }
+}
+
+void DateBookWeekView::resizeEvent( QResizeEvent *e )
+{
+ const int hourWidth = 20;
+ QScrollView::resizeEvent( e );
+ int avail = width()-qApp->style().scrollBarExtent().width()-1;
+ header->setGeometry( 0, 0, avail, header->sizeHint().height() );
+ setMargins( 0, header->height(), 0, 0 );
+ header->resizeSection( 0, hourWidth );
+ int sw = (avail - hourWidth) / 7;
+ for ( int i = 1; i < 7; i++ )
+ header->resizeSection( i, sw );
+ header->resizeSection( 7, avail - hourWidth - sw*6 );
+}
+
+void DateBookWeekView::setStartOfWeek( bool bStartOnMonday )
+{
+ bOnMonday = bStartOnMonday;
+ initNames();
+}
+
+//-------------------------------------------------------------------
+
+DateBookWeek::DateBookWeek( bool ap, bool startOnMonday, DateBookDB *newDB,
+ QWidget *parent, const char *name )
+ : QWidget( parent, name ),
+ db( newDB ),
+ startTime( 0 ),
+ ampm( ap ),
+ bStartOnMonday( startOnMonday )
+{
+ setFocusPolicy(StrongFocus);
+ QVBoxLayout *vb = new QVBoxLayout( this );
+ header = new DateBookWeekHeader( bStartOnMonday, this );
+ view = new DateBookWeekView( ampm, startOnMonday, this );
+ vb->addWidget( header );
+ vb->addWidget( view );
+
+ lblDesc = new QLabel( this, "event label" );
+ lblDesc->setFrameStyle( QFrame::Plain | QFrame::Box );
+ lblDesc->setBackgroundColor( yellow );
+ lblDesc->hide();
+
+ tHide = new QTimer( this );
+
+ connect( view, SIGNAL( showDay( int ) ),
+ this, SLOT( showDay( int ) ) );
+ connect( view, SIGNAL(signalShowEvent(const EffectiveEvent&)),
+ this, SLOT(slotShowEvent(const EffectiveEvent&)) );
+ connect( view, SIGNAL(signalHideEvent()),
+ this, SLOT(slotHideEvent()) );
+ connect( header, SIGNAL( dateChanged( int, int ) ),
+ this, SLOT( dateChanged( int, int ) ) );
+ connect( tHide, SIGNAL( timeout() ),
+ lblDesc, SLOT( hide() ) );
+ connect( header->spinYear, SIGNAL(valueChanged(int)),
+ this, SLOT(slotYearChanged(int)) );
+ connect( qApp, SIGNAL(weekChanged(bool)),
+ this, SLOT(slotWeekChanged(bool)) );
+ connect( qApp, SIGNAL(clockChanged(bool)),
+ this, SLOT(slotClockChanged(bool)));
+ setDate(QDate::currentDate());
+
+}
+
+void DateBookWeek::keyPressEvent(QKeyEvent *e)
+{
+ switch(e->key()) {
+ case Key_Up:
+ view->scrollBy(0, -20);
+ break;
+ case Key_Down:
+ view->scrollBy(0, 20);
+ break;
+ case Key_Left:
+ setDate(date().addDays(-7));
+ break;
+ case Key_Right:
+ setDate(date().addDays(7));
+ break;
+ default:
+ e->ignore();
+ }
+}
+
+void DateBookWeek::showDay( int day )
+{
+ QDate d;
+ d = dateFromWeek( _week, year, bStartOnMonday );
+ day--;
+ d = d.addDays( day );
+ emit showDate( d.year(), d.month(), d.day() );
+}
+
+void DateBookWeek::setDate( int y, int m, int d )
+{
+ QDate date;
+ date.setYMD( y, m, d );
+ setDate(QDate(y, m, d));
+}
+
+void DateBookWeek::setDate(QDate date)
+{
+ dow = date.dayOfWeek();
+ int w, y;
+ calcWeek( date, w, y, bStartOnMonday );
+ header->setDate( y, w );
+}
+
+void DateBookWeek::dateChanged( int y, int w )
+{
+ year = y;
+ _week = w;
+ getEvents();
+}
+
+QDate DateBookWeek::date() const
+{
+ QDate d;
+ d = dateFromWeek( _week - 1, year, bStartOnMonday );
+ if ( bStartOnMonday )
+ d = d.addDays( 7 + dow - 1 );
+ else {
+ if ( dow == 7 )
+ d = d.addDays( dow );
+ else
+ d = d.addDays( 7 + dow );
+ }
+ return d;
+}
+
+void DateBookWeek::getEvents()
+{
+ QDate startWeek = weekDate();
+
+ QDate endWeek = startWeek.addDays( 6 );
+ QValueList<EffectiveEvent> eventList = db->getEffectiveEvents(startWeek,
+ endWeek);
+ view->showEvents( eventList );
+ view->moveToHour( startTime );
+}
+
+void DateBookWeek::slotShowEvent( const EffectiveEvent &ev )
+{
+ if ( tHide->isActive() )
+ tHide->stop();
+
+ // why would someone use "<"? Oh well, fix it up...
+ // I wonder what other things may be messed up...
+ QString strDesc = ev.description();
+ int where = strDesc.find( "<" );
+ while ( where != -1 ) {
+ strDesc.remove( where, 1 );
+ strDesc.insert( where, "&#60;" );
+ where = strDesc.find( "<", where );
+ }
+
+ QString strCat;
+ // ### FIX later...
+// QString strCat = ev.category();
+// where = strCat.find( "<" );
+// while ( where != -1 ) {
+// strCat.remove( where, 1 );
+// strCat.insert( where, "&#60;" );
+// where = strCat.find( "<", where );
+// }
+
+ QString strNote = ev.notes();
+ where = strNote.find( "<" );
+ while ( where != -1 ) {
+ strNote.remove( where, 1 );
+ strNote.insert( where, "&#60;" );
+ where = strNote.find( "<", where );
+ }
+
+ QString str = "<b>" + strDesc + "</b><br>" + "<i>"
+ + strCat + "</i>"
+ + "<br>" + TimeString::longDateString( ev.date() )
+ + "<br><b>" + QObject::tr("Start") + "</b>: ";
+
+ if ( ev.startDate() != ev.date() ) {
+ // multi-day event. Show start date
+ str += TimeString::longDateString( ev.startDate() );
+ } else {
+ // Show start time.
+ str += TimeString::timeString(ev.start(), ampm, FALSE );
+ }
+
+ str += "<br><b>" + QObject::tr("End") + "</b>: ";
+ if ( ev.endDate() != ev.date() ) {
+ // multi-day event. Show end date
+ str += TimeString::longDateString( ev.endDate() );
+ } else {
+ // Show end time.
+ str += TimeString::timeString( ev.end(), ampm, FALSE );
+ }
+ str += "<br><br>" + strNote;
+
+ lblDesc->setText( str );
+ lblDesc->resize( lblDesc->sizeHint() );
+ // move the label so it is "centerd" horizontally...
+ lblDesc->move( QMAX(0,(width() - lblDesc->width()) / 2), 0 );
+ lblDesc->show();
+}
+
+void DateBookWeek::slotHideEvent()
+{
+ tHide->start( 2000, true );
+}
+
+void DateBookWeek::setStartViewTime( int startHere )
+{
+ startTime = startHere;
+ view->moveToHour( startTime );
+}
+
+int DateBookWeek::startViewTime() const
+{
+ return startTime;
+}
+
+void DateBookWeek::redraw()
+{
+ getEvents();
+}
+
+void DateBookWeek::slotYearChanged( int y )
+{
+ int totWeek;
+ QDate d( y, 12, 31 );
+ int throwAway;
+ calcWeek( d, totWeek, throwAway, bStartOnMonday );
+ while ( totWeek == 1 ) {
+ d = d.addDays( -1 );
+ calcWeek( d, totWeek, throwAway, bStartOnMonday );
+ }
+ if ( totWeek != totalWeeks() )
+ setTotalWeeks( totWeek );
+}
+
+
+void DateBookWeek::setTotalWeeks( int numWeeks )
+{
+ header->spinWeek->setMaxValue( numWeeks );
+}
+
+int DateBookWeek::totalWeeks() const
+{
+ return header->spinWeek->maxValue();
+}
+
+void DateBookWeek::slotWeekChanged( bool onMonday )
+{
+ bStartOnMonday = onMonday;
+ view->setStartOfWeek( bStartOnMonday );
+ header->setStartOfWeek( bStartOnMonday );
+ redraw();
+}
+
+void DateBookWeek::slotClockChanged( bool ap )
+{
+ ampm = ap;
+}
+
+// return the date at the beginning of the week...
+QDate DateBookWeek::weekDate() const
+{
+ return dateFromWeek( _week, year, bStartOnMonday );
+}
+
+// this used to only be needed by datebook.cpp, but now we need it inside
+// week view since
+// we need to be able to figure out our total number of weeks on the fly...
+// this is probably the best place to put it..
+
+// For Weeks that start on Monday... (EASY!)
+// At the moment we will use ISO 8601 method for computing
+// the week. Granted, other countries use other methods,
+// bet we aren't doing any Locale stuff at the moment. So,
+// this should pass. This Algorithim is public domain and
+// available at:
+// http://personal.ecu.edu/mccartyr/ISOwdALG.txt
+// the week number is return, and the year number is returned in year
+// for Instance 2001/12/31 is actually the first week in 2002.
+// There is a more mathematical definition, but I will implement it when
+// we are pass our deadline.
+
+// For Weeks that start on Sunday... (ahh... home rolled)
+// okay, if Jan 1 is on Friday or Saturday,
+// it will go to the pervious
+// week...
+
+bool calcWeek( const QDate &d, int &week, int &year,
+ bool startOnMonday = false )
+{
+ int weekNumber;
+ int yearNumber;
+
+ // remove a pesky warning, (Optimizations on g++)
+ weekNumber = -1;
+ int jan1WeekDay = QDate(d.year(), 1, 1).dayOfWeek();
+ int dayOfWeek = d.dayOfWeek();
+
+ if ( !d.isValid() )
+ return false;
+
+ if ( startOnMonday ) {
+ // find the Jan1Weekday;
+ if ( d.dayOfYear() <= ( 8 - jan1WeekDay) && jan1WeekDay > 4 ) {
+ yearNumber = d.year() - 1;
+ if ( jan1WeekDay == 5 || ( jan1WeekDay == 6 && QDate::leapYear(yearNumber) ) )
+ weekNumber = 53;
+ else
+ weekNumber = 52;
+ } else
+ yearNumber = d.year();
+ if ( yearNumber == d.year() ) {
+ int totalDays = 365;
+ if ( QDate::leapYear(yearNumber) )
+ totalDays++;
+ if ( ((totalDays - d.dayOfYear()) < (4 - dayOfWeek) )
+ || (jan1WeekDay == 7) && (totalDays - d.dayOfYear()) < 3) {
+ yearNumber++;
+ weekNumber = 1;
+ }
+ }
+ if ( yearNumber == d.year() ) {
+ int j = d.dayOfYear() + (7 - dayOfWeek) + ( jan1WeekDay - 1 );
+ weekNumber = j / 7;
+ if ( jan1WeekDay > 4 )
+ weekNumber--;
+ }
+ } else {
+ // it's better to keep these cases separate...
+ if ( d.dayOfYear() <= (7 - jan1WeekDay) && jan1WeekDay > 4
+ && jan1WeekDay != 7 ) {
+ yearNumber = d.year() - 1;
+ if ( jan1WeekDay == 6
+ || (jan1WeekDay == 7 && QDate::leapYear(yearNumber) ) ) {
+ weekNumber = 53;
+ }else
+ weekNumber = 52;
+ } else
+ yearNumber = d.year();
+ if ( yearNumber == d.year() ) {
+ int totalDays = 365;
+ if ( QDate::leapYear( yearNumber ) )
+ totalDays++;
+ if ( ((totalDays - d.dayOfYear()) < (4 - dayOfWeek % 7)) ) {
+ yearNumber++;
+ weekNumber = 1;
+ }
+ }
+ if ( yearNumber == d.year() ) {
+ int j = d.dayOfYear() + (7 - dayOfWeek % 7) + ( jan1WeekDay - 1 );
+ weekNumber = j / 7;
+ if ( jan1WeekDay > 4 ) {
+ weekNumber--;
+ }
+ }
+ }
+ year = yearNumber;
+ week = weekNumber;
+ return true;
+}
+
diff --git a/core/pim/datebook/datebookweek.h b/core/pim/datebook/datebookweek.h
new file mode 100644
index 0000000..6e675f1
--- a/dev/null
+++ b/core/pim/datebook/datebookweek.h
@@ -0,0 +1,152 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef DATEBOOKWEEK
+#define DATEBOOKWEEK
+
+#include <qpe/event.h>
+
+#include <qlist.h>
+#include <qscrollview.h>
+#include <qstring.h>
+#include <qvaluelist.h>
+
+class DateBookDB;
+class DateBookWeekHeader;
+class QDate;
+class QLabel;
+class QResizeEvent;
+class QSpinBox;
+class QTimer;
+class QHeader;
+
+class DateBookWeekItem
+{
+public:
+ DateBookWeekItem( const EffectiveEvent e );
+
+ void setGeometry( int x, int y, int w, int h );
+ QRect geometry() const { return r; }
+
+ const QColor &color() const { return c; }
+ const EffectiveEvent event() const { return ev; }
+
+private:
+ const EffectiveEvent ev;
+ QRect r;
+ QColor c;
+};
+
+class DateBookWeekView : public QScrollView
+{
+ Q_OBJECT
+public:
+ DateBookWeekView( bool ampm, bool weekOnMonday, QWidget *parent = 0,
+ const char *name = 0 );
+
+ bool whichClock() const;
+ void showEvents( QValueList<EffectiveEvent> &ev );
+ void moveToHour( int h );
+ void setStartOfWeek( bool bOnMonday );
+
+signals:
+ void showDay( int d );
+ void signalShowEvent( const EffectiveEvent & );
+ void signalHideEvent();
+
+protected slots:
+ void keyPressEvent(QKeyEvent *);
+
+private slots:
+ void slotChangeClock( bool );
+ void alterDay( int );
+
+private:
+ void positionItem( DateBookWeekItem *i );
+ DateBookWeekItem *intersects( const DateBookWeekItem * );
+ void drawContents( QPainter *p, int cx, int cy, int cw, int ch );
+ void contentsMousePressEvent( QMouseEvent * );
+ void contentsMouseReleaseEvent( QMouseEvent * );
+ void resizeEvent( QResizeEvent * );
+ void initNames();
+
+private:
+ bool ampm;
+ bool bOnMonday;
+ QHeader *header;
+ QList<DateBookWeekItem> items;
+ int rowHeight;
+ bool showingEvent;
+};
+
+class DateBookWeek : public QWidget
+{
+ Q_OBJECT
+
+public:
+ DateBookWeek( bool ampm, bool weekOnMonday, DateBookDB *newDB,
+ QWidget *parent = 0, const char *name = 0 );
+ void setDate( int y, int m, int d );
+ void setDate( QDate d );
+ QDate date() const;
+ DateBookWeekView *weekView() const { return view; }
+ void setStartViewTime( int startHere );
+ int startViewTime() const;
+ int week() const { return _week; };
+ void setTotalWeeks( int totalWeeks );
+ int totalWeeks() const;
+ QDate weekDate() const;
+
+public slots:
+ void redraw();
+ void slotWeekChanged( bool bStartOnMonday );
+ void slotClockChanged( bool a );
+
+signals:
+ void showDate( int y, int m, int d );
+
+protected slots:
+ void keyPressEvent(QKeyEvent *);
+
+private slots:
+ void showDay( int day );
+ void dateChanged( int y, int w );
+ void slotShowEvent( const EffectiveEvent & );
+ void slotHideEvent();
+ void slotYearChanged( int );
+
+private:
+ void getEvents();
+ int year;
+ int _week;
+ int dow;
+ DateBookWeekHeader *header;
+ DateBookWeekView *view;
+ DateBookDB *db;
+ QLabel *lblDesc;
+ QTimer *tHide;
+ int startTime;
+ bool ampm;
+ bool bStartOnMonday;
+};
+
+
+bool calcWeek( const QDate &d, int &week, int &year,
+ bool startOnMonday = false );
+#endif
diff --git a/core/pim/datebook/datebookweekheader.ui b/core/pim/datebook/datebookweekheader.ui
new file mode 100644
index 0000000..dd6a5b1
--- a/dev/null
+++ b/core/pim/datebook/datebookweekheader.ui
@@ -0,0 +1,167 @@
+<!DOCTYPE UI><UI>
+<class>DateBookWeekHeaderBase</class>
+<comment>*********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+*********************************************************************</comment>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>DateBookWeekHeaderBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>281</width>
+ <height>30</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Form1</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinYear</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>prefix</name>
+ <string>Y: </string>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>2037</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>1970</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>2002</number>
+ </property>
+ </widget>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinWeek</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>prefix</name>
+ <string>W: </string>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>52</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>1</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>1</number>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>labelDate</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>00. Jan-00. Jan</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignCenter</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ </hbox>
+</widget>
+<connections>
+ <connection>
+ <sender>spinYear</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>DateBookWeekHeaderBase</receiver>
+ <slot>yearChanged( int )</slot>
+ </connection>
+ <connection>
+ <sender>spinWeek</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>DateBookWeekHeaderBase</receiver>
+ <slot>weekChanged( int )</slot>
+ </connection>
+ <slot access="public">yearChanged( int )</slot>
+ <slot access="public">nextWeek()</slot>
+ <slot access="public">prevWeek()</slot>
+ <slot access="public">weekChanged( int )</slot>
+</connections>
+</UI>
diff --git a/core/pim/datebook/datebookweekheaderimpl.cpp b/core/pim/datebook/datebookweekheaderimpl.cpp
new file mode 100644
index 0000000..e7c7208
--- a/dev/null
+++ b/core/pim/datebook/datebookweekheaderimpl.cpp
@@ -0,0 +1,126 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "datebookweekheaderimpl.h"
+#include <qlabel.h>
+#include <qspinbox.h>
+#include <qdatetime.h>
+
+/*
+ * Constructs a DateBookWeekHeader which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ */
+DateBookWeekHeader::DateBookWeekHeader( bool startOnMonday, QWidget* parent,
+ const char* name, WFlags fl )
+ : DateBookWeekHeaderBase( parent, name, fl ),
+ bStartOnMonday( startOnMonday )
+{
+ setBackgroundMode( PaletteButton );
+ labelDate->setBackgroundMode( PaletteButton );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+DateBookWeekHeader::~DateBookWeekHeader()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * public slot
+ */
+void DateBookWeekHeader::yearChanged( int y )
+{
+ setDate( y, week );
+}
+/*
+ * public slot
+ */
+void DateBookWeekHeader::nextWeek()
+{
+ if ( week < 52 )
+ week++;
+ setDate( year, week );
+}
+/*
+ * public slot
+ */
+void DateBookWeekHeader::prevWeek()
+{
+ if ( week > 1 )
+ week--;
+ setDate( year, week );
+}
+/*
+ * public slot
+ */
+void DateBookWeekHeader::weekChanged( int w )
+{
+ setDate( year, w );
+}
+
+void DateBookWeekHeader::setDate( int y, int w )
+{
+ year = y;
+ week = w;
+ spinYear->setValue( y );
+ spinWeek->setValue( w );
+
+ QDate d = dateFromWeek( week, year, bStartOnMonday );
+
+ QString s = QString::number( d.day() ) + ". " + d.monthName( d.month() )
+ + "-";
+ d = d.addDays( 6 );
+ s += QString::number( d.day() ) + ". " + d.monthName( d.month() );
+ labelDate->setText( s );
+
+ emit dateChanged( y, w );
+}
+
+void DateBookWeekHeader::setStartOfWeek( bool onMonday )
+{
+ bStartOnMonday = onMonday;
+ setDate( year, week );
+}
+
+// dateFromWeek
+// compute the date from the week in the year
+
+QDate dateFromWeek( int week, int year, bool startOnMonday )
+{
+ QDate d;
+ d.setYMD( year, 1, 1 );
+ int dayOfWeek = d.dayOfWeek();
+ if ( startOnMonday ) {
+ if ( dayOfWeek <= 4 ) {
+ d = d.addDays( ( week - 1 ) * 7 - dayOfWeek + 1 );
+ } else {
+ d = d.addDays( (week) * 7 - dayOfWeek + 1 );
+ }
+ } else {
+ if ( dayOfWeek <= 4 || dayOfWeek == 7) {
+ d = d.addDays( ( week - 1 ) * 7 - dayOfWeek % 7 );
+ } else {
+ d = d.addDays( ( week ) * 7 - dayOfWeek % 7 );
+ }
+ }
+ return d;
+}
+
diff --git a/core/pim/datebook/datebookweekheaderimpl.h b/core/pim/datebook/datebookweekheaderimpl.h
new file mode 100644
index 0000000..2abef46
--- a/dev/null
+++ b/core/pim/datebook/datebookweekheaderimpl.h
@@ -0,0 +1,62 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef DATEBOOKDAYHEADER_H
+#define DATEBOOKDAYHEADER_H
+#include <qdatetime.h>
+#include "datebookweekheader.h"
+
+
+class DateBookWeekHeader : public DateBookWeekHeaderBase
+{
+ Q_OBJECT
+
+public:
+ DateBookWeekHeader( bool startOnMonday, QWidget* parent = 0,
+ const char* name = 0, WFlags fl = 0 );
+ ~DateBookWeekHeader();
+
+ void setDate( int y, int w );
+ void setStartOfWeek( bool onMonday );
+
+signals:
+ void dateChanged( int y, int w );
+
+public slots:
+ void yearChanged( int );
+ void nextWeek();
+ void prevWeek();
+ void weekChanged( int );
+
+protected slots:
+ void keyPressEvent(QKeyEvent *e)
+ {
+ e->ignore();
+ }
+
+private:
+ int year,
+ week;
+ bool bStartOnMonday;
+
+};
+
+QDate dateFromWeek( int week, int year, bool startOnMonday );
+
+#endif // DATEBOOKDAYHEADER_H
diff --git a/core/pim/datebook/dateentry.ui b/core/pim/datebook/dateentry.ui
new file mode 100644
index 0000000..0c363a4
--- a/dev/null
+++ b/core/pim/datebook/dateentry.ui
@@ -0,0 +1,1095 @@
+<!DOCTYPE UI><UI>
+<class>DateEntryBase</class>
+<comment>*********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+*********************************************************************</comment>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>DateEntryBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>242</width>
+ <height>339</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>New Event</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget row="1" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>MShape</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>MShadow</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Location</string>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Category</string>
+ </property>
+ <property>
+ <name>buddy</name>
+ <cstring>comboPriority</cstring>
+ </property>
+ </widget>
+ <widget row="0" column="1" rowspan="1" colspan="3" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>(None)</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Meeting</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Lunch</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Dinner</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Travel</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboDescription</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>currentItem</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>duplicatesEnabled</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Description:</string>
+ </property>
+ </widget>
+ <widget row="1" column="1" rowspan="1" colspan="3" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>(Unknown)</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Office</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Home</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboLocation</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>currentItem</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>duplicatesEnabled</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="2" column="1" rowspan="1" colspan="3" >
+ <class>CategorySelect</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboCategory</cstring>
+ </property>
+ </widget>
+ <widget row="3" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Start</string>
+ </property>
+ </widget>
+ <widget row="3" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonStart</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Jan 02 00</string>
+ </property>
+ </widget>
+ <widget row="3" column="2" rowspan="1" colspan="2" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>00:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>00:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>01:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>01:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>02:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>02:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>03:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>03:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>04:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>04:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>05:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>05:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>06:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>06:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>07:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>07:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>08:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>08:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>09:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>09:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>10:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>10:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>11:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>11:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>12:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>12:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>13:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>13:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>14:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>14:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>15:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>15:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>16:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>16:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>17:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>17:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>18:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>18:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>19:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>19:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>20:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>20:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>21:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>21:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>22:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>22:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>23:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>23:30</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboStart</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>duplicatesEnabled</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="4" column="1" >
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonEnd</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Jan 02 00</string>
+ </property>
+ </widget>
+ <widget row="4" column="2" rowspan="1" colspan="2" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>00:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>00:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>01:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>01:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>02:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>02:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>03:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>03:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>04:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>04:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>05:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>05:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>06:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>06:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>07:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>07:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>08:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>08:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>09:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>09:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>10:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>10:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>11:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>11:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>12:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>12:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>13:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>13:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>14:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>14:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>15:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>15:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>16:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>16:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>17:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>17:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>18:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>18:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>19:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>19:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>20:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>20:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>21:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>21:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>22:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>22:30</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>23:00</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>23:30</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboEnd</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>duplicatesEnabled</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="4" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>End</string>
+ </property>
+ </widget>
+ <widget row="5" column="0" >
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>checkAllDay</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>All day</string>
+ </property>
+ </widget>
+ <widget row="6" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3_2_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Time zone:</string>
+ </property>
+ </widget>
+ <widget row="6" column="1" rowspan="1" colspan="3" >
+ <class>TimeZoneSelector</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>timezone</cstring>
+ </property>
+ </widget>
+ <widget row="7" column="0" >
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>checkAlarm</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>autoMask</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Alarm</string>
+ </property>
+ <property stdset="1">
+ <name>checked</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="7" column="1" rowspan="1" colspan="2" >
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinAlarm</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>suffix</name>
+ <string> minutes</string>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>180</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>lineStep</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>value</name>
+ <number>5</number>
+ </property>
+ </widget>
+ <widget row="7" column="3" >
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Silent</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Loud</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboSound</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget row="8" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblRepeat</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Repeat</string>
+ </property>
+ </widget>
+ <widget row="8" column="1" rowspan="1" colspan="3" >
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdRepeat</cstring>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>No Repeat...</string>
+ </property>
+ </widget>
+ <widget row="9" column="0" rowspan="1" colspan="4" >
+ <class>QMultiLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>editNote</cstring>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>TimeZoneSelector</class>
+ <header location="global">qpe/tzselect.h</header>
+ <sizehint>
+ <width>21</width>
+ <height>10</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>1</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+ <customwidget>
+ <class>CategorySelect</class>
+ <header location="global">qpe/categoryselect.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>1</verdata>
+ </sizepolicy>
+ <pixmap>image1</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="45">789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523250004143a55a6b2e0026630c4f</data>
+ </image>
+ <image>
+ <name>image1</name>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>checkAlarm</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>spinAlarm</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>comboEnd</sender>
+ <signal>activated(const QString&amp;)</signal>
+ <receiver>DateEntryBase</receiver>
+ <slot>endTimeChanged( const QString &amp; )</slot>
+ </connection>
+ <connection>
+ <sender>cmdRepeat</sender>
+ <signal>clicked()</signal>
+ <receiver>DateEntryBase</receiver>
+ <slot>slotRepeat()</slot>
+ </connection>
+ <connection>
+ <sender>comboStart</sender>
+ <signal>activated(int)</signal>
+ <receiver>DateEntryBase</receiver>
+ <slot>startTimeChanged( int )</slot>
+ </connection>
+ <connection>
+ <sender>checkAllDay</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>comboEnd</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>checkAlarm</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>comboSound</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>checkAllDay</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>comboStart</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <slot access="public">endDateChanged( const QString &amp; )</slot>
+ <slot access="public">endDateChanged( int, int, int )</slot>
+ <slot access="public">endTimeChanged( const QString &amp; )</slot>
+ <slot access="public">slotRepeat()</slot>
+ <slot access="public">slotWait( int )</slot>
+ <slot access="public">startDateChanged( const QString &amp; )</slot>
+ <slot access="public">startDateChanged(int, int, int)</slot>
+ <slot access="public">startTimeChanged( int )</slot>
+ <slot access="public">typeChanged( const QString &amp; )</slot>
+ <slot access="public">tzexecute(void)</slot>
+</connections>
+</UI>
diff --git a/core/pim/datebook/dateentryimpl.cpp b/core/pim/datebook/dateentryimpl.cpp
new file mode 100644
index 0000000..1122f79
--- a/dev/null
+++ b/core/pim/datebook/dateentryimpl.cpp
@@ -0,0 +1,474 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "dateentryimpl.h"
+#include "repeatentry.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/categoryselect.h>
+#include <qpe/datebookmonth.h>
+#include <qpe/global.h>
+#include <qpe/timeconversion.h>
+#include <qpe/timestring.h>
+#include <qpe/tzselect.h>
+
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qmultilineedit.h>
+#include <qpopupmenu.h>
+#include <qscrollview.h>
+#include <qspinbox.h>
+#include <qtoolbutton.h>
+
+#include <stdlib.h>
+
+/*
+ * Constructs a DateEntry which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+
+DateEntry::DateEntry( bool startOnMonday, const QDateTime &start,
+ const QDateTime &end, bool whichClock, QWidget* parent,
+ const char* name )
+ : DateEntryBase( parent, name ),
+ ampm( whichClock ),
+ startWeekOnMonday( startOnMonday )
+{
+ init();
+ setDates(start,end);
+}
+
+static void addOrPick( QComboBox* combo, const QString& t )
+{
+ for (int i=0; i<combo->count(); i++) {
+ if ( combo->text(i) == t ) {
+ combo->setCurrentItem(i);
+ return;
+ }
+ }
+ combo->setEditText(t);
+}
+
+DateEntry::DateEntry( bool startOnMonday, const Event &event, bool whichClock,
+ QWidget* parent, const char* name )
+ : DateEntryBase( parent, name ),
+ ampm( whichClock ),
+ startWeekOnMonday( startOnMonday )
+{
+ init();
+ setDates(event.start(),event.end());
+ comboCategory->setCategories( event.categories(), "Calendar", tr("Calendar") );
+ if(!event.description().isEmpty())
+ addOrPick( comboDescription, event.description() );
+ if(!event.location().isEmpty())
+ addOrPick( comboLocation, event.location() );
+ checkAlarm->setChecked( event.hasAlarm() );
+ checkAllDay->setChecked( event.type() == Event::AllDay );
+ if(!event.notes().isEmpty())
+ editNote->setText(event.notes());
+ spinAlarm->setValue(event.alarmTime());
+ if ( event.alarmSound() != Event::Silent )
+ comboSound->setCurrentItem( 1 );
+ if ( event.hasRepeat() ) {
+ rp = event.repeatPattern();
+ cmdRepeat->setText( tr("Repeat...") );
+ }
+ setRepeatLabel();
+}
+
+void DateEntry::setDates( const QDateTime& s, const QDateTime& e )
+{
+ int shour,
+ ehour;
+ QString strStart,
+ strEnd;
+ startDate = s.date();
+ endDate = e.date();
+ startTime = s.time();
+ endTime = e.time();
+ startDateChanged( s.date().year(), s.date().month(), s.date().day() );
+ if ( ampm ) {
+ shour = s.time().hour();
+ ehour = e.time().hour();
+ if ( shour >= 12 ) {
+ if ( shour > 12 )
+ shour -= 12;
+ strStart.sprintf( "%d:%02d PM", shour, s.time().minute() );
+ } else {
+ if ( shour == 0 )
+ shour = 12;
+ strStart.sprintf( "%d:%02d AM", shour, s.time().minute() );
+ }
+ if ( ehour == 24 && e.time().minute() == 0 ) {
+ strEnd = "11:59 PM"; // or "midnight"
+ } else if ( ehour >= 12 ) {
+ if ( ehour > 12 )
+ ehour -= 12;
+ strEnd.sprintf( "%d:%02d PM", ehour, e.time().minute() );
+ } else {
+ if ( ehour == 0 )
+ ehour = 12;
+ strEnd.sprintf( "%d:%02d AM", ehour, e.time().minute() );
+ }
+ } else {
+ strStart.sprintf( "%02d:%02d", s.time().hour(), s.time().minute() );
+ strEnd.sprintf( "%02d:%02d", e.time().hour(), e.time().minute() );
+ }
+ addOrPick(comboStart, strStart );
+ endDateChanged( e.date().year(), e.date().month(), e.date().day() );
+ addOrPick(comboEnd, strEnd );
+}
+
+void DateEntry::init()
+{
+ comboDescription->setInsertionPolicy(QComboBox::AtCurrent);
+ comboLocation->setInsertionPolicy(QComboBox::AtCurrent);
+
+ initCombos();
+ QPopupMenu *m1 = new QPopupMenu( this );
+ startPicker = new DateBookMonth( m1, 0, TRUE );
+ m1->insertItem( startPicker );
+ buttonStart->setPopup( m1 );
+ connect( startPicker, SIGNAL( dateClicked( int, int, int ) ),
+ this, SLOT( startDateChanged( int, int, int ) ) );
+
+ //Let start button change both start and end dates
+ connect( startPicker, SIGNAL( dateClicked( int, int, int ) ),
+ this, SLOT( endDateChanged( int, int, int ) ) );
+ connect( qApp, SIGNAL( clockChanged( bool ) ),
+ this, SLOT( slotChangeClock( bool ) ) );
+ connect( qApp, SIGNAL(weekChanged(bool)),
+ this, SLOT(slotChangeStartOfWeek(bool)) );
+
+ QPopupMenu *m2 = new QPopupMenu( this );
+ endPicker = new DateBookMonth( m2, 0, TRUE );
+ m2->insertItem( endPicker );
+ buttonEnd->setPopup( m2 );
+ connect( endPicker, SIGNAL( dateClicked( int, int, int ) ),
+ this, SLOT( endDateChanged( int, int, int ) ) );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+DateEntry::~DateEntry()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+/*
+ * public slot
+ */
+void DateEntry::endDateChanged( int y, int m, int d )
+{
+ endDate.setYMD( y, m, d );
+ if ( endDate < startDate ) {
+ endDate = startDate;
+ }
+
+ buttonEnd->setText( TimeString::shortDate( endDate ) );
+
+ endPicker->setDate( endDate.year(), endDate.month(), endDate.day() );
+}
+
+static QTime parseTime( const QString& s, bool ampm )
+{
+ QTime tmpTime;
+ QStringList l = QStringList::split( ':', s );
+ int hour = l[0].toInt();
+ if ( ampm ) {
+ int i=0;
+ while (i<int(l[1].length()) && l[1][i]>='0' && l[1][i]<='9')
+ i++;
+ QString digits = l[1].left(i);
+ if ( l[1].contains( "PM", FALSE ) ) {
+ if ( hour != 12 )
+ hour += 12;
+ } else {
+ if ( hour == 12 )
+ hour = 0;
+ }
+ l[1] = digits;
+ }
+ int minute = l[1].toInt();
+ if ( minute > 59 )
+ minute = 59;
+ else if ( minute < 0 )
+ minute = 0;
+ if ( hour > 23 ) {
+ hour = 23;
+ minute = 59;
+ } else if ( hour < 0 )
+ hour = 0;
+ tmpTime.setHMS( hour, minute, 0 );
+ return tmpTime;
+}
+
+/*
+ * public slot
+ */
+void DateEntry::endTimeChanged( const QString &s )
+{
+ QTime tmpTime = parseTime(s,ampm);
+ if ( endDate > startDate || tmpTime >= startTime ) {
+ endTime = tmpTime;
+ } else {
+ endTime = startTime;
+ comboEnd->setCurrentItem( comboStart->currentItem() );
+ }
+}
+
+/*
+ * public slot
+ */
+void DateEntry::startDateChanged( int y, int m, int d )
+{
+ QDate prev = startDate;
+ startDate.setYMD( y, m, d );
+ if ( rp.type == Event::Weekly &&
+ startDate.dayOfWeek() != prev.dayOfWeek() ) {
+ // if we change the start of a weekly repeating event
+ // set the repeating day appropriately
+ char mask = 1 << (prev.dayOfWeek()-1);
+ rp.days &= (~mask);
+ rp.days |= 1 << (startDate.dayOfWeek()-1);
+ }
+
+ buttonStart->setText( TimeString::shortDate( startDate ) );
+
+ // our pickers must be reset...
+ startPicker->setDate( y, m, d );
+ endPicker->setDate( y, m, d );
+}
+
+/*
+ * public slot
+ */
+void DateEntry::startTimeChanged( int index )
+{
+ startTime = parseTime(comboStart->text(index),ampm);
+ changeEndCombo( index );
+}
+/*
+ * public slot
+ */
+void DateEntry::typeChanged( const QString &s )
+{
+ bool b = s != "All Day";
+ buttonStart->setEnabled( b );
+ comboStart->setEnabled( b );
+ comboEnd->setEnabled( b );
+}
+/*
+ * public slot
+ */
+void DateEntry::changeEndCombo( int change )
+{
+ if ( change + 2 < comboEnd->count() )
+ change += 2;
+ comboEnd->setCurrentItem( change );
+ endTimeChanged( comboEnd->currentText() );
+}
+
+void DateEntry::slotRepeat()
+{
+ // Work around for compiler Bug..
+ RepeatEntry *e;
+
+ // it is better in my opinion to just grab this from the mother,
+ // since, this dialog doesn't need to keep track of it...
+ if ( rp.type != Event::NoRepeat )
+ e = new RepeatEntry( startWeekOnMonday, rp, startDate, this);
+ else
+ e = new RepeatEntry( startWeekOnMonday, startDate, this );
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ e->showMaximized();
+#endif
+ if ( e->exec() ) {
+ rp = e->repeatPattern();
+ setRepeatLabel();
+ }
+}
+
+void DateEntry::slotChangeStartOfWeek( bool onMonday )
+{
+ startWeekOnMonday = onMonday;
+}
+
+Event DateEntry::event()
+{
+ Event ev;
+ Event::SoundTypeChoice st;
+ ev.setDescription( comboDescription->currentText() );
+ ev.setLocation( comboLocation->currentText() );
+ ev.setCategories( comboCategory->currentCategories() );
+ ev.setType( checkAllDay->isChecked() ? Event::AllDay : Event::Normal );
+ if ( startDate > endDate ) {
+ QDate tmp = endDate;
+ endDate = startDate;
+ startDate = tmp;
+ }
+ startTime = parseTime( comboStart->currentText(), ampm );
+ endTime = parseTime( comboEnd->currentText(), ampm );
+ if ( startTime > endTime && endDate == startDate ) {
+ QTime tmp = endTime;
+ endTime = startTime;
+ startTime = tmp;
+ }
+ // don't set the time if theres no need too
+ if ( ev.type() == Event::AllDay ) {
+ startTime.setHMS( 0, 0, 0 );
+ endTime.setHMS( 23, 59, 59 );
+ }
+
+ // adjust start and end times based on timezone
+ QDateTime start( startDate, startTime );
+ QDateTime end( endDate, endTime );
+ time_t start_utc, end_utc;
+
+// qDebug( "tz: %s", timezone->currentZone().latin1() );
+
+ // get real timezone
+ QString realTZ;
+ realTZ = QString::fromLocal8Bit( getenv("TZ") );
+
+ // set timezone
+ if ( setenv( "TZ", timezone->currentZone(), true ) != 0 )
+ qWarning( "There was a problem setting the timezone." );
+
+ // convert to UTC based on selected TZ (calling tzset internally)
+ start_utc = TimeConversion::toUTC( start );
+ end_utc = TimeConversion::toUTC( end );
+
+ // done playing around... put it all back
+ unsetenv( "TZ" );
+ if ( !realTZ.isNull() )
+ if ( setenv( "TZ", realTZ, true ) != 0 )
+ qWarning( "There was a problem setting the timezone." );
+
+ // convert UTC to local time (calling tzset internally)
+ ev.setStart( TimeConversion::fromUTC( start_utc ) );
+ ev.setEnd( TimeConversion::fromUTC( end_utc ) );
+
+ // we only have one type of sound at the moment... LOUD!!!
+ if ( comboSound->currentItem() != 0 )
+ st = Event::Loud;
+ else
+ st = Event::Silent;
+ ev.setAlarm( checkAlarm->isChecked(), spinAlarm->value(), st );
+ if ( rp.type != Event::NoRepeat )
+ ev.setRepeat( TRUE, rp );
+ ev.setNotes( editNote->text() );
+ return ev;
+}
+
+void DateEntry::setRepeatLabel()
+{
+
+ switch( rp.type ) {
+ case Event::Daily:
+ cmdRepeat->setText( tr("Daily...") );
+ break;
+ case Event::Weekly:
+ cmdRepeat->setText( tr("Weekly...") );
+ break;
+ case Event::MonthlyDay:
+ case Event::MonthlyDate:
+ cmdRepeat->setText( tr("Monthly...") );
+ break;
+ case Event::Yearly:
+ cmdRepeat->setText( tr("Yearly...") );
+ break;
+ default:
+ cmdRepeat->setText( tr("No Repeat...") );
+ }
+}
+
+void DateEntry::setAlarmEnabled( bool alarmPreset, int presetTime, Event::SoundTypeChoice sound )
+{
+ checkAlarm->setChecked( alarmPreset );
+ spinAlarm->setValue( presetTime );
+ if ( sound != Event::Silent )
+ comboSound->setCurrentItem( 1 );
+ else
+ comboSound->setCurrentItem( 0 );
+}
+
+void DateEntry::initCombos()
+{
+ comboStart->clear();
+ comboEnd->clear();
+ if ( ampm ) {
+ for ( int i = 0; i < 24; i++ ) {
+ if ( i == 0 ) {
+ comboStart->insertItem( "12:00 AM" );
+ comboStart->insertItem( "12:30 AM" );
+ comboEnd->insertItem( "12:00 AM" );
+ comboEnd->insertItem( "12:30 AM" );
+ } else if ( i == 12 ) {
+ comboStart->insertItem( "12:00 PM" );
+ comboStart->insertItem( "12:30 PM" );
+ comboEnd->insertItem( "12:00 PM" );
+ comboEnd->insertItem( "12:30 PM" );
+ } else if ( i > 12 ) {
+ comboStart->insertItem( QString::number( i - 12 ) + ":00 PM" );
+ comboStart->insertItem( QString::number( i - 12 ) + ":30 PM" );
+ comboEnd->insertItem( QString::number( i - 12 ) + ":00 PM" );
+ comboEnd->insertItem( QString::number( i - 12 ) + ":30 PM" );
+ } else {
+ comboStart->insertItem( QString::number( i) + ":00 AM" );
+ comboStart->insertItem( QString::number( i ) + ":30 AM" );
+ comboEnd->insertItem( QString::number( i ) + ":00 AM" );
+ comboEnd->insertItem( QString::number( i ) + ":30 AM" );
+ }
+ }
+ } else {
+ for ( int i = 0; i < 24; i++ ) {
+ if ( i < 10 ) {
+ comboStart->insertItem( QString("0")
+ + QString::number(i) + ":00" );
+ comboStart->insertItem( QString("0")
+ + QString::number(i) + ":30" );
+ comboEnd->insertItem( QString("0")
+ + QString::number(i) + ":00" );
+ comboEnd->insertItem( QString("0")
+ + QString::number(i) + ":30" );
+ } else {
+ comboStart->insertItem( QString::number(i) + ":00" );
+ comboStart->insertItem( QString::number(i) + ":30" );
+ comboEnd->insertItem( QString::number(i) + ":00" );
+ comboEnd->insertItem( QString::number(i) + ":30" );
+ }
+ }
+ }
+}
+
+void DateEntry::slotChangeClock( bool whichClock )
+{
+ ampm = whichClock;
+ initCombos();
+ setDates( QDateTime( startDate, startTime ), QDateTime( endDate, endTime ) );
+}
diff --git a/core/pim/datebook/dateentryimpl.h b/core/pim/datebook/dateentryimpl.h
new file mode 100644
index 0000000..785af7a
--- a/dev/null
+++ b/core/pim/datebook/dateentryimpl.h
@@ -0,0 +1,71 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef DATEENTRY_H
+#define DATEENTRY_H
+
+#include "dateentry.h"
+
+#include <qpe/event.h>
+
+#include <qdatetime.h>
+
+class DateBookMonth;
+
+class DateEntry : public DateEntryBase
+{
+ Q_OBJECT
+
+public:
+ DateEntry( bool startOnMonday, const QDateTime &start,
+ const QDateTime &end, bool whichClock = FALSE,
+ QWidget* parent = 0, const char* name = 0 );
+ DateEntry( bool startOnMonday, const Event &event, bool whichCLock = FALSE,
+ QWidget* parent = 0, const char* name = 0 );
+ ~DateEntry();
+
+ Event event();
+ void setAlarmEnabled( bool alarmPreset, int presetTime, Event::SoundTypeChoice );
+
+public slots:
+ void endDateChanged( int, int, int );
+ void endTimeChanged( const QString & );
+ void startDateChanged(int, int, int);
+ void startTimeChanged( int index );
+ void typeChanged( const QString & );
+ void changeEndCombo( int change );
+ void slotRepeat();
+ void slotChangeClock( bool );
+ void slotChangeStartOfWeek( bool );
+
+private:
+ void init();
+ void initCombos();
+ void setDates( const QDateTime& s, const QDateTime& e );
+ void setRepeatLabel();
+
+ DateBookMonth *startPicker, *endPicker;
+ QDate startDate, endDate;
+ QTime startTime, endTime;
+ Event::RepeatPattern rp;
+ bool ampm;
+ bool startWeekOnMonday;
+};
+
+#endif // DATEENTRY_H
diff --git a/core/pim/datebook/main.cpp b/core/pim/datebook/main.cpp
new file mode 100644
index 0000000..caa5fb6
--- a/dev/null
+++ b/core/pim/datebook/main.cpp
@@ -0,0 +1,38 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "datebook.h"
+#include <qpe/qpeapplication.h>
+
+
+int main( int argc, char **argv )
+{
+ QPEApplication a( argc, argv );
+
+ DateBook e;
+ QObject::connect( &a, SIGNAL( flush() ), &e, SLOT( flush() ) );
+ QObject::connect( &a, SIGNAL( reload() ), &e, SLOT( reload() ) );
+
+
+ e.setCaption( DateBook::tr("Calendar") );
+ a.showMainWidget(&e);
+
+ return a.exec();
+}
diff --git a/core/pim/datebook/qpe-datebook.control b/core/pim/datebook/qpe-datebook.control
new file mode 100644
index 0000000..c6ab81a
--- a/dev/null
+++ b/core/pim/datebook/qpe-datebook.control
@@ -0,0 +1,9 @@
+Files: bin/datebook apps/Applications/datebook.desktop
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: A datebook/appointment manager
+ A datebook/appointment manager for the Qtopia environment.
diff --git a/core/pim/datebook/repeatentry.cpp b/core/pim/datebook/repeatentry.cpp
new file mode 100644
index 0000000..5637c4d
--- a/dev/null
+++ b/core/pim/datebook/repeatentry.cpp
@@ -0,0 +1,595 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "repeatentry.h"
+
+#include <qpe/datebookmonth.h>
+#include <qpe/qpeapplication.h>
+#include <qpe/timestring.h>
+
+#include <qbuttongroup.h>
+#include <qlabel.h>
+#include <qpopupmenu.h>
+#include <qspinbox.h>
+#include <qtoolbutton.h>
+
+#include <time.h>
+
+// Global Templates for use in setting up the repeat label...
+const QString strDayTemplate = QObject::tr("Every");
+const QString strYearTemplate = QObject::tr("%1 %2 every ");
+const QString strMonthDateTemplate = QObject::tr("The %1 every ");
+const QString strMonthDayTemplate = QObject::tr("The %1 %1 of every");
+const QString strWeekTemplate = QObject::tr("Every ");
+const QString dayLabel[] = { QObject::tr("Monday"),
+ QObject::tr("Tuesday"),
+ QObject::tr("Wednesday"),
+ QObject::tr("Thursday"),
+ QObject::tr("Friday"),
+ QObject::tr("Saturday"),
+ QObject::tr("Sunday") };
+
+
+static QString numberPlacing( int x ); // return the proper word format for
+ // x (1st, 2nd, etc)
+static int week( const QDate &dt ); // what week in the month is dt?
+
+RepeatEntry::RepeatEntry( bool startOnMonday,
+ const QDate &newStart, QWidget *parent,
+ const char *name, bool modal, WFlags fl )
+ : RepeatEntryBase( parent, name, modal, fl ),
+ start( newStart ),
+ currInterval( NONE ),
+ startWeekOnMonday( startOnMonday )
+{
+ init();
+ fraType->setButton( currInterval );
+ chkNoEnd->setChecked( TRUE );
+ setupNone();
+}
+
+RepeatEntry::RepeatEntry( bool startOnMonday, const Event::RepeatPattern &rp,
+ const QDate &startDate,
+ QWidget *parent, const char *name, bool modal,
+ WFlags fl )
+ : RepeatEntryBase( parent, name, modal, fl ),
+ start( startDate ),
+ end( rp.endDate() ),
+ startWeekOnMonday( startOnMonday )
+{
+ // do some stuff with the repeat pattern
+ init();
+ switch ( rp.type ) {
+ default:
+ case Event::NoRepeat:
+ currInterval = NONE;
+ setupNone();
+ break;
+ case Event::Daily:
+ currInterval = DAY;
+ setupDaily();
+ break;
+ case Event::Weekly:
+ currInterval = WEEK;
+ setupWeekly();
+ int day, buttons;
+ for ( day = 0x01, buttons = 0; buttons < 7;
+ day = day << 1, buttons++ ) {
+ if ( rp.days & day ) {
+ if ( startWeekOnMonday )
+ fraExtra->setButton( buttons );
+ else {
+ if ( buttons == 7 )
+ fraExtra->setButton( 0 );
+ else
+ fraExtra->setButton( buttons + 1 );
+ }
+ }
+ }
+ slotWeekLabel();
+ break;
+ case Event::MonthlyDay:
+ currInterval = MONTH;
+ setupMonthly();
+ fraExtra->setButton( 0 );
+ slotMonthLabel( 0 );
+ break;
+ case Event::MonthlyDate:
+ currInterval = MONTH;
+ setupMonthly();
+ fraExtra->setButton( 1 );
+ slotMonthLabel( 1 );
+ break;
+ case Event::Yearly:
+ currInterval = YEAR;
+ setupYearly();
+ break;
+ }
+ fraType->setButton( currInterval );
+ spinFreq->setValue( rp.frequency );
+ if ( !rp.hasEndDate ) {
+ cmdEnd->setText( RepeatEntryBase::tr("No End Date") );
+ chkNoEnd->setChecked( TRUE );
+ } else
+ cmdEnd->setText( TimeString::shortDate( end ) );
+}
+
+RepeatEntry::~RepeatEntry()
+{
+}
+
+Event::RepeatPattern RepeatEntry::repeatPattern()
+{
+ QListIterator<QToolButton> it( listRTypeButtons );
+ QListIterator<QToolButton> itExtra( listExtra );
+ Event::RepeatPattern rpTmp;
+ int i;
+ for ( i = 0; *it; ++it, i++ ) {
+ if ( (*it)->isOn() ) {
+ switch ( i ) {
+ case NONE:
+ rpTmp.type = Event::NoRepeat;
+ break;
+ case DAY:
+ rpTmp.type = Event::Daily;
+ break;
+ case WEEK:
+ rpTmp.type = Event::Weekly;
+ rpTmp.days = 0;
+ int day;
+ for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
+ if ( (*itExtra)->isOn() ) {
+ if ( startWeekOnMonday )
+ rpTmp.days |= day;
+ else {
+ if ( day == 1 )
+ rpTmp.days |= Event::SUN;
+ else
+ rpTmp.days |= day >> 1;
+ }
+ }
+ }
+ break;
+ case MONTH:
+ if ( cmdExtra1->isOn() )
+ rpTmp.type = Event::MonthlyDay;
+ else if ( cmdExtra2->isOn() )
+ rpTmp.type = Event::MonthlyDate;
+ // figure out the montly day...
+ rpTmp.position = week( start );
+ break;
+ case YEAR:
+ rpTmp.type = Event::Yearly;
+ break;
+ }
+ break; // no need to keep looking!
+ }
+ }
+ rpTmp.frequency = spinFreq->value();
+ rpTmp.hasEndDate = !chkNoEnd->isChecked();
+ if ( rpTmp.hasEndDate ) {
+ rpTmp.setEndDate( end );
+ }
+ // timestamp it...
+ rpTmp.createTime = time( NULL );
+ return rpTmp;
+}
+
+void RepeatEntry::slotSetRType( int rtype )
+{
+ // now call the right function based on the type...
+ currInterval = static_cast<repeatButtons>(rtype);
+ switch ( currInterval ) {
+ case NONE:
+ setupNone();
+ break;
+ case DAY:
+ setupDaily();
+ break;
+ case WEEK:
+ setupWeekly();
+ slotWeekLabel();
+ break;
+ case MONTH:
+ setupMonthly();
+ cmdExtra2->setOn( TRUE );
+ slotMonthLabel( 1 );
+ break;
+ case YEAR:
+ setupYearly();
+ break;
+ }
+}
+
+void RepeatEntry::setupNone()
+{
+ lblRepeat->setText( tr("No Repeat") );
+ lblVar1->hide();
+ lblVar2->hide();
+ hideExtras();
+ cmdEnd->hide();
+ lblFreq->hide();
+ lblEvery->hide();
+ lblFreq->hide();
+ spinFreq->hide();
+ lblEnd->hide();
+ lblWeekVar->hide();
+}
+
+void RepeatEntry::setupDaily()
+{
+ hideExtras();
+ lblWeekVar->hide();
+ spinFreq->setValue( 1 );
+ lblFreq->setText( tr("day(s)") );
+ lblVar2->show();
+ showRepeatStuff();
+ lblRepeat->setText( strDayTemplate );
+ setupRepeatLabel( 1 );
+}
+
+void RepeatEntry::setupWeekly()
+{
+ // reshow the buttons...
+ fraExtra->setTitle( RepeatEntryBase::tr("Repeat On") );
+ fraExtra->setExclusive( FALSE );
+ fraExtra->show();
+ if ( startWeekOnMonday ) {
+ cmdExtra1->setText( RepeatEntryBase::tr("Mon") );
+ cmdExtra2->setText( RepeatEntryBase::tr("Tue") );
+ cmdExtra3->setText( RepeatEntryBase::tr("Wed") );
+ cmdExtra4->setText( RepeatEntryBase::tr("Thu") );
+ cmdExtra5->setText( RepeatEntryBase::tr("Fri") );
+ cmdExtra6->setText( RepeatEntryBase::tr("Sat") );
+ cmdExtra7->setText( RepeatEntryBase::tr("Sun") );
+ } else {
+ cmdExtra1->setText( RepeatEntryBase::tr("Sun") );
+ cmdExtra2->setText( RepeatEntryBase::tr("Mon") );
+ cmdExtra3->setText( RepeatEntryBase::tr("Tue") );
+ cmdExtra4->setText( RepeatEntryBase::tr("Wed") );
+ cmdExtra5->setText( RepeatEntryBase::tr("Thu") );
+ cmdExtra6->setText( RepeatEntryBase::tr("Fri") );
+ cmdExtra7->setText( RepeatEntryBase::tr("Sat") );
+ }
+ // I hope clustering these improve performance....
+ cmdExtra1->setOn( FALSE );
+ cmdExtra2->setOn( FALSE );
+ cmdExtra3->setOn( FALSE );
+ cmdExtra4->setOn( FALSE );
+ cmdExtra5->setOn( FALSE );
+ cmdExtra6->setOn( FALSE );
+ cmdExtra7->setOn( FALSE );
+
+ cmdExtra1->show();
+ cmdExtra2->show();
+ cmdExtra3->show();
+ cmdExtra4->show();
+ cmdExtra5->show();
+ cmdExtra6->show();
+ cmdExtra7->show();
+
+ lblWeekVar->show();
+ spinFreq->setValue( 1 );
+ // might as well set the day too...
+ if ( startWeekOnMonday ) {
+ fraExtra->setButton( start.dayOfWeek() - 1 );
+ } else {
+ fraExtra->setButton( start.dayOfWeek() % 7 );
+ }
+ lblFreq->setText( tr("week(s)") );
+ lblVar2->show();
+ showRepeatStuff();
+ setupRepeatLabel( 1 );
+}
+
+void RepeatEntry::setupMonthly()
+{
+ hideExtras();
+ lblWeekVar->hide();
+ fraExtra->setTitle( tr("Repeat By") );
+ fraExtra->setExclusive( TRUE );
+ fraExtra->show();
+ cmdExtra1->setText( tr("Day") );
+ cmdExtra1->show();
+ cmdExtra2->setText( tr("Date") );
+ cmdExtra2->show();
+ spinFreq->setValue( 1 );
+ lblFreq->setText( tr("month(s)") );
+ lblVar2->show();
+ showRepeatStuff();
+ setupRepeatLabel( 1 );
+}
+
+void RepeatEntry::setupYearly()
+{
+ hideExtras();
+ lblWeekVar->hide();
+ spinFreq->setValue( 1 );
+ lblFreq->setText( tr("year(s)") );
+ lblFreq->show();
+ lblFreq->show();
+ showRepeatStuff();
+ lblVar2->show();
+ QString strEvery = strYearTemplate.arg( start.monthName(start.month()) ).arg( numberPlacing(start.day()) );
+ lblRepeat->setText( strEvery );
+ setupRepeatLabel( 1 );
+
+}
+
+void RepeatEntry::init()
+{
+ QPopupMenu *m1 = new QPopupMenu( this );
+ repeatPicker = new DateBookMonth( m1, 0, TRUE );
+ m1->insertItem( repeatPicker );
+ cmdEnd->setPopup( m1 );
+ cmdEnd->setPopupDelay( 0 );
+
+ QObject::connect( repeatPicker, SIGNAL(dateClicked(int, int, int)),
+ this, SLOT(endDateChanged(int, int, int)) );
+ QObject::connect( qApp, SIGNAL(weekChanged(bool)),
+ this, SLOT(slotChangeStartOfWeek(bool)) );
+
+ listRTypeButtons.setAutoDelete( TRUE );
+ listRTypeButtons.append( cmdNone );
+ listRTypeButtons.append( cmdDay );
+ listRTypeButtons.append( cmdWeek );
+ listRTypeButtons.append( cmdMonth );
+ listRTypeButtons.append( cmdYear );
+
+ listExtra.setAutoDelete( TRUE );
+ listExtra.append( cmdExtra1 );
+ listExtra.append( cmdExtra2 );
+ listExtra.append( cmdExtra3 );
+ listExtra.append( cmdExtra4 );
+ listExtra.append( cmdExtra5 );
+ listExtra.append( cmdExtra6 );
+ listExtra.append( cmdExtra7 );
+}
+
+void RepeatEntry::slotNoEnd( bool unused )
+{
+ // if the item was toggled, then go ahead and set it to the maximum date
+ if ( unused ) {
+ end.setYMD( 3000, 12, 31 );
+ cmdEnd->setText( RepeatEntryBase::tr("No End Date") );
+ } else {
+ end = start;
+ cmdEnd->setText( TimeString::shortDate(end) );
+ }
+}
+
+void RepeatEntry::endDateChanged( int y, int m, int d )
+{
+ end.setYMD( y, m, d );
+ if ( end < start )
+ end = start;
+ cmdEnd->setText( TimeString::shortDate( end ) );
+ repeatPicker->setDate( end.year(), end.month(), end.day() );
+}
+
+void RepeatEntry::setupRepeatLabel( const QString &s )
+{
+ lblVar1->setText( s );
+}
+
+void RepeatEntry::setupRepeatLabel( int x )
+{
+ // change the spelling based on the value of x
+ QString strVar2;
+
+ if ( x > 1 )
+ lblVar1->show();
+ else
+ lblVar1->hide();
+
+ switch ( currInterval ) {
+ case NONE:
+ break;
+ case DAY:
+ if ( x > 1 )
+ strVar2 = tr( "days" );
+ else
+ strVar2 = tr( "day" );
+ break;
+ case WEEK:
+ if ( x > 1 )
+ strVar2 = tr( "weeks" );
+ else
+ strVar2 = tr( "week" );
+ break;
+ case MONTH:
+ if ( x > 1 )
+ strVar2 = RepeatEntryBase::tr( "months" );
+ else
+ strVar2 = tr( "month" );
+ break;
+ case YEAR:
+ if ( x > 1 )
+ strVar2 = RepeatEntryBase::tr( "years" );
+ else
+ strVar2 = tr( "year" );
+ break;
+ }
+ if ( !strVar2.isNull() )
+ lblVar2->setText( strVar2 );
+}
+
+void RepeatEntry::showRepeatStuff()
+{
+ cmdEnd->show();
+ chkNoEnd->show();
+ lblFreq->show();
+ lblEvery->show();
+ lblFreq->show();
+ spinFreq->show();
+ lblEnd->show();
+ lblRepeat->setText( RepeatEntryBase::tr("Every") );
+}
+
+void RepeatEntry::slotWeekLabel()
+{
+ QString str;
+ QListIterator<QToolButton> it( listExtra );
+ unsigned int i;
+ unsigned int keepMe;
+ bool bNeedCarriage = FALSE;
+ // don't do something we'll regret!!!
+ if ( currInterval != WEEK )
+ return;
+
+ if ( startWeekOnMonday )
+ keepMe = start.dayOfWeek() - 1;
+ else
+ keepMe = start.dayOfWeek() % 7;
+
+ QStringList list;
+ for ( i = 0; *it; ++it, i++ ) {
+ // a crazy check, if you are repeating weekly, the current day
+ // must be selected!!!
+ if ( i == keepMe && !( (*it)->isOn() ) )
+ (*it)->setOn( TRUE );
+ if ( (*it)->isOn() ) {
+ if ( startWeekOnMonday )
+ list.append( dayLabel[i] );
+ else {
+ if ( i == 0 )
+ list.append( dayLabel[6] );
+ else
+ list.append( dayLabel[i - 1] );
+ }
+ }
+ }
+ QStringList::Iterator itStr;
+ for ( i = 0, itStr = list.begin(); itStr != list.end(); ++itStr, i++ ) {
+ if ( i == 3 )
+ bNeedCarriage = TRUE;
+ else
+ bNeedCarriage = FALSE;
+ if ( str.isNull() )
+ str = *itStr;
+ else if ( i == list.count() - 1 ) {
+ if ( i < 2 )
+ str += tr(" and ") + *itStr;
+ else {
+ if ( bNeedCarriage )
+ str += tr( ",\nand " ) + *itStr;
+ else
+ str += tr( ", and " ) + *itStr;
+ }
+ } else {
+ if ( bNeedCarriage )
+ str += ",\n" + *itStr;
+ else
+ str += ", " + *itStr;
+ }
+ }
+ str = str.prepend( "on " );
+ lblWeekVar->setText( str );
+}
+
+void RepeatEntry::slotMonthLabel( int type )
+{
+ QString str;
+ if ( currInterval != MONTH || type > 1 )
+ return;
+ if ( type == 1 )
+ str = strMonthDateTemplate.arg( numberPlacing(start.day()) );
+ else
+ str = strMonthDayTemplate.arg( numberPlacing(week(start)))
+ .arg( dayLabel[start.dayOfWeek() - 1] );
+ lblRepeat->setText( str );
+}
+
+void RepeatEntry::slotChangeStartOfWeek( bool onMonday )
+{
+ startWeekOnMonday = onMonday;
+ // we need to make this unintrusive as possible...
+ int saveSpin = spinFreq->value();
+ char days = 0;
+ int day;
+ QListIterator<QToolButton> itExtra( listExtra );
+ for ( day = 1; *itExtra; ++itExtra, day = day << 1 ) {
+ if ( (*itExtra)->isOn() ) {
+ if ( !startWeekOnMonday )
+ days |= day;
+ else {
+ if ( day == 1 )
+ days |= Event::SUN;
+ else
+ days |= day >> 1;
+ }
+ }
+ }
+ setupWeekly();
+ spinFreq->setValue( saveSpin );
+ int buttons;
+ for ( day = 0x01, buttons = 0; buttons < 7;
+ day = day << 1, buttons++ ) {
+ if ( days & day ) {
+ if ( startWeekOnMonday )
+ fraExtra->setButton( buttons );
+ else {
+ if ( buttons == 7 )
+ fraExtra->setButton( 0 );
+ else
+ fraExtra->setButton( buttons + 1 );
+ }
+ }
+ }
+ slotWeekLabel();
+}
+
+static int week( const QDate &start )
+{
+ // figure out the week...
+ int stop = start.day(),
+ sentinel = start.dayOfWeek(),
+ dayOfWeek = QDate( start.year(), start.month(), 1 ).dayOfWeek(),
+ week = 1,
+ i;
+ for ( i = 1; i < stop; i++ ) {
+ if ( dayOfWeek++ == sentinel )
+ week++;
+ if ( dayOfWeek > 7 )
+ dayOfWeek = 0;
+ }
+ return week;
+}
+
+static QString numberPlacing( int x )
+{
+ // I hope this works in other languages besides english...
+ QString str = QString::number( x );
+ switch ( x % 10 ) {
+ case 1:
+ str += QWidget::tr( "st" );
+ break;
+ case 2:
+ str += QWidget::tr( "nd" );
+ break;
+ case 3:
+ str += QWidget::tr( "rd" );
+ break;
+ default:
+ str += QWidget::tr( "th" );
+ break;
+ }
+ return str;
+}
diff --git a/core/pim/datebook/repeatentry.h b/core/pim/datebook/repeatentry.h
new file mode 100644
index 0000000..949fecd
--- a/dev/null
+++ b/core/pim/datebook/repeatentry.h
@@ -0,0 +1,98 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef REPEATENTRY_H
+#define REPEATENTRY_H
+
+#include "repeatentrybase.h"
+
+#include <qpe/event.h>
+
+#include <qcheckbox.h>
+#include <qbuttongroup.h>
+#include <qdatetime.h>
+#include <qlist.h>
+#include <qtoolbutton.h>
+
+class DateBookMonth;
+
+class RepeatEntry : public RepeatEntryBase
+{
+ Q_OBJECT
+public:
+ RepeatEntry( bool startOnMonday,
+ const QDate &start, QWidget *parent = 0, const char *name = 0,
+ bool modal = TRUE, WFlags fl = 0 );
+ RepeatEntry( bool startOnMonday,
+ const Event::RepeatPattern &rp, const QDate &start,
+ QWidget *parent = 0, const char *name = 0, bool modal = TRUE,
+ WFlags fl = 0 );
+ ~RepeatEntry();
+
+ Event::RepeatPattern repeatPattern();
+ QDate endDate() { return end; };
+
+public slots:
+ void slotSetRType( int );
+ void endDateChanged( int, int, int );
+ void slotNoEnd( bool unused );
+
+private slots:
+ void setupRepeatLabel( const QString& );
+ void setupRepeatLabel( int );
+ void slotWeekLabel();
+ void slotMonthLabel( int );
+ void slotChangeStartOfWeek( bool onMonday );
+
+private:
+ void setupNone();
+ void setupDaily();
+ void setupWeekly();
+ void setupMonthly();
+ void setupYearly();
+
+ enum repeatButtons { NONE, DAY, WEEK, MONTH, YEAR };
+ void init();
+ inline void hideExtras();
+ void showRepeatStuff();
+
+ QList<QToolButton> listRTypeButtons;
+ QList<QToolButton> listExtra;
+ QDate start; // only used in one spot...
+ QDate end;
+ repeatButtons currInterval;
+ bool startWeekOnMonday;
+ DateBookMonth *repeatPicker;
+};
+
+inline void RepeatEntry::hideExtras()
+{
+ // hide the extra buttons...
+ fraExtra->hide();
+ chkNoEnd->hide();
+ QListIterator<QToolButton> it( listExtra );
+ for ( ; *it; ++it ) {
+ (*it)->hide();
+ (*it)->setOn( FALSE );
+ }
+
+}
+
+#endif
diff --git a/core/pim/datebook/repeatentrybase.ui b/core/pim/datebook/repeatentrybase.ui
new file mode 100644
index 0000000..9621d74
--- a/dev/null
+++ b/core/pim/datebook/repeatentrybase.ui
@@ -0,0 +1,713 @@
+<!DOCTYPE UI><UI>
+<class>RepeatEntryBase</class>
+<comment>*********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+*********************************************************************</comment>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>RepeatEntryBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>250</width>
+ <height>309</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Repeating Event </string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>1</number>
+ </property>
+ <widget>
+ <class>QButtonGroup</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>fraType</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>NoFrame</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string></string>
+ </property>
+ <property stdset="1">
+ <name>exclusive</name>
+ <bool>true</bool>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>1</number>
+ </property>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdNone</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>None</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdDay</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Day</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdWeek</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Week</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdMonth</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Month</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdYear</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Year</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout4</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblEvery</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Every:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>spinFreq</cstring>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>1</number>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblFreq</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Frequency</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout8</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblEnd</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>End On:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdEnd</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>No End Date</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>chkNoEnd</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>No End Date</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QButtonGroup</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>fraExtra</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Box</enum>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Repeat On</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>1</number>
+ </property>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Mon</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Tue</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra3</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Wed</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra4</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Thu</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra5</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Fri</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra6</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Sat</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdExtra7</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Sun</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QFrame</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Frame3</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>Box</enum>
+ </property>
+ <property stdset="1">
+ <name>frameShadow</name>
+ <enum>Sunken</enum>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>5</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>1</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout6</cstring>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblRepeat</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>3</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Every</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblVar1</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Var1</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblVar2</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>4</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Var 2</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignRight</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblWeekVar</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>7</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>WeekVar</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignHCenter</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>chkNoEnd</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdEnd</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>chkNoEnd</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>RepeatEntryBase</receiver>
+ <slot>slotNoEnd(bool)</slot>
+ </connection>
+ <connection>
+ <sender>spinFreq</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>lblVar1</receiver>
+ <slot>setNum(int)</slot>
+ </connection>
+ <connection>
+ <sender>spinFreq</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>RepeatEntryBase</receiver>
+ <slot>setupRepeatLabel( int )</slot>
+ </connection>
+ <connection>
+ <sender>fraType</sender>
+ <signal>clicked(int)</signal>
+ <receiver>RepeatEntryBase</receiver>
+ <slot>slotSetRType( int )</slot>
+ </connection>
+ <connection>
+ <sender>fraExtra</sender>
+ <signal>clicked(int)</signal>
+ <receiver>RepeatEntryBase</receiver>
+ <slot>slotMonthLabel( int )</slot>
+ </connection>
+ <connection>
+ <sender>fraExtra</sender>
+ <signal>clicked(int)</signal>
+ <receiver>RepeatEntryBase</receiver>
+ <slot>slotWeekLabel()</slot>
+ </connection>
+ <slot access="public">setupRepeatLabel( const QString &amp; )</slot>
+ <slot access="public">setupRepeatLabel( int )</slot>
+ <slot access="public">slotMonthLabel( int )</slot>
+ <slot access="public">slotNoEnd(bool)</slot>
+ <slot access="public">slotSetRType( int )</slot>
+ <slot access="public">slotWeekLabel()</slot>
+</connections>
+</UI>
diff --git a/core/pim/todo/.cvsignore b/core/pim/todo/.cvsignore
new file mode 100644
index 0000000..5ed04d8
--- a/dev/null
+++ b/core/pim/todo/.cvsignore
@@ -0,0 +1,4 @@
+moc_*
+Makefile
+todoentry.h
+todoentry.cpp
diff --git a/core/pim/todo/Makefile.in b/core/pim/todo/Makefile.in
new file mode 100644
index 0000000..f3c5f0e
--- a/dev/null
+++ b/core/pim/todo/Makefile.in
@@ -0,0 +1,201 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = todolist
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = mainwindow.h \
+ todotable.h \
+ todoentryimpl.h
+SOURCES = main.cpp \
+ mainwindow.cpp \
+ todotable.cpp \
+ todoentryimpl.cpp
+OBJECTS = main.o \
+ mainwindow.o \
+ todotable.o \
+ todoentryimpl.o \
+ todoentry.o
+INTERFACES = todoentry.ui
+UICDECLS = todoentry.h
+UICIMPLS = todoentry.cpp
+SRCMOC = moc_mainwindow.cpp \
+ moc_todotable.cpp \
+ moc_todoentryimpl.cpp \
+ moc_todoentry.cpp
+OBJMOC = moc_mainwindow.o \
+ moc_todotable.o \
+ moc_todoentryimpl.o \
+ moc_todoentry.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake todo.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+main.o: main.cpp \
+ mainwindow.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+mainwindow.o: mainwindow.cpp \
+ mainwindow.h \
+ todoentryimpl.h \
+ todoentry.h \
+ $(QPEDIR)/include/qpe/task.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/stringutil.h \
+ todotable.h \
+ $(QPEDIR)/include/qpe/categories.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/finddialog.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/ir.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ $(QPEDIR)/include/qpe/qpemessagebox.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h
+
+todotable.o: todotable.cpp \
+ todotable.h \
+ $(QPEDIR)/include/qpe/categories.h \
+ $(QPEDIR)/include/qpe/task.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/stringutil.h \
+ $(QPEDIR)/include/qpe/categoryselect.h \
+ $(QPEDIR)/include/qpe/xmlreader.h
+
+todoentryimpl.o: todoentryimpl.cpp \
+ todoentryimpl.h \
+ todoentry.h \
+ $(QPEDIR)/include/qpe/task.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/stringutil.h \
+ $(QPEDIR)/include/qpe/categoryselect.h \
+ $(QPEDIR)/include/qpe/datebookmonth.h \
+ $(QPEDIR)/include/qpe/event.h \
+ $(QPEDIR)/include/qpe/global.h \
+ $(QPEDIR)/include/qpe/imageedit.h \
+ $(QPEDIR)/include/qpe/timestring.h
+
+todoentry.h: todoentry.ui
+ $(UIC) todoentry.ui -o $(INTERFACE_DECL_PATH)/todoentry.h
+
+todoentry.cpp: todoentry.ui
+ $(UIC) todoentry.ui -i todoentry.h -o todoentry.cpp
+
+todoentry.o: todoentry.cpp \
+ todoentry.h \
+ todoentry.ui
+
+moc_mainwindow.o: moc_mainwindow.cpp \
+ mainwindow.h
+
+moc_todotable.o: moc_todotable.cpp \
+ todotable.h \
+ $(QPEDIR)/include/qpe/categories.h \
+ $(QPEDIR)/include/qpe/task.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/stringutil.h
+
+moc_todoentryimpl.o: moc_todoentryimpl.cpp \
+ todoentryimpl.h \
+ todoentry.h \
+ $(QPEDIR)/include/qpe/task.h \
+ $(QPEDIR)/include/qpe/palmtoprecord.h \
+ $(QPEDIR)/include/qpe/stringutil.h
+
+moc_todoentry.o: moc_todoentry.cpp \
+ todoentry.h
+
+moc_mainwindow.cpp: mainwindow.h
+ $(MOC) mainwindow.h -o moc_mainwindow.cpp
+
+moc_todotable.cpp: todotable.h
+ $(MOC) todotable.h -o moc_todotable.cpp
+
+moc_todoentryimpl.cpp: todoentryimpl.h
+ $(MOC) todoentryimpl.h -o moc_todoentryimpl.cpp
+
+moc_todoentry.cpp: todoentry.h
+ $(MOC) todoentry.h -o moc_todoentry.cpp
+
+
diff --git a/core/pim/todo/main.cpp b/core/pim/todo/main.cpp
new file mode 100644
index 0000000..4e1c8a1
--- a/dev/null
+++ b/core/pim/todo/main.cpp
@@ -0,0 +1,36 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "mainwindow.h"
+
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char **argv )
+{
+ QPEApplication a( argc, argv );
+
+ TodoWindow mw;
+ QObject::connect( &a, SIGNAL( flush() ), &mw, SLOT( flush() ) );
+ QObject::connect( &a, SIGNAL( reload() ), &mw, SLOT( reload() ) );
+
+ a.showMainWidget(&mw);
+
+ return a.exec();
+}
diff --git a/core/pim/todo/mainwindow.cpp b/core/pim/todo/mainwindow.cpp
new file mode 100644
index 0000000..fb85a09
--- a/dev/null
+++ b/core/pim/todo/mainwindow.cpp
@@ -0,0 +1,466 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "mainwindow.h"
+#include "todoentryimpl.h"
+#include "todotable.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/config.h>
+#include <qpe/finddialog.h>
+#include <qpe/global.h>
+#include <qpe/ir.h>
+#include <qpe/qpemenubar.h>
+#include <qpe/qpemessagebox.h>
+#include <qpe/resource.h>
+#include <qpe/task.h>
+#include <qpe/qpetoolbar.h>
+
+#include <qaction.h>
+#include <qarray.h>
+#include <qdatastream.h>
+#include <qdatetime.h>
+#include <qfile.h>
+#include <qmessagebox.h>
+#include <qpopupmenu.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <stdlib.h>
+
+static QString todolistXMLFilename()
+{
+ return Global::applicationFileName("todolist","todolist.xml");
+}
+
+static QString categoriesXMLFilename()
+{
+ return Global::applicationFileName("todolist","categories.xml");
+}
+
+TodoWindow::TodoWindow( QWidget *parent, const char *name, WFlags f = 0 ) :
+ QMainWindow( parent, name, f ), syncing(FALSE)
+{
+// QTime t;
+// t.start();
+
+ setCaption( tr("Todo") );
+ QString str;
+ table = new TodoTable( this );
+ table->setColumnWidth( 2, 10 );
+ table->setPaintingEnabled( FALSE );
+ table->setUpdatesEnabled( FALSE );
+ table->viewport()->setUpdatesEnabled( FALSE );
+
+ {
+ str = todolistXMLFilename();
+ if ( str.isNull() )
+ QMessageBox::critical( this,
+ tr("Out of Space"),
+ tr("Unable to create startup files\n"
+ "Free up some space\n"
+ "before you enter any data") );
+ else
+ table->load( str );
+ }
+
+ // repeat for categories...
+ str = categoriesXMLFilename();
+ if ( str.isNull() )
+ QMessageBox::critical( this,
+ tr( "Out of Space" ),
+ tr( "Unable to create startup files\n"
+ "Free up some space\n"
+ "before you enter any data") );
+
+ setCentralWidget( table );
+ setToolBarsMovable( FALSE );
+
+// qDebug("after load: t=%d", t.elapsed() );
+
+ Config config( "todo" );
+ config.setGroup( "View" );
+ bool complete = config.readBoolEntry( "ShowComplete", true );
+ table->setShowCompleted( complete );
+ QString category = config.readEntry( "Category", QString::null );
+ table->setShowCategory( category );
+
+ QPEToolBar *bar = new QPEToolBar( this );
+ bar->setHorizontalStretchable( TRUE );
+
+ QPEMenuBar *mb = new QPEMenuBar( bar );
+
+ catMenu = new QPopupMenu( this );
+ QPopupMenu *edit = new QPopupMenu( this );
+ contextMenu = new QPopupMenu( this );
+
+ bar = new QPEToolBar( this );
+
+ QAction *a = new QAction( tr( "New Task" ), Resource::loadPixmap( "new" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ),
+ this, SLOT( slotNew() ) );
+ a->addTo( bar );
+ a->addTo( edit );
+ a = new QAction( tr( "Edit" ), Resource::loadIconSet( "edit" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ),
+ this, SLOT( slotEdit() ) );
+ a->addTo( bar );
+ a->addTo( edit );
+ a->addTo( contextMenu );
+ a->setEnabled( FALSE );
+ editAction = a;
+ a = new QAction( tr( "Delete" ), Resource::loadIconSet( "trash" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ),
+ this, SLOT( slotDelete() ) );
+ a->addTo( bar );
+ a->addTo( edit );
+ a->addTo( contextMenu );
+ a->setEnabled( FALSE );
+ deleteAction = a;
+
+ if ( Ir::supported() ) {
+ a = new QAction( tr( "Beam" ), Resource::loadPixmap( "beam" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ),
+ this, SLOT( slotBeam() ) );
+ a->addTo( edit );
+ a->addTo( bar );
+ }
+
+ a = new QAction( tr( "Find" ), Resource::loadIconSet( "mag" ),
+ QString::null, 0, this, 0 );
+ connect( a, SIGNAL( activated() ),
+ this, SLOT( slotFind() ) );
+ a->addTo( bar );
+ a->addTo( edit );
+ if ( table->numRows() )
+ a->setEnabled( TRUE );
+ else
+ a->setEnabled( FALSE );
+
+ //a->setEnabled( FALSE );
+ findAction = a;
+// qDebug("mainwindow #2: t=%d", t.elapsed() );
+
+ completedAction = new QAction( QString::null, tr("Completed tasks"), 0, this, 0, TRUE );
+
+ catMenu->setCheckable( true );
+ populateCategories();
+
+ mb->insertItem( tr( "Task" ), edit );
+ mb->insertItem( tr( "View" ), catMenu );
+
+ resize( 200, 300 );
+ if ( table->numRows() > 0 )
+ currentEntryChanged( 0, 0 );
+ connect( table, SIGNAL( signalEdit() ),
+ this, SLOT( slotEdit() ) );
+ connect( table, SIGNAL(signalShowMenu(const QPoint &)),
+ this, SLOT( slotShowPopup(const QPoint &)) );
+
+// qDebug("mainwindow #3: t=%d", t.elapsed() );
+ table->updateVisible();
+ table->setUpdatesEnabled( TRUE );
+ table->setPaintingEnabled( TRUE );
+ table->viewport()->setUpdatesEnabled( TRUE );
+
+ connect( completedAction, SIGNAL( toggled(bool) ), this, SLOT( showCompleted(bool) ) );
+ connect( catMenu, SIGNAL(activated(int)), this, SLOT(setCategory(int)) );
+ connect( table, SIGNAL( currentChanged( int, int ) ),
+ this, SLOT( currentEntryChanged( int, int ) ) );
+
+// qDebug("done: t=%d", t.elapsed() );
+}
+
+void TodoWindow::slotNew()
+{
+ if(syncing) {
+ QMessageBox::warning(this, tr("Todo"),
+ tr("Can not edit data, currently syncing"));
+ return;
+ }
+
+ int id;
+ id = -1;
+ QArray<int> ids;
+ ids = table->currentEntry().categories();
+ if ( ids.count() )
+ id = ids[0];
+ NewTaskDialog e( id, this, 0, TRUE );
+
+ Task todo;
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ e.showMaximized();
+#endif
+ int ret = e.exec();
+
+ if ( ret == QDialog::Accepted ) {
+ table->setPaintingEnabled( false );
+ todo = e.todoEntry();
+ todo.assignUid();
+ table->addEntry( todo );
+ table->setPaintingEnabled( true );
+ findAction->setEnabled( TRUE );
+ }
+ // I'm afraid we must call this every time now, otherwise
+ // spend expensive time comparing all these strings...
+ populateCategories();
+}
+
+TodoWindow::~TodoWindow()
+{
+}
+
+void TodoWindow::slotDelete()
+{
+ if(syncing) {
+ QMessageBox::warning(this, tr("Todo"),
+ tr("Can not edit data, currently syncing"));
+ return;
+ }
+
+ if ( table->currentRow() == -1 )
+ return;
+
+ QString strName = table->text( table->currentRow(), 2 ).left( 30 );
+
+ if ( !QPEMessageBox::confirmDelete( this, tr( "Todo" ), strName ) )
+ return;
+
+
+
+ table->setPaintingEnabled( false );
+ table->removeCurrentEntry();
+ table->setPaintingEnabled( true );
+
+ if ( table->numRows() == 0 ) {
+ currentEntryChanged( -1, 0 );
+ findAction->setEnabled( FALSE );
+ }
+}
+
+void TodoWindow::slotEdit()
+{
+ if(syncing) {
+ QMessageBox::warning(this, tr("Todo"),
+ tr("Can not edit data, currently syncing"));
+ return;
+ }
+
+ Task todo = table->currentEntry();
+
+ NewTaskDialog e( todo, this, 0, TRUE );
+ e.setCaption( tr( "Edit Task" ) );
+
+#if defined(Q_WS_QWS) || defined(_WS_QWS_)
+ e.showMaximized();
+#endif
+ int ret = e.exec();
+
+ if ( ret == QDialog::Accepted ) {
+ table->setPaintingEnabled( false );
+ todo = e.todoEntry();
+ table->replaceCurrentEntry( todo );
+ table->setPaintingEnabled( true );
+ }
+ populateCategories();
+
+}
+
+void TodoWindow::slotShowPopup( const QPoint &p )
+{
+ contextMenu->popup( p );
+}
+
+void TodoWindow::showCompleted( bool s )
+{
+ if ( !table->isUpdatesEnabled() )
+ return;
+ table->setPaintingEnabled( false );
+ table->setShowCompleted( s );
+ table->setPaintingEnabled( true );
+}
+
+void TodoWindow::currentEntryChanged( int r, int )
+{
+ if ( r != -1 && table->rowHeight( r ) > 0 ) {
+ editAction->setEnabled( TRUE );
+ deleteAction->setEnabled( TRUE );
+ } else {
+ editAction->setEnabled( FALSE );
+ deleteAction->setEnabled( FALSE );
+ }
+}
+
+void TodoWindow::setCategory( int c )
+{
+ if ( c <= 0 ) return;
+ if ( !table->isUpdatesEnabled() )
+ return;
+ table->setPaintingEnabled( false );
+ for ( unsigned int i = 1; i < catMenu->count(); i++ )
+ catMenu->setItemChecked( i, c == (int)i );
+ if ( c == 1 ) {
+ table->setShowCategory( QString::null );
+ setCaption( tr("Todo") + " - " + tr( "All" ) );
+ } else if ( c == (int)catMenu->count() - 1 ) {
+ table->setShowCategory( tr( "Unfiled" ) );
+ setCaption( tr("Todo") + " - " + tr( "Unfiled" ) );
+ } else {
+ QString cat = table->categories()[c - 2];
+ table->setShowCategory( cat );
+ setCaption( tr("Todo") + " - " + cat );
+ }
+ table->setPaintingEnabled( true );
+}
+
+void TodoWindow::populateCategories()
+{
+ catMenu->clear();
+
+ completedAction->addTo( catMenu );
+ completedAction->setOn( table->showCompleted() );
+
+ int id,
+ rememberId;
+ id = 1;
+ catMenu->insertItem( tr( "All" ), id++ );
+// catMenu->insertSeparator();
+ QStringList categories = table->categories();
+ categories.append( tr( "Unfiled" ) );
+ for ( QStringList::Iterator it = categories.begin();
+ it != categories.end(); ++it ) {
+ catMenu->insertItem( *it, id );
+ if ( *it == table->showCategory() )
+ rememberId = id;
+ ++id;
+ }
+ if ( table->showCategory().isEmpty() )
+ setCategory( 1 );
+ else
+ setCategory( rememberId );
+}
+
+void TodoWindow::reload()
+{
+ table->clear();
+ table->load( todolistXMLFilename() );
+ syncing = FALSE;
+}
+
+void TodoWindow::flush()
+{
+ syncing = TRUE;
+ table->save( todolistXMLFilename() );
+}
+
+void TodoWindow::closeEvent( QCloseEvent *e )
+{
+ if(syncing) {
+ /* no need to save if in the middle of syncing */
+ e->accept();
+ return;
+ }
+
+ if ( table->save( todolistXMLFilename() ) ) {
+ e->accept();
+ // repeat for categories...
+ // if writing configs fail, it will emit an
+ // error, but I feel that it is "ok" for us to exit
+ // espically since we aren't told if the write succeeded...
+ Config config( "todo" );
+ config.setGroup( "View" );
+ config.writeEntry( "ShowComplete", table->showCompleted() );
+ config.writeEntry( "Category", table->showCategory() );
+ } else {
+ if ( QMessageBox::critical( this, tr("Out of space"),
+ tr("Todo was unable\n"
+ "to save your changes.\n"
+ "Free up some space\n"
+ "and try again.\n"
+ "\nQuit Anyway?"),
+ QMessageBox::Yes|QMessageBox::Escape,
+ QMessageBox::No|QMessageBox::Default)
+ != QMessageBox::No )
+ e->accept();
+ else
+ e->ignore();
+ }
+}
+
+void TodoWindow::slotFind()
+{
+ // put everything back to view all for searching...
+ if ( !catMenu->isItemChecked( 0 ) )
+ setCategory( 0 );
+
+ FindDialog dlg( "Todo List", this );
+ QObject::connect( &dlg,
+ SIGNAL(signalFindClicked(const QString &,
+ bool, bool, int)),
+ table,
+ SLOT(slotDoFind(const QString&, bool, bool, int)) );
+ QObject::connect( table, SIGNAL(signalNotFound()), &dlg,
+ SLOT(slotNotFound()) );
+ QObject::connect( table, SIGNAL(signalWrapAround()), &dlg,
+ SLOT(slotWrapAround()) );
+ dlg.exec();
+ if ( table->numSelections() )
+ table->clearSelection();
+ table->clearFindRow();
+}
+
+
+void TodoWindow::setDocument( const QString &filename )
+{
+ if ( filename.find(".vcs") != int(filename.length()) - 4 ) return;
+
+ QValueList<Task> tl = Task::readVCalendar( filename );
+ for( QValueList<Task>::Iterator it = tl.begin(); it != tl.end(); ++it ) {
+ table->addEntry( *it );
+ }
+}
+
+static const char * beamfile = "/tmp/obex/todo.vcs";
+
+void TodoWindow::slotBeam()
+{
+ unlink( beamfile ); // delete if exists
+ Task c = table->currentEntry();
+ mkdir("/tmp/obex/", 0755);
+ Task::writeVCalendar( beamfile, c );
+ Ir *ir = new Ir( this );
+ connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) );
+ QString description = c.description();
+ ir->send( beamfile, description, "text/x-vCalendar" );
+}
+
+void TodoWindow::beamDone( Ir *ir )
+{
+ delete ir;
+ unlink( beamfile );
+}
diff --git a/core/pim/todo/mainwindow.h b/core/pim/todo/mainwindow.h
new file mode 100644
index 0000000..f4fcd1b
--- a/dev/null
+++ b/core/pim/todo/mainwindow.h
@@ -0,0 +1,73 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <qmainwindow.h>
+
+class TodoTable;
+class QAction;
+class QPopupMenu;
+class Ir;
+
+class TodoWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ TodoWindow( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
+ ~TodoWindow();
+
+public slots:
+ void flush();
+ void reload();
+
+protected slots:
+ void slotNew();
+ void slotDelete();
+ void slotEdit();
+ void slotShowPopup( const QPoint & );
+ void showCompleted( bool );
+ void currentEntryChanged( int r, int c );
+ void setCategory( int );
+ void slotFind();
+ void setDocument( const QString & );
+ void slotBeam();
+ void beamDone( Ir * );
+
+protected:
+ void closeEvent( QCloseEvent *e );
+
+private:
+ void populateCategories();
+
+private:
+ TodoTable *table;
+ QAction *editAction,
+ *deleteAction,
+ *findAction,
+ * completedAction;
+ QPopupMenu *contextMenu, *catMenu;
+
+ bool syncing;
+};
+
+#endif
diff --git a/core/pim/todo/qpe-todo.control b/core/pim/todo/qpe-todo.control
new file mode 100644
index 0000000..80195a0
--- a/dev/null
+++ b/core/pim/todo/qpe-todo.control
@@ -0,0 +1,9 @@
+Files: bin/todolist apps/Applications/todo.desktop
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: TODO-list manager
+ A Todo-list manager for the Qtopia environment.
diff --git a/core/pim/todo/todo.pro b/core/pim/todo/todo.pro
new file mode 100644
index 0000000..e28ea1c
--- a/dev/null
+++ b/core/pim/todo/todo.pro
@@ -0,0 +1,19 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(QPEDIR)/bin
+HEADERS = mainwindow.h \
+ todotable.h \
+ todoentryimpl.h
+SOURCES = main.cpp \
+ mainwindow.cpp \
+ todotable.cpp \
+ todoentryimpl.cpp
+
+INTERFACES = todoentry.ui
+
+TARGET = todolist
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TRANSLATIONS = ../i18n/de/todolist.ts
diff --git a/core/pim/todo/todoentry.ui b/core/pim/todo/todoentry.ui
new file mode 100644
index 0000000..c735e76
--- a/dev/null
+++ b/core/pim/todo/todoentry.ui
@@ -0,0 +1,266 @@
+<!DOCTYPE UI><UI>
+<class>NewTaskDialogBase</class>
+<comment>*********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+*********************************************************************</comment>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>NewTaskDialogBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>249</width>
+ <height>321</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>New Task</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout4</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Priority:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>1 - Very High</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>2 - High</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>3 - Normal</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>4 - Low</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>5 - Very Low</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboPriority</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>currentItem</name>
+ <number>2</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout3</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property stdset="1">
+ <name>frameShape</name>
+ <enum>NoFrame</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Category:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>CategorySelect</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>comboCategory</cstring>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout4</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>checkCompleted</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&amp;Completed</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>checkDate</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>D&amp;ue</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>buttonDate</cstring>
+ </property>
+ <property stdset="1">
+ <name>enabled</name>
+ <bool>false</bool>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>1 Jan 2001</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QMultiLineEdit</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>txtTodo</cstring>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>CategorySelect</class>
+ <header location="global">qpe/categoryselect.h</header>
+ <sizehint>
+ <width>-1</width>
+ <height>-1</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>1</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="646">789c6dd2c10ac2300c00d07bbf2234b7229d1be245fc04c5a3201e4615f430059d0711ff5ddb2e6bb236ec90eed134cb5a19d8ef36602af5ecdbfeeac05dda0798d3abebde87e3faa374d3807fa0d633a52d38d8de6f679fe33fc776e196f53cd010188256a3600a292882096246517815ca99884606e18044a3a40d91824820924265a7923a2e8bcd05f33db1173e002913175f2a6be6d3294871a2d95fa00e8a94ee017b69d339d90df1e77c57ea072ede6758</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>checkDate</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>buttonDate</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <slot access="protected">dateChanged( const QString &amp; )</slot>
+ <slot access="protected">dateChanged( int, int, int )</slot>
+</connections>
+</UI>
diff --git a/core/pim/todo/todoentryimpl.cpp b/core/pim/todo/todoentryimpl.cpp
new file mode 100644
index 0000000..79206de
--- a/dev/null
+++ b/core/pim/todo/todoentryimpl.cpp
@@ -0,0 +1,142 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "todoentryimpl.h"
+
+#include <qpe/categoryselect.h>
+#include <qpe/datebookmonth.h>
+#include <qpe/global.h>
+#include <qpe/imageedit.h>
+#include <qpe/task.h>
+#include <qpe/timestring.h>
+
+#include <qmessagebox.h>
+#include <qpopupmenu.h>
+#include <qtoolbutton.h>
+#include <qcombobox.h>
+#include <qcheckbox.h>
+#include <qlineedit.h>
+#include <qmultilineedit.h>
+#include <qlabel.h>
+#include <qtimer.h>
+#include <qapplication.h>
+
+
+NewTaskDialog::NewTaskDialog( const Task& task, QWidget *parent,
+ const char *name, bool modal, WFlags fl )
+ : NewTaskDialogBase( parent, name, modal, fl ),
+ todo( task )
+{
+ todo.setCategories( task.categories() );
+ if ( todo.hasDueDate() )
+ date = todo.dueDate();
+ else
+ date = QDate::currentDate();
+
+ init();
+ comboPriority->setCurrentItem( task.priority() - 1 );
+
+ checkCompleted->setChecked( task.isCompleted() );
+ checkDate->setChecked( task.hasDueDate() );
+ buttonDate->setText( TimeString::longDateString( date ) );
+
+ txtTodo->setText( task.description() );
+}
+
+/*
+ * Constructs a NewTaskDialog which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+NewTaskDialog::NewTaskDialog( int id, QWidget* parent, const char* name, bool modal,
+ WFlags fl )
+ : NewTaskDialogBase( parent, name, modal, fl ),
+ date( QDate::currentDate() )
+{
+ if ( id != -1 ) {
+ QArray<int> ids( 1 );
+ ids[0] = id;
+ todo.setCategories( ids );
+ }
+ init();
+}
+
+void NewTaskDialog::init()
+{
+ QPopupMenu *m1 = new QPopupMenu( this );
+ picker = new DateBookMonth( m1, 0, TRUE );
+ m1->insertItem( picker );
+ buttonDate->setPopup( m1 );
+ comboCategory->setCategories( todo.categories(), "Todo List", tr("Todo List") );
+
+ connect( picker, SIGNAL( dateClicked( int, int, int ) ),
+ this, SLOT( dateChanged( int, int, int ) ) );
+
+ buttonDate->setText( TimeString::longDateString( date ) );
+ picker->setDate( date.year(), date.month(), date.day() );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+NewTaskDialog::~NewTaskDialog()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+void NewTaskDialog::dateChanged( int y, int m, int d )
+{
+ date = QDate( y, m, d );
+ buttonDate->setText( TimeString::longDateString( date ) );
+}
+
+/*!
+*/
+
+Task NewTaskDialog::todoEntry()
+{
+ todo.setDueDate( date, checkDate->isChecked() );
+ if ( comboCategory->currentCategory() != -1 ) {
+ todo.setCategories( comboCategory->currentCategories() );
+ }
+ todo.setPriority( comboPriority->currentItem() + 1 );
+ todo.setCompleted( checkCompleted->isChecked() );
+
+ todo.setDescription( txtTodo->text() );
+
+ return todo;
+}
+
+
+/*!
+
+*/
+
+void NewTaskDialog::accept()
+{
+ QString strText = txtTodo->text();
+ if ( !strText || strText == "") {
+ // hmm... just decline it then, the user obviously didn't care about it
+ QDialog::reject();
+ return;
+ }
+ QDialog::accept();
+}
diff --git a/core/pim/todo/todoentryimpl.h b/core/pim/todo/todoentryimpl.h
new file mode 100644
index 0000000..932d66e
--- a/dev/null
+++ b/core/pim/todo/todoentryimpl.h
@@ -0,0 +1,61 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef NEWTASKDIALOG_H
+#define NEWTASKDIALOG_H
+
+#include "todoentry.h"
+
+#include <qpe/task.h>
+
+#include <qdatetime.h>
+#include <qpalette.h>
+
+class QLabel;
+class QTimer;
+class DateBookMonth;
+
+class NewTaskDialog : public NewTaskDialogBase
+{
+ Q_OBJECT
+
+public:
+ NewTaskDialog( const Task &task, QWidget *parent = 0, const char* name = 0,
+ bool modal = FALSE, WFlags fl = 0 );
+ NewTaskDialog( int id, QWidget* parent = 0, const char* name = 0,
+ bool modal = FALSE, WFlags fl = 0 );
+ ~NewTaskDialog();
+
+ Task todoEntry();
+
+protected slots:
+ void dateChanged( int y, int m, int d );
+
+protected:
+ virtual void accept();
+
+private:
+ void init();
+ Task todo;
+ QDate date;
+ DateBookMonth *picker;
+};
+
+#endif // NEWTASKDIALOG_H
diff --git a/core/pim/todo/todotable.cpp b/core/pim/todo/todotable.cpp
new file mode 100644
index 0000000..77d3389
--- a/dev/null
+++ b/core/pim/todo/todotable.cpp
@@ -0,0 +1,859 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "todotable.h"
+
+#include <qpe/categoryselect.h>
+#include <qpe/xmlreader.h>
+
+#include <qasciidict.h>
+#include <qcombobox.h>
+#include <qfile.h>
+#include <qpainter.h>
+#include <qtextcodec.h>
+#include <qtimer.h>
+#include <qdatetime.h>
+
+#include <qcursor.h>
+#include <qregexp.h>
+
+#include <errno.h>
+#include <stdlib.h>
+
+
+
+static bool taskCompare( const Task &task, const QRegExp &r, int category );
+
+static QString journalFileName();
+
+CheckItem::CheckItem( QTable *t, const QString &key )
+ : QTableItem( t, Never, "" ), checked( FALSE ), sortKey( key )
+{
+}
+
+QString CheckItem::key() const
+{
+ return sortKey;
+}
+
+void CheckItem::setChecked( bool b )
+{
+ checked = b;
+ table()->updateCell( row(), col() );
+}
+
+void CheckItem::toggle()
+{
+ TodoTable *parent = static_cast<TodoTable*>(table());
+ Task newTodo = parent->currentEntry();
+ checked = !checked;
+ newTodo.setCompleted( checked );
+ table()->updateCell( row(), col() );
+ parent->replaceCurrentEntry( newTodo, true );
+}
+
+bool CheckItem::isChecked() const
+{
+ return checked;
+}
+
+static const int BoxSize = 10;
+
+void CheckItem::paint( QPainter *p, const QColorGroup &cg, const QRect &cr,
+ bool )
+{
+ p->fillRect( 0, 0, cr.width(), cr.height(), cg.brush( QColorGroup::Base ) );
+
+ int marg = ( cr.width() - BoxSize ) / 2;
+ int x = 0;
+ int y = ( cr.height() - BoxSize ) / 2;
+ p->setPen( QPen( cg.text() ) );
+ p->drawRect( x + marg, y, BoxSize, BoxSize );
+ p->drawRect( x + marg+1, y+1, BoxSize-2, BoxSize-2 );
+ p->setPen( darkGreen );
+ x += 1;
+ y += 1;
+ if ( checked ) {
+ QPointArray a( 7*2 );
+ int i, xx, yy;
+ xx = x+1+marg;
+ yy = y+2;
+ for ( i=0; i<3; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy++;
+ }
+ yy -= 2;
+ for ( i=3; i<7; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy--;
+ }
+ p->drawLineSegments( a );
+ }
+}
+
+
+ComboItem::ComboItem( QTable *t, EditType et )
+ : QTableItem( t, et, "3" ), cb( 0 )
+{
+ setReplaceable( FALSE );
+}
+
+QWidget *ComboItem::createEditor() const
+{
+ QString txt = text();
+ ( (ComboItem*)this )->cb = new QComboBox( table()->viewport() );
+ cb->insertItem( "1" );
+ cb->insertItem( "2" );
+ cb->insertItem( "3" );
+ cb->insertItem( "4" );
+ cb->insertItem( "5" );
+ cb->setCurrentItem( txt.toInt() - 1 );
+ return cb;
+}
+
+void ComboItem::setContentFromEditor( QWidget *w )
+{
+ TodoTable *parent = static_cast<TodoTable*>(table());
+ Task newTodo = parent->currentEntry();
+
+ if ( w->inherits( "QComboBox" ) )
+ setText( ( (QComboBox*)w )->currentText() );
+ else
+ QTableItem::setContentFromEditor( w );
+ newTodo.setPriority( text().toInt() );
+ parent->replaceCurrentEntry( newTodo, true );
+}
+
+void ComboItem::setText( const QString &s )
+{
+ if ( cb )
+ cb->setCurrentItem( s.toInt() - 1 );
+ QTableItem::setText( s );
+}
+
+QString ComboItem::text() const
+{
+ if ( cb )
+ return cb->currentText();
+ return QTableItem::text();
+}
+
+
+
+TodoTable::TodoTable( QWidget *parent, const char *name )
+// #ifdef QT_QTABLE_NOHEADER_CONSTRUCTOR
+// : QTable( 0, 3, parent, name, TRUE ),
+// #else
+ : QTable( 0, 3, parent, name ),
+// #endif
+ showComp( true ),
+ enablePainting( true ),
+ mCat( 0 ),
+ currFindRow( -2 )
+{
+ mCat.load( categoryFileName() );
+ setSorting( TRUE );
+ setSelectionMode( NoSelection );
+ setColumnStretchable( 2, TRUE );
+ setColumnWidth( 0, 20 );
+ setColumnWidth( 1, 35 );
+ setLeftMargin( 0 );
+ verticalHeader()->hide();
+ horizontalHeader()->setLabel( 0, tr( "C." ) );
+ horizontalHeader()->setLabel( 1, tr( "Prior." ) );
+ horizontalHeader()->setLabel( 2, tr( "Description" ) );
+ connect( this, SIGNAL( clicked( int, int, int, const QPoint & ) ),
+ this, SLOT( slotClicked( int, int, int, const QPoint & ) ) );
+ connect( this, SIGNAL( pressed( int, int, int, const QPoint & ) ),
+ this, SLOT( slotPressed( int, int, int, const QPoint & ) ) );
+ connect( this, SIGNAL( valueChanged( int, int ) ),
+ this, SLOT( slotCheckPriority( int, int ) ) );
+ connect( this, SIGNAL( currentChanged( int, int ) ),
+ this, SLOT( slotCurrentChanged( int, int ) ) );
+
+ menuTimer = new QTimer( this );
+ connect( menuTimer, SIGNAL(timeout()), this, SLOT(slotShowMenu()) );
+}
+
+void TodoTable::addEntry( const Task &todo )
+{
+ int row = numRows();
+ setNumRows( row + 1 );
+ updateJournal( todo, ACTION_ADD );
+ insertIntoTable( new Task(todo), row );
+ setCurrentCell(row, currentColumn());
+ updateVisible();
+}
+
+void TodoTable::slotClicked( int row, int col, int, const QPoint &pos )
+{
+ if ( !cellGeometry( row, col ).contains(pos) )
+ return;
+ // let's switch on the column number...
+ switch ( col )
+ {
+ case 0: {
+ CheckItem *i = static_cast<CheckItem*>(item( row, col ));
+ if ( i ) {
+ int x = pos.x() - columnPos( col );
+ int y = pos.y() - rowPos( row );
+ int w = columnWidth( col );
+ int h = rowHeight( row );
+ if ( i && x >= ( w - BoxSize ) / 2 && x <= ( w - BoxSize ) / 2 + BoxSize &&
+ y >= ( h - BoxSize ) / 2 && y <= ( h - BoxSize ) / 2 + BoxSize ) {
+ i->toggle();
+ }
+ emit signalDoneChanged( i->isChecked() );
+ }
+ }
+ break;
+ case 1:
+ break;
+ case 2:
+ // may as well edit it...
+ menuTimer->stop();
+// emit signalEdit();
+ break;
+ }
+}
+
+void TodoTable::slotPressed( int row, int col, int, const QPoint &pos )
+{
+ if ( col == 2 && cellGeometry( row, col ).contains(pos) )
+ menuTimer->start( 750, TRUE );
+}
+
+void TodoTable::slotShowMenu()
+{
+ emit signalShowMenu( QCursor::pos() );
+}
+
+void TodoTable::slotCurrentChanged( int, int )
+{
+ menuTimer->stop();
+}
+
+void TodoTable::internalAddEntries( QList<Task> &list )
+{
+ setNumRows( list.count() );
+ int row = 0;
+ Task *it;
+ for ( it = list.first(); it; it = list.next() )
+ insertIntoTable( it, row++ );
+}
+
+
+Task TodoTable::currentEntry() const
+{
+ QTableItem *i = item( currentRow(), 0 );
+ if ( !i || rowHeight( currentRow() ) <= 0 )
+ return Task();
+ Task *todo = todoList[(CheckItem*)i];
+ todo->setCompleted( ( (CheckItem*)item( currentRow(), 0 ) )->isChecked() );
+ todo->setPriority( ( (ComboItem*)item( currentRow(), 1 ) )->text().toInt() );
+ return *todo;
+}
+
+void TodoTable::replaceCurrentEntry( const Task &todo, bool fromTableItem )
+{
+ int row = currentRow();
+ updateJournal( todo, ACTION_REPLACE, row );
+
+ if ( !fromTableItem ) {
+ journalFreeReplaceEntry( todo, row );
+ updateVisible();
+ }
+}
+
+void TodoTable::removeCurrentEntry()
+{
+ Task *oldTodo;
+ int row = currentRow();
+ CheckItem *chk;
+
+ chk = static_cast<CheckItem*>(item(row, 0 ));
+ if ( !chk )
+ return;
+ oldTodo = todoList[chk];
+ todoList.remove( chk );
+ oldTodo->setCompleted( chk->isChecked() );
+ oldTodo->setPriority( static_cast<ComboItem*>(item(row, 1))->text().toInt() );
+ realignTable( row );
+ updateVisible();
+ updateJournal( *oldTodo, ACTION_REMOVE, row );
+ delete oldTodo;
+}
+
+
+bool TodoTable::save( const QString &fn )
+{
+ QString strNewFile = fn + ".new";
+ QFile f( strNewFile );
+ if ( !f.open( IO_WriteOnly|IO_Raw ) )
+ return false;
+
+ QString buf("<!DOCTYPE Tasks>\n<Tasks>\n");
+ QCString str;
+ int total_written;
+
+ for ( QMap<CheckItem*, Task *>::Iterator it = todoList.begin();
+ it != todoList.end(); ++it ) {
+ if ( !item( it.key()->row(), 0 ) )
+ continue;
+ Task *todo = *it;
+ // sync item with table
+ todo->setCompleted( ((CheckItem*)item(it.key()->row(), 0))->isChecked() );
+ todo->setPriority( ((ComboItem*)item( it.key()->row(), 1))->text().toInt() );
+ buf += "<Task";
+ todo->save( buf );
+ buf += " />\n";
+ str = buf.utf8();
+ total_written = f.writeBlock( str.data(), str.length() );
+ if ( total_written != int(str.length()) ) {
+ f.close();
+ QFile::remove( strNewFile );
+ return false;
+ }
+ buf = "";
+ }
+
+ buf += "</Tasks>\n";
+ str = buf.utf8();
+ total_written = f.writeBlock( str.data(), str.length() );
+ if ( total_written != int(str.length()) ) {
+ f.close();
+ QFile::remove( strNewFile );
+ return false;
+ }
+ f.close();
+
+ // now do the rename
+ if ( ::rename( strNewFile, fn ) < 0 )
+ qWarning( "problem renaming file %s to %s errno %d",
+ strNewFile.latin1(), fn.latin1(), errno );
+
+ // remove the journal
+ QFile::remove( journalFileName() );
+ return true;
+}
+
+void TodoTable::load( const QString &fn )
+{
+ loadFile( fn, false );
+ if ( QFile::exists(journalFileName()) ) {
+ loadFile( journalFileName(), true );
+ save( fn );
+ }
+// QTable::sortColumn(2,TRUE,TRUE);
+// QTable::sortColumn(1,TRUE,TRUE);
+ QTable::sortColumn(0,TRUE,TRUE);
+ setCurrentCell( 0, 2 );
+}
+
+void TodoTable::updateVisible()
+{
+ if ( !isUpdatesEnabled() )
+ return;
+
+// qDebug("--> updateVisible!");
+
+ int visible = 0;
+ int id = mCat.id( "Todo List", showCat );
+ for ( int row = 0; row < numRows(); row++ ) {
+ CheckItem *ci = (CheckItem *)item( row, 0 );
+ Task *t = todoList[ci];
+ QArray<int> vlCats = t->categories();
+ bool hide = false;
+ if ( !showComp && ci->isChecked() )
+ hide = true;
+ if ( !showCat.isEmpty() ) {
+ if ( showCat == tr( "Unfiled" ) ) {
+ if ( vlCats.count() > 0 )
+ hide = true;
+ } else {
+ // do some comparing, we have to reverse our idea here...
+ if ( !hide ) {
+ hide = true;
+ for ( uint it = 0; it < vlCats.count(); ++it ) {
+ if ( vlCats[it] == id ) {
+ hide = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if ( hide ) {
+ if ( currentRow() == row )
+ setCurrentCell( -1, 0 );
+ if ( rowHeight( row ) > 0 )
+ hideRow( row );
+ } else {
+ if ( rowHeight( row ) == 0 ) {
+ showRow( row );
+ adjustRow( row );
+ }
+ visible++;
+ }
+ }
+ if ( !visible )
+ setCurrentCell( -1, 0 );
+}
+
+void TodoTable::viewportPaintEvent( QPaintEvent *pe )
+{
+ if ( enablePainting )
+ QTable::viewportPaintEvent( pe );
+}
+
+void TodoTable::setPaintingEnabled( bool e )
+{
+ if ( e != enablePainting ) {
+ if ( !enablePainting ) {
+ enablePainting = true;
+ rowHeightChanged( 0 );
+ viewport()->update();
+ } else {
+ enablePainting = false;
+ }
+ }
+}
+
+void TodoTable::clear()
+{
+ for ( QMap<CheckItem*, Task *>::Iterator it = todoList.begin();
+ it != todoList.end(); ++it ) {
+ Task *todo = *it;
+ delete todo;
+ }
+ todoList.clear();
+ for ( int r = 0; r < numRows(); ++r ) {
+ for ( int c = 0; c < numCols(); ++c ) {
+ if ( cellWidget( r, c ) )
+ clearCellWidget( r, c );
+ clearCell( r, c );
+ }
+ }
+ setNumRows( 0 );
+}
+
+void TodoTable::sortColumn( int col, bool /*ascending*/, bool /*wholeRows*/ )
+{
+ // The default for wholeRows is false, however
+ // for this todo table we want to exchange complete
+ // rows when sorting. Also, we always want ascending, since
+ // the values have a logical order.
+ QTable::sortColumn( col, TRUE, TRUE );
+ updateVisible();
+}
+
+void TodoTable::slotCheckPriority(int row, int col )
+{
+ // kludgey work around to make forward along the updated priority...
+ if ( col == 1 ) {
+ // let everyone know!!
+ ComboItem* i = static_cast<ComboItem*>( item( row, col ) );
+ emit signalPriorityChanged( i->text().toInt() );
+ }
+}
+
+
+void TodoTable::updateJournal( const Task &todo, journal_action action, int row )
+{
+ QFile f( journalFileName() );
+ if ( !f.open(IO_WriteOnly|IO_Append) )
+ return;
+ QString buf;
+ QCString str;
+ buf = "<Task";
+ todo.save( buf );
+ buf += " Action=\"" + QString::number( int(action) ) + "\"";
+ buf += " Row=\"" + QString::number( row ) + "\"";
+ buf += "/>\n";
+ str = buf.utf8();
+ f.writeBlock( str.data(), str.length() );
+ f.close();
+}
+
+void TodoTable::rowHeightChanged( int row )
+{
+ if ( enablePainting )
+ QTable::rowHeightChanged( row );
+}
+
+void TodoTable::loadFile( const QString &strFile, bool fromJournal )
+{
+ QFile f( strFile );
+ if ( !f.open(IO_ReadOnly) )
+ return;
+
+ int action, row;
+ action = 0; row = 0;
+
+ enum Attribute {
+ FCompleted = 0,
+ FHasDate,
+ FPriority,
+ FCategories,
+ FDescription,
+ FDateYear,
+ FDateMonth,
+ FDateDay,
+ FUid,
+ FAction,
+ FRow
+ };
+
+ QAsciiDict<int> dict( 31 );
+ QList<Task> list;
+ dict.setAutoDelete( TRUE );
+ dict.insert( "Completed", new int(FCompleted) );
+ dict.insert( "HasDate", new int(FHasDate) );
+ dict.insert( "Priority", new int(FPriority) );
+ dict.insert( "Categories", new int(FCategories) );
+ dict.insert( "Description", new int(FDescription) );
+ dict.insert( "DateYear", new int(FDateYear) );
+ dict.insert( "DateMonth", new int(FDateMonth) );
+ dict.insert( "DateDay", new int(FDateDay) );
+ dict.insert( "Uid", new int(FUid) );
+ dict.insert( "Action", new int(FAction) );
+ dict.insert( "Row", new int(FRow) );
+
+ QByteArray ba = f.readAll();
+ f.close();
+ char* dt = ba.data();
+ int len = ba.size();
+ bool hasDueDate = FALSE;
+
+ action = ACTION_ADD;
+ int i = 0;
+ char *point;
+ while ( ( point = strstr( dt+i, "<Task " ) ) != NULL ) {
+ // new Task
+ i = point - dt;
+ Task *todo = new Task;
+ int dtY = 0, dtM = 0, dtD = 0;
+
+ i += 5;
+
+ while( 1 ) {
+ while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
+ ++i;
+ if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
+ break;
+ // we have another attribute, read it.
+ int j = i;
+ while ( j < len && dt[j] != '=' )
+ ++j;
+ char *attr = dt+i;
+ dt[j] = '\0';
+ i = ++j; // skip =
+ while ( i < len && dt[i] != '"' )
+ ++i;
+ j = ++i;
+ bool haveUtf = FALSE;
+ bool haveEnt = FALSE;
+ while ( j < len && dt[j] != '"' ) {
+ if ( ((unsigned char)dt[j]) > 0x7f )
+ haveUtf = TRUE;
+ if ( dt[j] == '&' )
+ haveEnt = TRUE;
+ ++j;
+ }
+ if ( i == j ) {
+ // empty value
+ i = j + 1;
+ continue;
+ }
+ QCString value( dt+i, j-i+1 );
+ i = j + 1;
+ int *lookup = dict[ attr ];
+ if ( !lookup ) {
+ todo->setCustomField(attr, value);
+ continue;
+ }
+ switch( *lookup ) {
+ case FCompleted:
+ todo->setCompleted( value.toInt() );
+ break;
+ case FHasDate:
+ // leave...
+ hasDueDate = value.toInt();
+ break;
+ case FPriority:
+ todo->setPriority( value.toInt() );
+ break;
+ case FCategories: {
+ //QString str = Qtopia::plainString( value );
+ todo->setCategories( Qtopia::Record::idsFromString( value ) );
+ break;
+ }
+ case FDescription:
+ {
+ QString str = (haveUtf ? QString::fromUtf8( value )
+ : QString::fromLatin1( value ) );
+ if ( haveEnt )
+ str = Qtopia::plainString( str );
+ todo->setDescription( str );
+ break;
+ }
+ case FDateYear:
+ dtY = value.toInt();
+ break;
+ case FDateMonth:
+ dtM = value.toInt();
+ break;
+ case FDateDay:
+ dtD = value.toInt();
+ break;
+ case FUid:
+ todo->setUid( value.toInt() );
+ break;
+ case FAction:
+ action = value.toInt();
+ break;
+ case FRow:
+ row = value.toInt();
+ break;
+ default:
+ qDebug( "huh??? missing enum? -- attr.: %s", attr );
+ break;
+ }
+ }
+
+ if ( dtY != 0 && dtM != 0 && dtD != 0 )
+ todo->setDueDate( QDate( dtY, dtM, dtD), hasDueDate );
+ else
+ todo->setHasDueDate( hasDueDate );
+
+// if ( categoryList.find( todo.category() ) == categoryList.end() )
+// categoryList.append( todo.category() );
+
+
+ // sadly we can't delay adding of items from the journal to get
+ // the proper effect, but then, the journal should _never_ be
+ // that huge
+
+ switch( action ) {
+ case ACTION_ADD:
+ if ( fromJournal ) {
+ int myrows = numRows();
+ setNumRows( myrows + 1 );
+ insertIntoTable( todo, myrows );
+ delete todo;
+ } else
+ list.append( todo );
+ break;
+ case ACTION_REMOVE:
+ journalFreeRemoveEntry( row );
+ break;
+ case ACTION_REPLACE:
+ journalFreeReplaceEntry( *todo, row );
+ delete todo;
+ break;
+ default:
+ break;
+ }
+ }
+// qDebug("parsing done=%d", t.elapsed() );
+ if ( list.count() > 0 ) {
+ internalAddEntries( list );
+ list.clear();
+ }
+// qDebug("loading done: t=%d", t.elapsed() );
+}
+
+void TodoTable::journalFreeReplaceEntry( const Task &todo, int row )
+{
+ QString strTodo;
+ strTodo = todo.description().left(40).simplifyWhiteSpace();
+ if ( row == -1 ) {
+ QMapIterator<CheckItem*, Task *> it;
+ for ( it = todoList.begin(); it != todoList.end(); ++it ) {
+ if ( *(*it) == todo ) {
+ row = it.key()->row();
+ it.key()->setChecked( todo.isCompleted() );
+ static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) );
+ item( row, 2 )->setText( strTodo );
+ *(*it) = todo;
+ }
+ }
+ } else {
+ Task *t = todoList[static_cast<CheckItem*>(item(row, 0))];
+ todoList.remove( static_cast<CheckItem*>(item(row, 0)) );
+ delete t;
+ static_cast<CheckItem*>(item(row, 0))->setChecked( todo.isCompleted() );
+ static_cast<ComboItem*>(item(row, 1))->setText( QString::number(todo.priority()) );
+ item( row, 2 )->setText( strTodo );
+ todoList.insert( static_cast<CheckItem*>(item(row,0)), new Task(todo) );
+ }
+}
+
+void TodoTable::journalFreeRemoveEntry( int row )
+{
+ CheckItem *chk;
+ chk = static_cast<CheckItem*>(item(row, 0 ));
+ if ( !chk )
+ return;
+ todoList.remove( chk );
+
+ realignTable( row );
+}
+
+void TodoTable::keyPressEvent( QKeyEvent *e )
+{
+ if ( e->key() == Key_Space || e->key() == Key_Return ) {
+ switch ( currentColumn() ) {
+ case 0: {
+ CheckItem *i = static_cast<CheckItem*>(item(currentRow(),
+ currentColumn()));
+ if ( i )
+ i->toggle();
+ break;
+ }
+ case 1:
+ break;
+ case 2:
+ emit signalEdit();
+ default:
+ break;
+ }
+ } else {
+ QTable::keyPressEvent( e );
+ }
+}
+
+QStringList TodoTable::categories()
+{
+ // This is called seldom, so calling a load in here
+ // should be fine.
+ mCat.load( categoryFileName() );
+ QStringList categoryList = mCat.labels( "Todo List" );
+ return categoryList;
+}
+
+void TodoTable::slotDoFind( const QString &findString, bool caseSensitive,
+ bool backwards, int category )
+{
+ // we have to iterate through the table, this gives the illusion that
+ // sorting is actually being used.
+ if ( currFindRow < -1 )
+ currFindRow = currentRow() - 1;
+ clearSelection( TRUE );
+ int rows,
+ row;
+ CheckItem *chk;
+ QRegExp r( findString );
+
+ r.setCaseSensitive( caseSensitive );
+ rows = numRows();
+ static bool wrapAround = true;
+
+ if ( !backwards ) {
+ for ( row = currFindRow + 1; row < rows; row++ ) {
+ chk = static_cast<CheckItem*>( item(row, 0) );
+ if ( taskCompare(*(todoList[chk]), r, category) )
+ break;
+ }
+ } else {
+ for ( row = currFindRow - 1; row > -1; row-- ) {
+ chk = static_cast<CheckItem*>( item(row, 0) );
+ if ( taskCompare(*(todoList[chk]), r, category) )
+ break;
+ }
+ }
+ if ( row >= rows || row < 0 ) {
+ if ( row < 0 )
+ currFindRow = rows;
+ else
+ currFindRow = -1;
+ if ( wrapAround )
+ emit signalWrapAround();
+ else
+ emit signalNotFound();
+ wrapAround = !wrapAround;
+ } else {
+ currFindRow = row;
+ QTableSelection foundSelection;
+ foundSelection.init( currFindRow, 0 );
+ foundSelection.expandTo( currFindRow, numCols() - 1 );
+ addSelection( foundSelection );
+ setCurrentCell( currFindRow, numCols() - 1 );
+ // we should always be able to wrap around and find this again,
+ // so don't give confusing not found message...
+ wrapAround = true;
+ }
+}
+
+int TodoTable::showCategoryId() const
+{
+ int id;
+ id = -1;
+ // if allcategories are selected, you get unfiled...
+ if ( showCat != tr( "Unfiled" ) && showCat != tr( "All" ) )
+ id = mCat.id( "Todo List", showCat );
+ return id;
+}
+
+static bool taskCompare( const Task &task, const QRegExp &r, int category )
+{
+ bool returnMe;
+ QArray<int> cats;
+ cats = task.categories();
+
+ returnMe = false;
+ if ( (category == -1 && cats.count() == 0) || category == -2 )
+ returnMe = task.match( r );
+ else {
+ int i;
+ for ( i = 0; i < int(cats.count()); i++ ) {
+ if ( cats[i] == category ) {
+ returnMe = task.match( r );
+ break;
+ }
+ }
+ }
+ return returnMe;
+}
+
+static QString journalFileName()
+{
+ QString str;
+ str = getenv( "HOME" );
+ str += "/.todojournal";
+ return str;
+}
+
+// int TodoTable::rowHeight( int ) const
+// {
+// return 18;
+// }
+
+// int TodoTable::rowPos( int row ) const
+// {
+// return 18*row;
+// }
+
+// int TodoTable::rowAt( int pos ) const
+// {
+// return QMIN( pos/18, numRows()-1 );
+// }
diff --git a/core/pim/todo/todotable.h b/core/pim/todo/todotable.h
new file mode 100644
index 0000000..4f3a064
--- a/dev/null
+++ b/core/pim/todo/todotable.h
@@ -0,0 +1,207 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef TODOTABLE_H
+#define TODOTABLE_H
+
+#include <qpe/categories.h>
+#include <qpe/stringutil.h>
+#include <qpe/task.h>
+
+#include <qtable.h>
+#include <qmap.h>
+#include <qguardedptr.h>
+
+class Node;
+class QComboBox;
+class QTimer;
+
+class CheckItem : public QTableItem
+{
+public:
+ CheckItem( QTable *t, const QString &sortkey );
+
+ void setChecked( bool b );
+ void toggle();
+ bool isChecked() const;
+ void setKey( const QString &key ) { sortKey = key; }
+ QString key() const;
+
+ void paint( QPainter *p, const QColorGroup &cg, const QRect &cr, bool selected );
+
+private:
+ bool checked;
+ QString sortKey;
+};
+
+class ComboItem : public QTableItem
+{
+public:
+ ComboItem( QTable *t, EditType et );
+ QWidget *createEditor() const;
+ void setContentFromEditor( QWidget *w );
+ void setText( const QString &s );
+ int alignment() const { return Qt::AlignCenter; }
+
+ QString text() const;
+
+private:
+ QGuardedPtr<QComboBox> cb;
+
+};
+
+class TodoTextItem : public QTableItem
+{
+public:
+ TodoTextItem( QTable *t, const QString & str )
+ :QTableItem( t, QTableItem::Never, str ) {}
+
+ QString key () const { return Qtopia::buildSortKey( text() ); }
+};
+
+
+
+enum journal_action { ACTION_ADD, ACTION_REMOVE, ACTION_REPLACE };
+
+class TodoTable : public QTable
+{
+ Q_OBJECT
+
+public:
+ TodoTable( QWidget *parent = 0, const char * name = 0 );
+ void addEntry( const Task &todo );
+ void clearFindRow() { currFindRow = -2; }
+
+ Task currentEntry() const;
+ void replaceCurrentEntry( const Task &todo, bool fromTableItem = false );
+
+ QStringList categories();
+
+ void setShowCompleted( bool sc ) { showComp = sc; updateVisible(); }
+ bool showCompleted() const { return showComp; }
+
+ void setShowCategory( const QString &c ) { showCat = c; updateVisible(); }
+ const QString &showCategory() const { return showCat; }
+ int showCategoryId() const;
+
+ bool save( const QString &fn );
+ void load( const QString &fn );
+ void clear();
+ void removeCurrentEntry();
+
+ void setPaintingEnabled( bool e );
+
+ virtual void sortColumn( int col, bool ascending, bool /*wholeRows*/ );
+
+// int rowHeight( int ) const;
+// int rowPos( int row ) const;
+// virtual int rowAt( int pos ) const;
+
+signals:
+ void signalEdit();
+ void signalDoneChanged( bool b );
+ void signalPriorityChanged( int i );
+ void signalShowMenu( const QPoint & );
+ void signalNotFound();
+ void signalWrapAround();
+
+protected:
+ void keyPressEvent( QKeyEvent *e );
+
+private:
+ void updateVisible();
+ void viewportPaintEvent( QPaintEvent * );
+ void internalAddEntries( QList<Task> &list);
+ inline void insertIntoTable( Task *todo, int row );
+ void updateJournal( const Task &todo, journal_action action, int row = -1);
+ void mergeJournal();
+ void journalFreeReplaceEntry( const Task &todo, int row );
+ void journalFreeRemoveEntry( int row );
+ inline void realignTable( int row );
+ void loadFile( const QString &strFile, bool fromJournal = false );
+
+private slots:
+ void slotClicked( int row, int col, int button, const QPoint &pos );
+ void slotPressed( int row, int col, int button, const QPoint &pos );
+ void slotCheckPriority(int row, int col );
+ void slotCurrentChanged(int row, int col );
+ void slotDoFind( const QString &findString, bool caseSensetive,
+ bool backwards, int category );
+ void slotShowMenu();
+ void rowHeightChanged( int row );
+
+private:
+ friend class TodoWindow;
+
+ QMap<CheckItem*, Task *> todoList;
+ QStringList categoryList;
+ bool showComp;
+ QString showCat;
+ QTimer *menuTimer;
+ bool enablePainting;
+ Categories mCat;
+ int currFindRow;
+};
+
+
+inline void TodoTable::insertIntoTable( Task *todo, int row )
+{
+ QString sortKey = (char) ((todo->isCompleted() ? 'a' : 'A')
+ + todo->priority() )
+ + Qtopia::buildSortKey( todo->description() );
+ CheckItem *chk = new CheckItem( this, sortKey );
+ chk->setChecked( todo->isCompleted() );
+ ComboItem *cmb = new ComboItem( this, QTableItem::WhenCurrent );
+ cmb->setText( QString::number( todo->priority() ) );
+ QTableItem *ti = new TodoTextItem( this, todo->description().left(40).simplifyWhiteSpace() );
+ ti->setReplaceable( false );
+
+ setItem( row, 0, chk );
+ setItem( row, 1, cmb );
+ setItem( row, 2, ti );
+
+ todoList.insert( chk, todo );
+}
+
+inline void TodoTable::realignTable( int row )
+{
+ QTableItem *ti1,
+ *ti2,
+ *ti3;
+ int totalRows = numRows();
+ for ( int curr = row; curr < totalRows - 1; curr++ ) {
+ // this is bad, we must take the item out and then
+ // set it. In the end, it behaves no worse (time wise)
+ // then the old way of saving the entries to file, clearing
+ // the table re-reading in the file and resetting the table
+ ti1 = item( curr + 1, 0 );
+ ti2 = item( curr + 1, 1 );
+ ti3 = item( curr + 1, 2 );
+ takeItem( ti1 );
+ takeItem( ti2 );
+ takeItem( ti3 );
+ setItem( curr, 0, ti1 );
+ setItem( curr, 1, ti2 );
+ setItem( curr, 2, ti3 );
+ }
+ setNumRows( totalRows - 1 );
+}
+
+#endif
diff --git a/core/settings/citytime/.cvsignore b/core/settings/citytime/.cvsignore
new file mode 100644
index 0000000..d316ac9
--- a/dev/null
+++ b/core/settings/citytime/.cvsignore
@@ -0,0 +1,5 @@
+moc_*
+*.moc
+Makefile
+citytimebase.cpp
+citytimebase.h
diff --git a/core/settings/citytime/Makefile.in b/core/settings/citytime/Makefile.in
new file mode 100644
index 0000000..b058021
--- a/dev/null
+++ b/core/settings/citytime/Makefile.in
@@ -0,0 +1,184 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = citytime
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = citytime.h \
+ zonemap.h \
+ sun.h \
+ stylusnormalizer.h
+SOURCES = citytime.cpp \
+ zonemap.cpp \
+ main.cpp \
+ sun.c \
+ stylusnormalizer.cpp
+OBJECTS = citytime.o \
+ zonemap.o \
+ main.o \
+ sun.o \
+ stylusnormalizer.o \
+ citytimebase.o
+INTERFACES = citytimebase.ui
+UICDECLS = citytimebase.h
+UICIMPLS = citytimebase.cpp
+SRCMOC = moc_citytime.cpp \
+ moc_zonemap.cpp \
+ moc_stylusnormalizer.cpp \
+ moc_citytimebase.cpp
+OBJMOC = moc_citytime.o \
+ moc_zonemap.o \
+ moc_stylusnormalizer.o \
+ moc_citytimebase.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake citytime.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+citytime.o: citytime.cpp \
+ zonemap.h \
+ stylusnormalizer.h \
+ citytime.h \
+ citytimebase.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ $(QPEDIR)/include/qpe/config.h \
+ $(QPEDIR)/include/qpe/timestring.h \
+ $(QPEDIR)/include/qpe/tzselect.h \
+ $(QPEDIR)/include/qpe/qcopenvelope_qws.h
+
+zonemap.o: zonemap.cpp \
+ sun.h \
+ zonemap.h \
+ stylusnormalizer.h \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/timestring.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+main.o: main.cpp \
+ citytime.h \
+ citytimebase.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+sun.o: sun.c \
+ sun.h \
+ $(QPEDIR)/include/qpe/qmath.h
+
+stylusnormalizer.o: stylusnormalizer.cpp \
+ stylusnormalizer.h
+
+citytimebase.h: citytimebase.ui
+ $(UIC) citytimebase.ui -o $(INTERFACE_DECL_PATH)/citytimebase.h
+
+citytimebase.cpp: citytimebase.ui
+ $(UIC) citytimebase.ui -i citytimebase.h -o citytimebase.cpp
+
+citytimebase.o: citytimebase.cpp \
+ citytimebase.h \
+ citytimebase.ui
+
+moc_citytime.o: moc_citytime.cpp \
+ citytime.h \
+ citytimebase.h
+
+moc_zonemap.o: moc_zonemap.cpp \
+ zonemap.h \
+ stylusnormalizer.h
+
+moc_stylusnormalizer.o: moc_stylusnormalizer.cpp \
+ stylusnormalizer.h
+
+moc_citytimebase.o: moc_citytimebase.cpp \
+ citytimebase.h
+
+moc_citytime.cpp: citytime.h
+ $(MOC) citytime.h -o moc_citytime.cpp
+
+moc_zonemap.cpp: zonemap.h
+ $(MOC) zonemap.h -o moc_zonemap.cpp
+
+moc_stylusnormalizer.cpp: stylusnormalizer.h
+ $(MOC) stylusnormalizer.h -o moc_stylusnormalizer.cpp
+
+moc_citytimebase.cpp: citytimebase.h
+ $(MOC) citytimebase.h -o moc_citytimebase.cpp
+
+
diff --git a/core/settings/citytime/citytime.cpp b/core/settings/citytime/citytime.cpp
new file mode 100644
index 0000000..b2f9f14
--- a/dev/null
+++ b/core/settings/citytime/citytime.cpp
@@ -0,0 +1,272 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "zonemap.h"
+#include "citytime.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/config.h>
+#include <qpe/timestring.h>
+#include <qpe/tzselect.h>
+#if ( defined Q_WS_QWS || defined(_WS_QWS_) ) && !defined(QT_NO_COP)
+#include <qpe/qcopenvelope_qws.h>
+#endif
+
+
+#include <qdir.h>
+#include <qfile.h>
+#include <qlabel.h>
+#include <qmessagebox.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+#include <qtoolbutton.h>
+
+#include <stdlib.h>
+
+CityTime::CityTime( QWidget *parent, const char* name,
+ WFlags fl )
+ : CityTimeBase( parent, name, fl ),
+ strRealTz(0),
+ bAdded(false)
+{
+ Config config( "qpe" );
+ bWhichClock = config.readBoolEntry( "AMPM", TRUE );
+ frmMap->changeClock( bWhichClock );
+
+ char *pEnv;
+ pEnv = NULL;
+ pEnv = getenv("TZ");
+ if ( pEnv )
+ strRealTz = pEnv;
+ pEnv = NULL;
+ pEnv = getenv("HOME");
+ if ( pEnv )
+ strHome = pEnv;
+ // append the labels to their respective lists...
+ listCities.setAutoDelete( true );
+ listTimes.setAutoDelete( true );
+
+ listCities.append( cmdCity1 );
+ listCities.append( cmdCity2 );
+ listCities.append( cmdCity3 );
+
+ listTimes.append( lblCTime1 );
+ listTimes.append( lblCTime2 );
+ listTimes.append( lblCTime3 );
+
+
+ // kludgy way of getting the screen size so we don't have to depend
+ // on a resize event...
+ QWidget *d = QApplication::desktop();
+ if ( d->width() < d->height() ) {
+ // append for that 4 down look
+
+ listCities.append( cmdCity4 );
+ listCities.append( cmdCity5 );
+ listCities.append( cmdCity6 );
+ listTimes.append( lblCTime4 );
+ listTimes.append( lblCTime5 );
+ listTimes.append( lblCTime6 );
+ lblCTime7->hide();
+ lblCTime8->hide();
+ lblCTime9->hide();
+ cmdCity7->hide();
+ cmdCity8->hide();
+ cmdCity9->hide();
+ } else {
+ listCities.append( cmdCity7 );
+ listCities.append( cmdCity8 );
+ listCities.append( cmdCity9 );
+ listTimes.append( lblCTime7 );
+ listTimes.append( lblCTime8 );
+ listTimes.append( lblCTime9 );
+ lblCTime4->hide();
+ lblCTime5->hide();
+ lblCTime6->hide();
+ cmdCity4->hide();
+ cmdCity5->hide();
+ cmdCity6->hide();
+ }
+ bAdded = true;
+ readInTimes();
+ changed = FALSE;
+ QObject::connect( qApp, SIGNAL( clockChanged(bool) ),
+ this, SLOT( changeClock(bool) ) );
+ // now start the timer so we can update the time quickly every second
+ timerEvent( 0 );
+}
+
+CityTime::~CityTime()
+{
+ if ( changed ) {
+ Config cfg("CityTime");
+ cfg.setGroup("TimeZones");
+ QListIterator<QToolButton> itCity( listCities );
+ int i;
+ bool realTzWritten = FALSE;
+ for ( i = 0, itCity.toFirst(); i < CITIES; i++, ++itCity ) {
+ if ( !strCityTz[i].isNull() ) {
+ cfg.writeEntry("Zone"+QString::number(i), strCityTz[i]);
+ cfg.writeEntry("ZoneName"+QString::number(i), itCity.current()->text());
+ if ( strCityTz[i] == strRealTz )
+ realTzWritten = TRUE;
+ }
+ }
+ if ( realTzWritten ) {
+ cfg.removeEntry("Zone"+QString::number(CITIES));
+ cfg.removeEntry("ZoneName"+QString::number(CITIES));
+ } else {
+ cfg.writeEntry("Zone"+QString::number(CITIES), strRealTz);
+ if ( nameRealTz.isEmpty() ) {
+ int i = strRealTz.find( '/' );
+ nameRealTz = strRealTz.mid( i+1 );
+ }
+ cfg.writeEntry("ZoneName"+QString::number(CITIES), nameRealTz);
+ }
+ QCopEnvelope ( "QPE/System", "timeZoneListChange()" );
+
+ changed = FALSE;
+ }
+ // restore the timezone, just in case we messed with it and
+ // are destroyed at an inoppurtune moment
+ if ( !strRealTz.isNull() ) {
+ // this should be checked, but there is not much that can done at this
+ //point if it fails
+ setenv( "TZ", strRealTz, true );
+ }
+}
+
+void CityTime::timerEvent( QTimerEvent *e )
+{
+ if ( e )
+ killTimer( timerId );
+ // change the time again!!
+ showTime();
+ int ms = 1000 - QTime::currentTime().msec();
+ timerId = startTimer( ms );
+}
+
+void CityTime::mousePressEvent( QMouseEvent * )
+{
+ // DEBUG enable this to get a look at the zone information DEBUG
+// frmMap->showZones();
+}
+
+void CityTime::showTime( void )
+{
+ int i;
+ QListIterator<QLabel> itTime(listTimes);
+
+ // traverse the list...
+ for ( i = 0, itTime.toFirst(); i < CITIES; i++, ++itTime) {
+ if ( !strCityTz[i].isNull() ) {
+ if ( setenv( "TZ", strCityTz[i], true ) == 0 ) {
+ itTime.current()->setText( TimeString::shortTime(bWhichClock) );
+ } else {
+ QMessageBox::critical( this, tr( "Time Changing" ),
+ tr( "There was a problem setting timezone %1" )
+ .arg( QString::number( i + 1 ) ) );
+ }
+ }
+ }
+ // done playing around... put it all back
+ unsetenv( "TZ" );
+ if ( !strRealTz.isNull() ) {
+ if ( setenv( "TZ", strRealTz, true ) != 0 ) {
+ QMessageBox::critical( this, tr( "Restore Time Zone" ),
+ tr( "There was a problem setting your timezone."
+ "Your time may be wrong now..." ) );
+ }
+ }
+}
+
+void CityTime::beginNewTz()
+{
+ frmMap->setFocus();
+}
+
+void CityTime::slotNewTz( const QString & strNewCountry,
+ const QString & strNewCity )
+{
+ // determine what to do based on what putton is pressed...
+ QListIterator<QToolButton> itCity(listCities);
+ int i;
+ // go through the list and make adjustments based on which button is on
+ for ( i = 0, itCity.toFirst(); itCity.current(), i < CITIES; i++, ++itCity ) {
+ QToolButton *cmdTmp = itCity.current();
+ if ( cmdTmp->isOn() ) {
+ strCityTz[i] = strNewCountry + strNewCity;
+ QString s = strNewCity;
+ cmdTmp->setText( s.replace( QRegExp("_"), " " ) );
+ cmdTmp->toggle();
+ // we can actually break, since there is only one button
+ // that is ever pressed!
+ changed = TRUE;
+ break;
+ }
+ }
+ showTime();
+}
+
+void CityTime::readInTimes( void )
+{
+ Config cfg("CityTime");
+ cfg.setGroup("TimeZones");
+ QListIterator<QToolButton> itCity( listCities );
+ int i=0;
+ nameRealTz = QString::null;
+ QString zn;
+ for ( ; i < CITIES ; i++ ) {
+ zn = cfg.readEntry("Zone"+QString::number(i), QString::null);
+ if ( zn.isNull() )
+ break;
+ QString nm = cfg.readEntry("ZoneName"+QString::number(i));
+ strCityTz[i] = zn;
+ itCity.current()->setText(nm);
+ if ( zn == strRealTz )
+ nameRealTz = nm;
+ ++itCity;
+ }
+ if ( i == 0 ) {
+ // write in our own in a shameless self promotion and some humor
+ QStringList list = timezoneDefaults();
+ int i;
+ QStringList::Iterator it = list.begin();
+ for ( i = 0, itCity.toFirst(); i < CITIES && itCity.current();
+ i++, ++itCity ) {
+ strCityTz[i] = *it++;
+ itCity.current()->setText( *it++ );
+ }
+ }
+ if ( nameRealTz.isEmpty() ) {
+ //remember the current time zone even if we don't have room
+ //to show it.
+ zn = cfg.readEntry("Zone"+QString::number(CITIES), QString::null);
+ if ( zn == strRealTz )
+ nameRealTz = cfg.readEntry("ZoneName"+QString::number(CITIES));
+ i++;
+ }
+}
+
+void CityTime::changeClock( bool newClock )
+{
+ bWhichClock = newClock;
+ showTime();
+}
diff --git a/core/settings/citytime/citytime.h b/core/settings/citytime/citytime.h
new file mode 100644
index 0000000..5a2c4d8
--- a/dev/null
+++ b/core/settings/citytime/citytime.h
@@ -0,0 +1,66 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef TIMEWIDGETIMPL_H
+#define TIMEWIDGETIMPL_H
+
+#include <qlist.h>
+#include <qwidget.h>
+
+#include "citytimebase.h"
+
+const int CITIES = 6; // the number of cities...
+
+class ZoneMap;
+
+class CityTime : public CityTimeBase
+{
+ Q_OBJECT
+public:
+ CityTime(QWidget* parent = 0, const char *name = 0, WFlags fl = 0);
+ ~CityTime();
+
+public slots:
+ void beginNewTz();
+ void slotNewTz( const QString& strNewCountry, const QString& strNewCity );
+ void changeClock( bool newClock );
+
+protected:
+ void timerEvent( QTimerEvent* );
+ void mousePressEvent( QMouseEvent* event );
+
+private:
+ void showTime( void ); // get and show the time for various places...
+ void readInTimes( void ); // a method to get information from the config
+ QString strRealTz; // save the TZ var
+ QString nameRealTz; // and what it is called
+ QString strHome; // the home variable...
+ bool bAdded; // a flag to indicate things have been added...
+ bool bWhichClock;
+ int timerId;
+
+ // a spot to hold the time zone for each city
+ QString strCityTz[CITIES];
+ QList<QToolButton> listCities;
+ QList<QLabel> listTimes;
+ bool changed;
+};
+
+#endif
diff --git a/core/settings/citytime/citytime.pro b/core/settings/citytime/citytime.pro
new file mode 100644
index 0000000..d988b48
--- a/dev/null
+++ b/core/settings/citytime/citytime.pro
@@ -0,0 +1,13 @@
+# $Id$
+CONFIG += qt warn_on release
+TEMPLATE = app
+DESTDIR = $(QPEDIR)/bin
+INTERFACES = citytimebase.ui
+HEADERS = citytime.h zonemap.h sun.h stylusnormalizer.h
+SOURCES = citytime.cpp zonemap.cpp main.cpp sun.c stylusnormalizer.cpp
+TARGET = citytime
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += $(QPEDIR)/include
+LIBS += -lqpe
+
+TRANSLATIONS = ../i18n/de/citytime.ts
diff --git a/core/settings/citytime/citytimebase.ui b/core/settings/citytime/citytimebase.ui
new file mode 100644
index 0000000..4665097
--- a/dev/null
+++ b/core/settings/citytime/citytimebase.ui
@@ -0,0 +1,1199 @@
+<!DOCTYPE UI><UI>
+<class>CityTimeBase</class>
+<comment>*********************************************************************
+** Copyright (C) 2001 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+** $Id$
+**
+*********************************************************************</comment>
+<author>Trenton Schulz</author>
+<widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>CityTimeBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>289</width>
+ <height>359</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>City Time</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>3</number>
+ </property>
+ <widget>
+ <class>ZoneMap</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>frmMap</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>7</vsizetype>
+ </sizepolicy>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout2</cstring>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>4</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>3</number>
+ </property>
+ <widget row="0" column="2" >
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdCity7</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;location 4&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="2" column="3" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblCTime9</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <pointsize>10</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;CITY 6 TIME&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ <widget row="1" column="2" >
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdCity8</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;location 5&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdCity2</cstring>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;location 2&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="5" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblCTime6</cstring>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <pointsize>10</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;CITY 6 TIME&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ <widget row="5" column="0" >
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdCity6</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;location 6&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="3" column="0" >
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdCity4</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;location 4&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="4" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblCTime5</cstring>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <pointsize>10</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;CITY 5 TIME&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ <widget row="1" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblCTime2</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <pointsize>10</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;CITY 2 TIME&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblCTime1</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <pointsize>10</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;CITY 1 TIME&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdCity3</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;location 3&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="1" column="3" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblCTime8</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <pointsize>10</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;CITY 5 TIME&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdCity1</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;location 1&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="0" column="3" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblCTime7</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <pointsize>10</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;CITY 3 TIME&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ <widget row="3" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblCTime4</cstring>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <pointsize>10</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;CITY 4 TIME&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ <widget row="4" column="0" >
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdCity5</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;location 5&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>lblCTime3</cstring>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <pointsize>10</pointsize>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;CITY 3 TIME&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignVCenter|AlignRight</set>
+ </property>
+ <property>
+ <name>hAlign</name>
+ </property>
+ </widget>
+ <widget row="2" column="2" >
+ <class>QToolButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>cmdCity9</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>font</name>
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property stdset="1">
+ <name>focusPolicy</name>
+ <enum>TabFocus</enum>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;location 6&gt;</string>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ <property stdset="1">
+ <name>toggleButton</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+ <customwidget>
+ <class>ZoneMap</class>
+ <header location="local">zonemap.h</header>
+ <sizehint>
+ <width>200</width>
+ <height>400</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>7</hordata>
+ <verdata>7</verdata>
+ </sizepolicy>
+ <pixmap>image0</pixmap>
+ <signal>signalTz(const QString &amp;, const QString &amp;)</signal>
+ <slot access="public">slotIllum(bool)</slot>
+ <slot access="public">slotZoom(bool)</slot>
+ </customwidget>
+</customwidgets>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="197524">789cc4bdd772e34ab6ae7bbf9ea263e16ec5096c7973712e442f2fca5066c7be8025e8404f82da2f7f3273fcff20c45255cd9ea64f7760b23e024c9fc36526f4bffee75f6f0fb7fffa9ffff55ff345b0e845ff8ab260f6afff8997a3d1e67fff9ffff7fffed77f1fededfdebc05e07e707ff3af8efffe7bffe3b4aff15fdcbdb33ffdb3fb39c2ec887fb96e3087cb4bf67793c201f9c5b0e1ec1677bee7ed822cbf3c944d9a53f69930fdcfda8098ee4f7d991b27b3ede9025bd75872cf9373fc887529e27e1fd3d492f682bbbf4bc2a59ca138cc9529ec903f9c8d57fd8051fa17e4db2fcdeab91e5f7f1a7b22b4f780d46fbaca660d47790081fa0bc9f6764f9fde6068cfc0728cf01d2f39ec892ffec108cf4d7f8fde19eb45f9a3b36bd23fddbe8928f02777f4e3e76e363d604b33e9760f4e7ea992cf7177b64e98f690f8cfecb1764793e2f844dfd5c7af33159ee8ff03cebbb7e5576cf0f62b294675903a3feab1659f29f3c29bbe73f376469bfd695f021c6c700ed7188feaef7c128cf12e53f42ffad0330faabf96ed98eb63475edb10023bff12959fa231b9065fccd2ac21c0fe10559da773e25cbf3f13518e3d1e3efcf24fd8b5b30f20f5fc8727f3e5496fc9ec952fe7e57f810e5f944fdd83e9f8764493fe7f3ecaf09599eaf8ec892de2a07a3bffaa9f011e6e7ba0d46fbe7efca2ebd9a3c6f66c3e9a14b9f7c24e37b5a05637c0613b2dccfdec1189fe32159daa7be4796f6a8497f9af122ed9f57c018bffd108cfa0d911feb37dd234bfdfad764997f952559f29b838fd0fee34730e64f2f26a3fd5fc148bf3e5696fe43fb1c433e3402f0b1b46ffd982cf7ab48eff85ceea72e3d333ad1bec3028cf64c783f121e84e41357bfe041f810fd9be56469efe0932ceddb7c261fbbf4ba2bb2b44fbc00531eef9125bde246d9d5bf9290a5bd7bfb60c8d3f4912cbfcf3764298fd75076e5194dc9529ee0058cf65f307d8ca7f5a9b28cff0959d25f5f90a57cc5bb30e743109025bd694bd9a5d778214b79d2148cf1d9bb214bf93fd11f47d0df692c7c8cfc8673f0b1ccdf06ca777c8ef183f63f8ee57ed7c97f636ea03d920e18f5a92f850fa17fa615b28c8f469f7c1abaf6be071f49fb2443b28c87ca2df9c4716345167910cfc1d45763b2b4d7724096f4e76f6429afa7bf97fc965764296ff64a96fa2e593ef46fb343c6f8699225fdd654d9a5df3f163ec2fc5c4cc8f2fbe593b28c3f94ef08f65ad12523ff6bb2fcbef1a42cf9dd90a53eb31a18f2ba774686feb852167db422cb78acf695657cdf9225bf794696fa2f781ff269b8244b7a9348d9ddaf2664496f21f3e99ce375ec298bbc8cc892deb04686bd575576e9e523f031e4694a96df8f7df039e4d70559ee2f36e018f213e3e9e45ce475712e7cba0ff93d134e53e1aeebbfc3fd038c87e642f8d09820aeff7a60f457f3802ce33d3922cb78ec6560b47fccdf9fc9fc5adc81393f6365994f73b2e4e7cd94ddfdc93359f2ef2564c97fd817e678adf864c9ef739f8cf46a60c86faf4e467b5c9131ff3c30c65fda5076fd9f1d93213f06ca529e53b294273d5076f7eb73b2d4a7f108e6780dc892df22254b7e41ae2cf9b13e68ef0998e377345376e9ad33b2a47fd1274bfa953d6599cf9a1ef41bea67c6b3fbfdac4796f45a3764c8939c8cfe417b1f9fcbfd469b2ced93a3fec7b1a47f714686be8dc852de02e3f3641ff3e95d599eef8031ffe647cad21e0f60e89f5ea82cfaa94ac6fc7d5376bfaf3f81313febe7caeef7eb3a19f6d38bf0e9bedc1fd7c89087b7c2692adc75f2ffd0e803990ff501f9cccdb7f10959c653510163fe345265f7bcbf20cbfcf77365b93f23c31e92f960f403f469a6ecfaabda214b7ed95059d28bc8925ffd5159f4f10359f28b0a30f489774896fc2f5acaee7e5127e3f70918f3353a26cbf84a3fc992defc4359c6fb9c2cf52998df9994bfb55076e59f0664c827b60fe667d6274bfee303b2e4df3f54167b94e9a1ff9257b2a4df45ff72be365f9545de5d9165be6dfaca222f5ec8927f0fe5e1fc1d256449ef624096f2ccf6c0e7f2fca64186ffd2264bfea39ab2f4e70519f56f29bbfb338c17cefff11d19f6fc5059fcaf902cf9d76e94c51eec90e10f15cae24fe8f3529e96a687f120f3f99cf265305576f90f32b2e43fa82b4b7f60bc51fe2c7d65b117f97bd80353f4c709da735e5116fb84e9419e64ca529e19fad7c813493f06c3de6ebd9111af5a2b8b3cc4f3690a7b2d22c37eba5096fafb64296fd821cb78f5ddf83b52fded4f8439ff570559eed7d760d81f9b800cf9b15276bfafb7c9f2fb0519f3797c44167994be9191de81b2cce70bf2f991931f6764497f7d09c67cee75c9327e8a3b65773f9c9325bd6241867f5711e67c0d2e94c53ea99125fd68ac2cfed63359d20b1be063e98ff11919f6415559e6db3b19f6fa8c2ced5f63798e215fd17f9cdff3736597de8af9637e7fde288b7ec778e07ccde7ca321f3d32cadb5196f938254bfae395b2d8a34b61ced7a44f96fcb25365f77ce09125bfe158d9ddaf1d91211f6aca521ffe1ef2334dc892dfa2af2cf2e8810c7ffc4559ee0fc8925f88f63b813f508c945d7e454496fcaa17caa2efeec8925fb65096faf5c0901f0b65941ff99fa23d1b7764dc477a942721ef439ed53d32e4f3abb2f8bf28ff29ecab75830cfbee130c79d77a5516fbeb830cf98cf97c06f9d728c8682ff4ff19e4dde6168cf6ad67c2947f2b9f0cfff3932ce51b6dc8323f2ea4fd02da0fdd3e18fabc9b9345fea4cf64f8fb32bf8263d853e92b599e8ffbca4e5ec55db2c897fe800c797a0fc678eb0f95c57e3b204b7e8b4765977ed5274bfaa9fe5ed2ff9c81319e3653b2cc0faf45467d06ca2efda5fe5eeab7395476f7d72cffb9e41fb3bc9017930a59eab79a298bfdb221cb7caa9c2bcbfcd7fb90779a3ee2455764c86bf417e5c5c5882ce9e72d65d13f7db2a49f2f955dfa952332ec79948ff2242ec8f0bfb62cf3774e96fc070fca62efb13ce8df55872cf569be80212f862bb2e4d77d55167d744b96fc96e7caa20ff5bee4d7bf5276f59b37c0e8afe05559d23f25e3f7b7caeef7b9d80701e55174a1ecda6b724b863d365616fdb44f86bff948867fd3204bfe6106a67df44696fc860b32fcdd2332c6c7842ce94f1230fcc70ad3873c9f9c9225bdd93119f67b0886bcfb8cc9f2fce6832ccf17d7c26768af39e6f319e4f30afd734679ef7e7f7c40f9d198828fcf23371e7db2dccfc660daef2119f264a0ecfa2f699065be2f4e9445deec9131df47ca2eff5a420edcfd614e86fd47c6fc4eeec8884f0dc9927f559f477e3159d2abd684399fd73919f6e4922ce9559e9445be8dc958bfcbc098bf69932ce363b165e94ffe1ef3f7f34859f2bf2023ff4f32e2f57530e6737caa2cfaf78d0cf91129cbf89990a1bf9ec9925f7eaf2cf26c4396f66c0dc8909f7c1ef37fd65296f9f94e86bd7ba52cfe34f3877c182d955dfe337d5ecab7667ba07f9be764f4475ff814f27c3e5296fe3921233e9829cb7c5f91a53cd33765579ecd0359daa77946c6fa1fc623e547af4586bc3f5716793f204b79aa7a1ff36f4996f2788fcae26f8dc9982f183fb4b7364b65f15f5ec9529eda87b2e85f9607e3e7e25459fab34746fbec2b4b7bd4c9d23e39e637e5d9f89a8c78c6bdb2c4ff597e8c9751ac2ce3fb4098f65f744b467b42be511e7ebe29cbfa668d2ce5a956c8529efc058cf6fa44f9cf604fafe764c8f38ef039ca5393f632f64de0e45b3d25433fdf8363699f2823cb785ee8fde8d8f11319f25bca63ec0bf89ff7ca2ebfe69a2cf2343e2363bded018cf157dc92a53fd71365917715b2ccbfd11559f2af8d94459ec764c9bf182bbbfb594a0e63371ffb64c427f7c1187f714886bdc1fa425e5d44cae2efcfc952beea89b2cb7f7c48c6fa47074cff735f59fc4fb60fe4d35cef4b79c6ac1fe453b05696fb6c4ff4efe7b5b22bcfe0890cf92ee353ed99784286fddd264b79962365975fff8e2ce5496e95ddfd6e932ce5493e955d79d26b32fae3088cf991f9ca323f981fe4d7aaa22cf6679d2ce51d9e2a4b79591f8eaf1b65b11f94a5bcf90319f27e09c67cdd4464c46753b2946f5a288bfed7df637dca53167dccfc31ded62d6577bfc7fad35ec17ca33c9b4ec9f0ff1f9525fec1f6c4f80ab62cfa86ed83f155cf95a57d1a64699f19cb83f19443bea8bfac0cfd744c96fe1d0764c47b06cae27fbd91a5bc83a5b22bcf28224b799ba8ff19e3057b64c85b5f59f4cb0119f6f5bbb2c4933664c9af1882195f6d91e11f27cad2dfb764d8479fcaa27faa60f4d76757f81cf37189fccf519f02f3f71cfaa1e1daeb44edcd2e98f6e5a2410e45debf2b3b79d8d4fb22ffe77a1ff27f0386bc5d4ec990f7e7caeefea24a96fc92bab2cb2f5c9325bfe69db2bbefcfc918df2330edfd0765d1ff4db28cc75eaaeccab362f961efa7beb2bbef6bfa689f58d99567119151de7d65773fbe27c39f617a984f9f4f64297ff74c59e2032159ca3f59288bbfc4f689a5fcd3a6b2e8fb822ce5f79f9545dfb1bd313ee24361cafbfa0319f18c2a19f19696b2f85f4f64e89f4259ea9392a53e5e57d995b7abbf97fa7c2e94dd7d2f21c3be45ff51be476b32ca575516f9f84a96f279c7ca222ff479f817a9b2cb3fbf234bf95667caee7e634c96f6f65664ec8f63f930ffb31e19fe4740863dbb5176e50b876429ffa0adecee5fccc9d0efbeb22b5fa2e9617ebe91111f3c01435f041d32f4c54059fc17f61ff4457aa5ecca93bd90a5bcfd4cd9dd1f3c92115fbc57167b44d3837db4274cfd30ed92a57c9b2b65f11feec8586f4d94653c7e92a1ef7d6569cf942ce51b5c2bcb789890614fe760fa5727ca629f0fc8f0f72265f1173a64e8ff6b65d1bf0b32e2bbb7caee7eed812ce56d7864d827187fd43f459f8cf5ea6b65f13f0332e27b4365591fbb20c3bf7a22a3bfa03fce389e6232f469ae2cfaac49867ff9ac2cfe25db13e3677a4f46fb63fe9d233e57bf5116fb4b19ebc785b2dc0fc9d0b71565b137347dac5723ff73ee4f6992e14f8e94459e7e92b11f0aed7f8ef8dc6c4ac6fafe868c78df5259ec872119e31ff2ec1ceddd833c08b85e74a5eceeb7d0bee101f6fbc87c54ff6e5113a63db0e890e10fd6c1d0dff1982cf7fd776577bfd620c7723f234b7e5e0f0c79b578258bbcaa2e94453f4fc9d06f89b2d80b2959cae3dd2acbfd980c7fb405863caa9d28bbfca29c2ce5f1c7ca529e908cf204ca2ebf19eb0f7fba3e5596f27864acf748ffa8ffe46564ac1ff7945dfed543b2946f73a12cfee63119e57b50167baf4a46ff0dc9529ecd040c79345c9361bf7c288b7c8dc9b05f96caa28f4ec852de40ef4b79bb7a1ffa342263bfff080cf914337fe8c7d99bb294e7920cfb63a9ecf26bb17e186f599d2cf9a70519fdc3f683fc5a35c9588fd9b2c42f72b2946fd85396f5b657b2942f7c5276e59b6dc852bee64c59eca30519f6bed8dfea1fcd2e9545ffde93e14f46cae26f1e92a19f17ca2ebf8b0a59ca53cb9525bed225a3bf8ec0908fd1a1b2c8bb3732f6ef1c288b3f3423233eeb298b3ed0fbd0e70365f1cf347da9cf455d59e2452c2fc6e3469f97f95163fbd19e9b83e9df2764ac575d90a5bc514b59eccd2119f37bad2ce395fd87f1ba0a945d79e737649407e353f52dfb13e3336a90113f4a95c53ede90a53c134f59f4ef0719f379cbae3c9fec2fea0f945ff5e9a9b2ec476b91a53ce38eb28ccf828cf97ca32cf6c73559ca9355c8680ff417f5ef608f8cf5d40365b1770ec9d81f74a22cf615cb8bf17571ac2cf18f902cf9afd0bed4e7d11d19fb95efc9386f72a82cf1a39c2ce5b9785196f6d907237ebd7e57167b93ed037b6b33579678d83319e977c9904f6db2d46782f60c604f557232f253c6fa41a12cf61dc67710c03e86fe0b12c4cbf07c7880fdbc536591aff764ec97417b8427d80fff41c67905e8b33080bd83f998a6287f4c867de6c6ffe9e1c939ec932e19f6491f0cf9bb08c9d0a797caa2cf0764d84bcf64a4df23c35e06535f0f876449af1f90613fe87d496f9190b17f6209867cebc664493fb9244bf9c38db2d87b6f64c92fce94a57e1764d807cc1fe3b3fa4286ff14288bbc5d93a53dbb756589ff3e91a17f3d6597fff2992ce54b6764ec4f5980195f7953167f7a4c96f275dbca22cf5a64295f63a62ce55b91a57c9f7bcaae7c05cb87fecf3a64d89b5361eadfc140d9956ff242c6faf1908c78cf4859e26f0bb29467d55676e519b6c8b05fd0fed4a7d14a59ec910a19f6c93b59cab33c5596f1744396f2f59764ec1fac8121efd6a9b2c4ef1b64d8733332f4e389b2c4cfcec9d08fb1b22bcf94e5c3f81a4f95a5ff8ec8d8dfcefb5c0f7e24637f7ca82ceb056332faef4c59e21f4f6429df66a62cf67a44863d3750967852872ce59ba17ef4579b2b32ca1b92117fd1e7a57cabb5b2bbdfa893d19ffbca127fd1f4a57cad3bb28ca7cd1319faf6100c7d9ab6c988cfaf95453eb4c8d03737ca626f7864d89f97ca62affb64c4e34ec9523eaf20437fb13e187f514d59f407eb8ff1377a5616fbe89e8cfd1d81b2c48b347dc49bc9184f3dd61fe36978a22ce399e9613c5d1c294b7c654cc678bf264bfdd790bfd4c7618f8c784b5759f4ed862ce5697acae2dfbd93610f1e80113fc823b2e8dbf05e59e26f2959f2af79ca627f3c90913fe445007d1db23eb017ea1d65b127987e80fd627c1ef6c46245c6f9bdb5b2d8eb4f649407cc78c8649f8cdf1f2bcb7ada1159f2af8f94253e73053e91f84bf4a82ce59b91b15fada52cfdf349463c13fd4f7b66caf2a27d366b6591a7e88f10edf13927e3f92365292fca43fb68b626a3fe736529ff1119e759dfc9d89f25fa23a43d525d81313fbb1118fa7cea93e3c4c98f7732d6a32760c8c7e48a2cfaae3b5276e97d5e92612f1d2abbfbf92d59d21fa1bcf46f932659e657724d96fcf20b6597dee88d2cf9452764e8bf1c0cf9d57f2763fde94559e46f9f2cf9d526ca22dfeec892fee0030c79145f91213ff53eecaf4f32e21d7a5ff2afec9325ffca48d9e53f1892a5be3dd61ffdf5790c867c4b2fc9224f6a2fcaa24ff7c858ffdf90b15e31509678c7940cff3c224b793ed97ee8df3eea437f336f90a53cd1a5b2ec975892a5fd46afca92ff2959ca57a9298bfed6f4a4fd96b7cad27ee764d8631918f2721393b1be169011df4895c55e9c93b1feaee94979d75532ecc7576529ef1119e57d274bf95a981fd4876bd617fab03f5196fd1d2f64294fe54e59daef8c8c78cbb3b294674496f6aa0ec9d84fd003733fdfa7b2aca7b0bda06f972b65991f6c0feee7f395459f2fc88817bd2bcbfce4f8c1785ced91e17f883c0da98fb31332ec812619eb67a7caa2ef5764f82f1d6569df828cfd455565579e4d9d0cffe58a0c79fa00c6781b3595257ed423633dea52d9e51f307d8cc7eabbb2b41febcf785b9b8cf982f6a57e5f1c92717e305796f274c9d89fb2a72cf613db23c07eff9ab2ec77c07ca63dd08a94c59e66fd12e8f389b2c4abf43eec43d63fc17ed567658917a1feb4278a1519f652a42cf65448c679af4765193ff764d88f7a1ff14f8c2fda13cb5059c6db822ce90f67caa2cfafc992fe04ed4bfb6271a92cf649858cf35dac1ffa6780fe547b03f23742fd2ece95a57d30de687f4c4664d84797ca62afdd91b1bfb950167b668f8cf5cb6332cedb7e2a4bfbb9fe3e53ffba9b91451ed6bb6489b75c3c91b11f810cfd3cf5c8a28fba21599eaff03ee45da28c78cc4cd9a5179d9325bdea3559ca130764c4936a60c8abfa1919f6c64859fc65a60f7baaea298b7edd274bfe69870c799708533ff61fc9b02fce95451f55c888575495653dea842cf6daf2958cfddea81ff561ff4959e2c3fb64913fd3908cfaeb7dc44fcec8883765ca2eff16eb87fe5cadc838bf3805433f161f64ec7f7c54167b88e5817eecce945d7946ef64c8cb0b65590f5a90a5bc9b336529ef2559cadbd4fca43d9b5db28c9f44d387bd8ef940fd387f5496fd552d32eccb95b2e8f70d19e729f69565ff04db8bf6fb5ad995af32264bf9f32119fb95303ea84fa31919ef0b682bcbfee63a19fb93de95c59eb923e33cdab1b2b4f72d19feb6de97fa046f64c41bd01fd4a70b8f2ce5aba4ca128fec93a57cbda1b2c41f3ec958efa892d1be15b2e43fc6f8537dd9571679774d86fe3a5616ff7f8f8cf8edadb2c45f3232e2e1e84feacf755f59e4fb920cfd79ab2cf67641c67993a6b2c48bd89f09f6678d9565bf00ca437db9689161ff7595c55ef8244b7ed32b6577bf35244b7ef51e18fa74fe42c67ac4a3b2c4173664bc2fe34c59e60fd33f813e823ca53e0d4ec8d0a735b23cbf84bc0fd19e4bd4274279466d32f6933d83a18f43c803f5e7bb64f847556589c7f5c9189f0fca325e3ec838cf2eed13aafebb2763ff68050c7934fd24239eb80786bc985c9325bd7a5559f4d3922cf26c7d424e4edcfc1f91b19e83f4e9df855332fc8f2519eb0d2f64c97f38529678c30759e217b52a3911be22a7ae3cb34459e4ed06ccf59a1a19f6c85859f67ff2f7d057515f59f6e3a464e8eb9eb2bb9f9c92a5bd86976429af7744c67ac51c0c7d54c4ca529e0e59cad31c298bbfabf7a53cb5736559dff2c8529e4a43d995a7d1244bf93e5764ec7760ff41fff4d85fd03fb3bab2d85b8764296f7fa62cfa4759cadb8a95ddfdc60159ca9b56c8d84f89fea0fe594564c4132664eccfc9c8b0bf1e94255e35234b79066fcad27e4db29467d35176ed35d1f2c05e5980a18fb203658937b4c988d7acc8d2bec323b2947f744d46f93f95653d8ce5c378ac687e684fd617e3b1b1afecca3ff4c868df4730f455fd990cfdd4204bff8fee9425fea58cf973ad2cf3794896fc830118faa9c6e7a18f2a5b96f4efc9583fa92b4b7f633c515ff54664e8837b65f127dfc9d87f7345c67ee99c2ce51fa3bda97ffa1764e88f076549ff8c8cfa1c2bbbfc8a13b2e47781fe08e97fd7c958afd823e37c18fa23843d50f92043ffb7c9586f785396f39fac2fdabb1991218fd03ff427375d32f66ff860e8c7f10519fb1f301e23d46701a67f99e764ec9f8994657f6e8f0cfb527f2fe5dfbc90e1ffb9fadad747897ebaa881795e600286fe5a56c988272f858d7e71f7c385b21baf714e167d130d94455e3e80313f9367b2ccbfd92759d2f7af945dfad1902ce98785b2e8d77d30f48577a02ce397cf435f5c74c8220faafa7b294f375176f9872bb2942f592abbfb498d2ce5f38f94c55f6d81a10f821959e45372ae2ce725a664294f76a3ecf21bb0fdd05f4955d9dd9f4fc8529ede4059e2f73d61ea832c214bfb142959cad77f5376e5ebf964f873156597ff6c4ec6783a5276f72ff4f752beee9db2ecef60fe5cffdf23a37c3365d1f7af6429efa8a52cfa2a274b790797caae3c59832ce54d0332e22dac3fe47d764646fbed93b13f235216f9c8fc02295f3653167d744a867de42bbbf2f51ec952bec689b2bb5f1c93e1af9221efc22a59e4c5e79a8cf3496c3fe88b569f2cf5199e2bbbf2663532ec83a6b2bbbfee9211bfca955d79bbecdf04fb0d503eeaa3bcae2cfb0b6ec9d0b73d32e21567ca32dfa76429ffbcab2cfaf6950cfbfa4259ee9f90a5fca33119eb3bbc0ffd56657ed05fe32bb2946ffeaa2cf12a65d80337ca321ef43eda93f99f487922b617e3cf0365b1ff6a64c44bd6ca120f3b224b79aafa7b29cf7aa12cf1408c67fa7f8d0f65d177ec2ffad37d32fcd92b65592fb826c35e867e88d0ffcb0b65d9bf7a4c863e0e94e5fcf7848cfdfb4d65d9bfba0143ff6e86ca52fe3e19f1a71365b10794e1bf613c517f176b32eca95c59e23d900f11ec91568b8cf7e7bc9271de15fd17239e30817c8ae1ef579fc8386f84f68d196f91f112a9bf7a284c7d9d7f9245fe0e07caa24f8760c8cfe61159e4cfea5c59e453950cfdf7aa2ce97960e8d35a850c7dbfafeceefb7532d26b2b8b3db107e67eb71659e647fd5559ec934732f2d3e791df0d19f93595c51f15f91251ff250b32e2e16d65b1074664e477af2cf9adc9c8afaa2cf6d82518fa2cbb5696fc5764e88b86b2ec67f8204bfede5859fced9c8cfc5f94a5be2c2fe441ab20c3bfdf5396fd012c1ff5d781b2e437214b79bac7cae22f866494e74c59fcaf0e18fa69c5e7a99f9acab2dfe3882ce55d2e95657fe22159cabbbc5316ffef930c7bf952d9ddefb3bd1394f75459f623a03d19cf9b1f90b1ffae5096f8cb928cf589b9b2c4d7db64a9cf7aa52cfae2980c7fd65796f8c5882cf5691e2a4b7d1ec8187fbc0ff9b7627d20ffaa4b6589570764c8df2b65a91feb037d37b95776e59fe8efa57e17b1b2d4ef8d8cf17546c67e06f417f561dc5216ff8aed017db80894c5dfd4fb58bfbe5696fdb95532e6c35c59ec2165297fe3990cf983f94efd387e25e3fd0e97ca521e8f0c7f3b5416fb82e5c1f8dfe8efb13f08fd4dfd39fd204b7e6bbd2ff9550ec9f08fb62cfb2f3330f4e3e8932ce98dbbcad25e6332e25f3d30faa772af2cf1ef1919e59982d15e2d9697f18f7765d1efe2bf44d497f30e19f93d90719e0df9c7d0ffb3828cf533cc57ead3cf5b32ec2df44f0c7ba82ff64594c0ffbf70e32b50fff4e2044c7df6a62cf1b15330f493e72b8bbed823e3f73565895fdf0a53ff783764e89f4f65496f49467a1565594fe2efa16f8a07b2a4ef9f9391fe9db2dcdf9091feb5b2e8ef7730e64b75ae2cf91d90a15f5f94653eb13cd427fa3ce2114f64e47fa22cfe78138cf935e07de8871edb03fa21592b8b7ecfc9927ffcac2cfa83f5877e882f9445be5e09539e77f7c9925f912b8b7f3a254b7e595359e2012f64c96fd55596f58f1618f3b15e21633df45059fc697d1ef1990b65a97f4196f2543f94ddfdd12519e313fd45f91ab33e90a7d51e59dabfb2224bfed51919faf851d9e5573d2643ffb6c19097d32159f21bb1bdd0df9b7332ec1fcc4fcacb6843c6f9c36365592fcac09087ab4459d677f6c858ef3927239e3157167d1781210fe757648cd791b2f83ffc3de395a9b2946f46863fda5416ffaf4b867d119271be0cfd4f793a8cc890ff6b65896fed93b1ffef4559f417e415e56db1a72cfbbd1232ec8db1b2e8871b32fcc71365a90fcb03791d85cab2bebd24637de4942ce94d30be13d477b352167fb44146ff4ec028ef27da37c17aea6ca22cebcb4764fcfd12942f813ed9ec29cb7ac30919ed75a92cfa1ded9142ffb4d6643c8ff19b32febca72ce5b923e3f94259ce6f407fa4287f6b45c6f9815730e2d3d35b32fe3e83c817f5dfa63918faacdb50167921e5d9fa471fcae24f8ec0d4378f64c8bb180cf9d0ef9125bd60a12cef733806437ecf07643c3f5596f8a9e82fb5cfe70bb2c8a77ca02cf9f7c9a8cfb1b2c4e7f93ce4e9f2902ccfd72f95a5bc4f60e8c3594a46fdc53e30f61bf69b77c0f87de3168cf13ead29cb7a92de17f93446fb45186fc52119fb839ec9d80f22f233e2fcaf5c2a4bfcae4b86bf93298b3c7e24633d3400637e5d3494259ef64cc6fadb81b2c88353b2e4377b5596785f878cf833c61fe5c3f05659e41bcb8bf69b1f2b8b7cab90e19fde8369ff6f59e2435332d6afdaca12aff3c8927e21f222a27c5a3f2a4bff74c888ffc5caa22f3232fa674dc67903fe9ef1af2e19fec3b5b2accfeaf3925edd5796f640ff50de8581b2f89798cf946f832365799f418b8cfebf27233fa497c2fe8fde9465bd6f4ec6fee64f65592f3b25e3bc39fa93f232ae2bcb7af53e19fe42aa2cf24f19fa6002863e481265492f2323bdaeb2f8276764b4ff81b2c443d0ffdc8fba6279b17ed88f9465fffe1119f1f65365293feb9f227e112bbbfc7c977fa8fec7c5b5b0c68f8ec19047bd3e18f2a1910b53fead6ec0987fb5028cdf77ab60fcfe2211a67c4b6660cce7cd3b19fb39eb60ccc78b1b65896fbe91112f1d9345beae9fc992df300463fc5d0cc9f8fda330e5df305596fd9fd764f8efafcaeef7171f64496fd40363be4ddfc9b09f6332f6bb64ca120f5b90b15fea098cf1b4ba5316fb6a42463ce45059ca7f4f463cc45316ff8df5817fd75a92a11fd0ff31daafd75616f97441c67ee837658917a17d29efd60519e75146ca223fd7649cffa82acbf98a3b32d68b4ec1b43f1f9545df54c8d0370fcad23f3119f27f0ac67caebc9125fde05459ecfd1e19fbb1ae9445ff34c8d21e6bf40fe567f55e59dedf9092b1bff25859eaf342c6786e2a8b7c3922a3bf1f94e57d43283fe5eff45259f6675c91b1df62a32cf6784086fc8d95257eb447c6f95b4d1ff1b90b32c6cb2d18f27b5e5396fdb9af64f8077bcab25eba4f46ff687a58df6b90b1df06f389f27d5c5796fc5ec8d07fe7cae2efb07de88fec2b8b7d3526435f431e51de4f2664e4c7f240be47efca72ff838cf63e5496f1c7f2a788e70ac711e39b4365d9ff7749867d2af339a63c5bde80299f0fc890574d65777ff506467d9b9f60c63f5b64e9efc65a59e2070119fbb9a5ff63ceefd6b5b27bbefe4e86be40f939df7b8764bc6fa0a62ce393bfc77c0f3e9465bd81f9a13f93900cfd9028cb7e822519f18a3365d99f7744c6fa06f3c37c1fbf90b15e992abbf4c30732ecff3b65912fc764d88387ca32dffb64c97f8efae8fc1e2acb78f3c888173c28cbfac0868cfd3b6fcab2bfbf43c6fb5c3f94c5fffa24a33d301e39bf477bca32bf591eaee71e298b3dfb4ac679923b65699f2619fb4fd17f9cefeb3332ecd985b2ccf76b32f23f5096fe6179e99f1d2a8b7ed1fcb05e3f5096f9c3e7290f9ec990070fcad21ea76494c75716fd5090616f1f29cbfc70f2263ae6fccef6c8886f2fc15c9fb8204b7ff5de95c51eab90b1df2116e6fc9df494a5ff03b2a4378d94451e0cc9581f6e80d19fa33e19fee84259ca7b4e96f427beb2ccef2b32f68f7964f1e7d72c2fd79bf6c9381f74a62cf6c82919efa3fb501679552763fee5ca623f56c9a8ef1d18f3bffa4c863ceb284b7b303fceff1b65b127597ff45ff75659da9bf9a3ff5a1b61cefff999b29ccfb926a33dce95ddfdf49e0c7998294b7d4332f4c99665fdf4968cf5842618f33d7c27431e1f2bcb7c4fc992ffa0a22cfdff46c67ac6a5b29c37780463fe8f3fc9b02fce9565be55c9781f40a42cf2e9858cf6385196f1caf6c2f898b0be900715961ff2205b298bbce89011fff695a53d6ec8789fe299b2ecbfda27e37ca1e417737ef79ec988ef4b7faafebdb820cbfd6943d9f963cd4730da7bd95096fd767b64aca754c9f03f6fc068cfde0719f1a1aeb2f81be764f4e71919fb078ec1982fab0765b1cf9b64d82327ca22ef7c32e6abf4b7eabfa84296f47b47ca22ff9ec8d82ff2a02cfaba4d46fbf5c890cf0760cc87fc9c0cfbfa912cf94febcad29f5764ecbf5c2b4bf9fa64ac27697ef0f7311e38ded7e7ca220f7332ea5f5796f68bc992ff67a62cf547fb6a7c6345c6f9b6b5b2ccbf4f32fcd389b2d82b1764f4f74059fcff1a59ca131c294bbcd1b57f6cf585f4c70d19f6f30318e36bbd1166ffc62b30fae3d32323fed026e37c46138cf6a89e91a15ff7c1a8efec4959d68f5ec9902f7a1fe7a39cbeb2e623f6433bf994a687fc7b9e9f60fc7dd3e61e187f8f74b60fc6df0f1c8f848ff0f7bfa32e19f1a04730d2db8460a417d6c1fcfba4488f7f0f6c81f2f17d7bfe1318f12cff5698ef93497c30d7af4fc17c5f5f00e679af8130cf6b072b30cfef1e81f1fb10e5e37efb654f98efdb0a2764a43707f3fd8f4b30de2fe577c8c88fcfe37d157e838cfaa27c5c5f096330deb73454c6fb8f3c6549af20a33f5ac2f407ab684fae0f143561c6bfd2088cf1df457d192faaa0fc317e1fdf0827905f33b427fdb5f1828cf5894732f46548c678dc80217f669eb2c4bbe664e8ff0b32e2917760f85ba34765c97f4896f4c3b6b2f837ef64a43f23a3fe180ff4afe6cfca12ef0fc888f79f298b3dd725239e74a32ce5fb20c3de7c21633f08fa93fed3e4848cfd4b67ca223f4fc9a8ef87b2d4f7958cfa56c9e8ff6b30fca7f14c59fc15e647ffe95859f425db03fd19be294b7ca34d86be3f2763fc62bef3efd7171764fcfdda3365f73ef5b94796f76fad3f94e5fd59cc0fef97984c95e57d1b0519e77f626589e73f91b17ea0f7f17e943b32fc3bcd0fef676a90d15e27ca62ff1e92a1efc6caee7e5c234b7bb5176469aff6c2f7cc15fcc39f21ae089ff6fbd85c49e9b9f89bdfa5f87ef7332971b7f43d7f97949e0b713fc3bf7b7edf1f80839df492d2efbf2b97fdfdb0549fd1ceef83d2bddd72ecd637ff4d7b8d4b57f84dfdbd523ebf6affdd76297f4e7ed35f7f24fdf137ed1deee4bf5bff292ef79c3f73cfcd7ff1fc3f3d3eede7e2bbfc9d8e5cfa2b7f6dae7feeb370d7c6fcfbd3bf3057612eb95fc1fddde7d7ee372bbf8aefed674d9fdf5ef6fbbadf70df37bffc5eeed7c072bfe1b75c190affd27dd7f8925605d715d2bb362db4c13337e6f3c6a56feb51987f4b7d58cea596bfd06bb9736f7b15a61cf6f7b7fe1d9e633ae5fadb72dee3b35cc6efdae177fd50be6a680f9bcf9de98f1fdb7fa5e5bfff52aeef3e0bedcf8abfedcffb9dfefbd5657fffe09e6ffce4996d7b7efff9d7c66745fb93fdf1257fe891ca7fe86a62ced6c0b5d2bfffc8f5b367af77f2a8eedcaf969ebb0657f16c7327fd72d9da25661e6d5cfcee71a75cb5f61faf57f0933afebbd75fe913ef37f9fed17ef9ee77fcf76e7fec3ecb3e68fe0df5f92bd777fd51717a84f3ff9fba6aa57f37fda7bf31ed0232a0e1744913df55dd2532ac82cfaa2f7aa6897f3f9b675ebe2927afb6fbae81ef1b861bf8ae70f71ffd8eff6a3edfcc67ed17e97cdf1e52eea5b131a8e37ef6fb1af2fff1bb5fe7f1abab59fab72dc3aff3fe23fddbf8f2ecee6fd91f3faba7fd77fab78d893f333e7fd91fd0237f4676fdd9ebfd1f9493d4212fedadae28eb107e36db5f75c9ae6c2beb865a296d7bb54bdf7ffc442efe4e27f07ef69be7fe48fdff6c3f5066277f639a3f6b8bea6f2eb66dadbdd5ddffc9eb97fdf11fd32394174d3ffed3f2ef67d79e91637bf02f6efcd50f3a64cf5f397bd97eb69ddc6f38b9b5814ff1639a0dc89595bfef6ceb95b3af37ed057c11eb03d9fc3a4eb7ecca5dfa5fbb32767b15f88c55a6ffba3d98def6f3cfb4ffae6e123dd22b95f7df4bf7bbfeddcd8f3e5455afe287ebab1ef9b1bd7e97f7dfa147e492fed8c9ff3fa447ca7333fe66feeecaca5fc9e3b2cce17560ae433cfbf84dde1fa5ebed9b72354b97956b47f83c36d789b94ecd75d6deea277e5fd6477f468fa43fa9ff77bfffbb64fd6e9af1df90f6aecefe553b7ca747fea89cff27dae067fdf1558f70eefc539fb4e1a94776e76a59e6574abf235316d397a8224d2bdbcffdc2f3cde57981177a91177b89979acf2eaecc5c3dbfebf5bd813734cf8ddcf32b3f94dfbadfe7a56bdc5e78137fe54dbd9937f716ded25b796baff0367ec3fbf42ebc8a57f56a5edd6b784df3df9677e95d79c67af3c6b0b96d393f4d3a37285fb5549ff225df79dfd67fb71dfeeae7aff4c89ee98fea5f4c9ffaa11c8b2cc7debeaf7bd94f6c78b7ae8f79fd7a7cfcddedb4db1fdfeb91ff44ccc0cadc6bccd51afe6d3f1f71bf1c43aa959ea7bfc0989491dfde9db94c3adebdf7e099df798fde93f76c3e8d9cf73ae67a3597d1179ef17d3ca33bbc3d73ed9bcbe81bcfe81bcfe8096f692ea30f3c9b9ed1139ed113de797b11f8e6f2822008cd67642e23670363b30726bfa06b2e63b3063d73f5cd3530d730180579300e269089a68cc1d45c3329abd6f3bbeb3b195e29d5b91c437bdcf9aeec5ffdaeed77f32dfb54ec8f721ffd913477cb5bee2ffebb9cd775a9dcd7edaf7dfb3bbdb0fb1c7ffff8cdbd3f73edf6c7171de3f4c83fa943c4de6e409758fbddf3afcdbfad1ddfb69fc1dc7f7431a9225848ecc87c16fabb1b534a895d17c1325805eba00836c16770115402332203634706c637081ae6dfa6b5825670195c994f3b52cd6f83dbe02eb80f1e8276f0183c05cfc14bd0098c7f11bc066f819941819941819941c17e701098d91398d91398991398d11d9899139899139899139a99137ae60ac2308cc2384c82bbd08caeb01b6661cf2fc27e380887e128ccbdbb701c4ec2a9df0967de4338f77fee13548c0ca74d5c928da6fe2bdb53a1fdb4b2f9daef04263d7f6dbe3333db5fba36e9189f6865effd2159fa35dfad5e5ea20c4d97966977d31f6dedb7af9f3f4bbf8998a2ad832de3ca94ef0e7aaa5daabfa953b030e98b0e93b860536c8c70fd93b2d65cb9b6e5603bd577e28c7f872eb1fdf18ddefb0fe991b2dd9795e40bf548bbf4ec6be99e19e96161ae4df8195e984f3b72cccc086b613d34b3226c86adf032bc0aed7337e16d68f44b786fae0773b545ee8726fdf0297c0e5fc24e68d20e8d7e09cdec08cdec08cdec088d7e098d7e09cd0c09cd0c098f65768566968466968467f8343325f2f1bc2ff723336ba2c05c46e74446e744460e4549308ad2a81bd97abefc42265386574a6dc38bb19e13a461ca1419dd15f5457f064bd155d4597fa8fd77ffbdeb8f40fe078bf6575df22b7f0097fb4d490f79617bebbb510f3c4a5f6adf7e7cd3f7bf1a3be5f8e39fd1757fa48d921d76ff767ae477f6de5ffdac610d416455ec6228120f6a4403730f32221afa76dda1509961d7246c4bdc44a3288fc6d1249a46b3681e991e89cc288956d13a2afc4eb4893e2333832253a3c8f44a548bea51236a46ade832323a2532694466d447b7d15d646650f410b523db63e7e6f3c9f0737017991e8d3af61eeedb7f9b1915991915bd476d37433ee4d3ce98684f668ad359360f33732233d3a2c3e8283a8e4ea253532fab03ef4b7eca5759bed523cd925c371c4ca3b3e83cf6632f0e82c28be2303a8ea33836e98ee32498c7c6df8abb81e890aaae0bfdaafdbf5e5cfbb1f1b94f5706892d5de39ee885dfa7cb4fd797ed459cc5bdb86fca672cd078e83762bb4ba7093db8b0fd6cbecfdd772ba343cc1808276e969872c463f4fb777a64bb9e23b1cbb69653c6c85f1f9fdbfe28ef65f8cfea9157c80cfb196ce58dde6feec8a2d7d2bfabb8674671b0095bb1b1fb63233b6363efc77373997bb19931b1d1f0b1d1f471116fe24ff37921f22c36e9c46ee698cf9ae8023baaed088f8c3e71b3c4c8b2b86e3e5fe43ba7233ea03b0cc70dcc0c7c67d93dc719637f6f4740cb702e7575656eb77f6e2f7f67ffe25e6446577c692e53ced8b4536c665b7cdb16bd62afa31df9fdefe891529bbbcf698929a37f27dbbf4b9fbec6d894f54e2ea74b76d7aa76d7ab5e7f925e6de7df657d52f647fe2e7db2eb1f7ed523ffa40ed9ca50d109e7f17dfce017b19103b1d119f1139ebb31f2c78c56b73fcaca302bd3f6cdfd67fcfecafcdbb476dcf18ee3d7f82d7e8f3fe2bd783f3e880f633362e2e3f8c4ea97f834fef0baf1997f629e3f4ffcc4f35749e0744b3b31332689e40a5a32e2a3a7244e9292ee30233f31d64cd28585e59bef5f4497b819f581d9716ad8e89c24333ae8499e4d7a493f1924c3c4ca4f2b23696fffce1fd9b58fcd8c48f23848c6c9246c25d36416cc93b95f24a67ec912a3b12d723ebef8c3edbf2b9b1bceff58fa17c67790f59f3be7f7358c0fd4713e611b72fa77b1a50fd809f6593b3b6cbb188995185f2a29bc45b289df92cfe422290c9b5197548dff68fcabc4cd2cf12792fa2ff54849af99df583b847e2af7eafdf5f1f9ffb33fa232d5c890c4c8e0c4c882a4158c12c8416b532797edafeb0d8861254696fa47613d319cd8d1736b678af934bd9118cb29b13d62d24e8c4c49ec2ce3da85e5e7e425e924af817dde584d8919ddf6ff8919e9c9de5627b811de9519c04fce06ea0bab2bdc73fba27b924c2c33ea94e440625dc9617264edeee4785be76fe3f1657f64477e3abbddd6d7d42336333c3915bda87e0af5d31fb5cb7f96bf4dc3b6fd19fac0d43335fa35e51eae3f2aa3e95742c7d919929a72a7462aa54622a5463ea7499aa656f20ccdbfe9abedda13df95b5561a43e5d859f527bfffb33a64d73ffc1ad7fa2ece5cf9328fff48eceac7b9f94536fa45da4bfbe9201d867974928e924e9aa7e37412ac8caf318adbde209da6337f1cdfbb98c8951fa7f374911ab999ae8c9c794ed7c9495aa41b634135d3cff4c24be2abb49256fd4e5a4beb69236dc6af693f5ce9da77c7c5cb6c9438f6ee5263a3a597f12cbd4aafd39bf43635dfa7f7f0ba3f4a3ae2cbec303a82b3e4743b2becf7cec27a828e319f96d387b49d3e7a51928b6c8cec0efafa4f657943f5c8fa9bf6bf36f74facae35695066deb876e47356ee769c9efa5d7fec7ecf7d6be7d1287d4a9fd397b4939c4747e96bfa16e5a61f56e9bbff893c7fb65ee16258a64f4d5ba546daa4fbde223df0eae9a1b7f2ced3a3f4383d496d9b9c491bdbd8606aaeae99815dc3ddc05b191ba1e31f3bbdf5d51fd9d52715897bfafbddb01b794137f687c9953f4f9ffc6137f9859efef7d7f1e2efc6ef377aa46cf7bde1bbf29e9ab25dc939cd58f80f73b0bdb5534d6b7553c87ac35d2353ba59b7d735b2b73b08465d2b5fcc68ec8eb6b2b26b6cfbee586493935155db1be63be393748ddceb1a9fa46b7c92ae9131dd6577e59edbcdbfb4aee264d789c8b8aef15dba465e7737a223e8777c99254f72515794f54af7b3e4a79851d23572be5b11d9ff4b3f8097ade377eb23bb6bbff40fcaedcc7581ddb6a77d5f96b52fdb7434ae64f5b8ed0373bf6b7edb35be983b07c3be2eade9741b320ed4f7a96dd3ed9a74bac66aed1a1ba07b25eb523602af31c363699feeb544cebb66b6778d1de0594967fbefaebdd5b3d55299cb3e11cb603f8d54eb3e881dd16d771fa39352993e76ca5cfb26dddd314a3dcf768edb5ff7856ffd9135e6625bd631e2dcad5548bcc9edec40cca9a2f128c6401a883388bde82279760fae6d517cef4683bfea3e759fbbb6553bdd57efc41b74dfa293ae1d6de3ee47f72df1bb7b626f77f74dba77f8cd81b90ecd7766e4778fe3b3ee49f7b47b963c45c7c12a9e76cf333ff3b220bdcac2709245599c257ec3d8b90ddff48edb6765cb7a02996dcbdc7231161b07696476b6165937cb24f21b3d88cea067be9d25e2776c67c856e7d83518f7db7bd149592feb67836ce8cea8883c6afc726dba525a9bd8c66e28ebb76b0e4eca5839eaafb0d7b8e12ec48cd41778f465cde91ab134f96cb8357049af80cfe785b3d8cb46599e56b3b1f5f3cc771da77b4dbf1a5decf6a6651397a6cdcbf88666541b1d60d73f3233ba33239db279b6c896887e7c9422e4e576329f99b1bcb2b58d966445b6c93eb38bac92991198d56c1f58cbcc5f6566cc640d632f98f1923583b9675764efe16bbca1ff96a6dfcc8ccc2efd2233333233ed9fdda0af1f55df75dc5eec57b70e5394da53c681f3afcc3df39d95182ece76adb1d427d74edbbd64653d529643e5f317afa57b8feded5a2fe354bbeb1be57808f58779c6d5ccc88fcc8cfecc8e2633eab276f09499df664fd0d6b6759ecd657bcce89cac93bd2603f3f996bdc7a6b533d30bd99ee880ccf45866466776981d65465665469e64a68732fbbb73b187bfd8abe57a94d67d7ba6777b9eac8b385df1b0f53bbee88ea7af7ac47af77634f44c597a612fea19f993f57b49ef3bffe25736309fdf3d5fc1fb6599d6fe2ad7bfac3197754f796f32ebcb34b0c7acd78dbabd4cf602f47af25cafdfdeeaa0335c94d3d0e3bd81e8f19ed1f93da3777a6684f5c6a5f6faf851e7daef7a66c4f7a6bd59cfe8fc9e91843d33b37aa68f7a6b8939f68ab09e9a51df3333b367f473cfe8e4f4103e18751ad78b6c392a320e740fdd0bcad8de8e4bb76ec431588e2d725da63cde311ee231ee97dbf5edcb7e2dccb7de40e48fd384b6542d27676c9ca9e164999d9f1f7ea357d539d930f2ad83348a2f766fd5fd2eebd564fda257ef357acd5eab67b473ef4a767af4ae7b37bddbde5defbef7d0b33b4b4ccbf51ebd453c882b3d333a7bcff16def257eeb75e249efd5c892ebde5bcfb47eefa3b7d7dbef1df44c6bf68e7ac7bd93de69efac77def7b3671ba3ef5bcfb30af9f1a8b6b52d67a31f98729b1e493fc2513f8cda6ea7c9b5917daf5bffe38b2e29f57a3f4a622b1bed6a623fee27fdb4dfed67e1c8cae37e0feb0ef4397e661f97d74776fd9536e467a5a40faeb1cfb8069dcd337856de5d8713e955e8f526f63534b9d66d65b25da337f5eef7077d33c2fb2323b3ed9af7c69f3b7f67cfc95fd746fd3cadf4c7feaa3fe94ffb6616f5cdc8f6ae4d3b2dfacbfe2a98f7d7a237dd4aeb81c40177a31c655dd237f2babf81d5f5299f56baf43f6535d7b67ddfcc06ab93fa668cf4cdace99bf1d2af9b7218dd62758af57bec67dfd4b3dfea67d98b29df65ffaa7fddbfe9dff6effaf7d151d6747be41a3646978cfc8ed531f1f3ce9eb93db173421701c0de8e6b9c43b47ba0df5c3b6ccf0d192ee911dab727327ffb0fb8da223fdcfac4b4342f2193dcdea469e9f74d99d31a87c1f37d3377fb66c4db1eb271ffc0e88cbebd5e24d6e4ec58e3a3f48d8cee9b91da37b2b26f5bd8b44edfe88fbe1d9176bf9549af7f287aa47fd43fee9b72f44fd1b267e219f6cf07fec0cc9041792da6acfb6adb38c920345734880789f9b4bdfdbcf54fb4d7777c94e04ed659ba9783eec0c8e3be9931835ed4fd72f6e177bae43b7fe43b5f8ecfc29f7292eb4cdac1b6b14ab2a31d7959b2b9a3c136ad415ffcb9c140facdbb6d7fb1fd07a67f0646470c72f135acef30180f2603f3ec6026f27f309791ed2cabce763d4975c8ce6cb1cfd978a08b099674b59d29b61d6dbfb9bd0fc626182ce0e799e70666d60c6c7e66560ecc4c1bd8b298993530f51ed8ba983e1fd4c40f1a98913f30bf1bd83630690f5a251d53dedb56d64b65bb89fe48a9fd9dce3ec47e2db776696dd5f4c32f069783abc1f5e06670ebaf06a607fa937032b81f3c64cfe9f5a0ed1d0f1e074f7d33576d29ac5d6af7c95a39357836cf9b12d9f5816c6aee9bd61bbc7a496c46dde04d2ca4c17bd6e9be8793e062f031580ff606fb83838119f103d3c3836319a5bd23f3db7ba32b52230f8cac1c9c04f3c8f6aaadf9d9e07ce81b7bf469e80d03bf188632ab6c8f0da3616c771f0e13d159c374d81d66c3deb0df3d8ddde8f53bc381e892e1d06fb8fdbfa6d587a361debf1b8e87268fe1d4c8bee71ddd51eef1a7e0ceaea7d81e1ece86f3e162b81cae329bcf7a5804723eb1565aa3fe598ca5ec8fecae236d7d94865848a6bcb69c9fd1d1f062686cf9617558cbb2613d9c78a7de62d8b07d66f71e436fca6f3bd8cb447f7145ff6cd8343afa63d88afb26bdcb7466d7a8ba07b6ff6cbf99ba5c89c4195a6b7433bcb1ed3ebc1dde0def65440f1f86ede1a3e804bbbee45652cf77db6aeb8fb0ed5c5cb0f4bdfd4d706574b8c967f824fe9df30bb1de64a3294353a6e18bfcdbce8aa1e9ebe1abe870f7fc9e3c1b98993e34636cf83efc181a5dd1bb0fdefa2bd36efb224d860732b6ed65748cacd318bf7b68a56d43ee9b761cbab3f5b592ce39f41b3bfe8829cdf04876fad91884b5d3ed7ea4e1b170af2e7b696d69ec5c76a5323264685bd1c882a1a9f5c8b4a2675a6f64e4f8c8fc766446f12832572cf26094c83af928953db9a3ae4406ede7c8b4e2c8d8c7a3bef8155c2b1819993732f26d6466dfc8c8b7d15874dc68329a8e66a3f9c8c89e915d6bb7cf19b9335a4b7ab6dca362b419f6c3ba4dc7e98e725ca814fbeabd8e3623c4aa18cffa4e26bafbbee82e2b6b6d7b8c4c5b8c767db63f1293dff55f76e38ad00f23336247e6bb9169ff5143765adad8d1a829bab55f17d9396ab5b77b8d21235d9de9ef5445f7f01a999935ba1a6dac1f30b4699bdf8d4c3f5bc96875c3c88cbc91f9f7c8cc8ed183c878ab03466decc079927d6edffa21a54bd79c76fc14ee7be3a74bf343dad7e992fdd2beb96399096e5f1dd6abd84fce320e64f6d87eb156e0c8f4c3c8dc1bd9991f8b056fd766ac5d3432e37c64ed95898c2b7b6f647e1bbfc2662aad6975dd1c71b11023ff466fc3d6c8f6b86dfd3dd18a2a1f5eb0f3023bfa46a54f37b20fccdcbd1c1d8e6c8f1ecb9c77dad88e64dbdaa7b29f76647a7774de1b8e9e8379eee75e6e74411ee65118e5719ee4e9609c77f32cefe57d6f959cfbab7c900ea3ab7c387830cf8df2dca6958ff3493e0d27b9d161f95c6654be103d68f79ce6cbec395fc97aba6dbd7c9d17b91905f18b5ff4447e77faa645f34fa75bdc1ed4fc222df24a5e7591e0779165db19b28d6d59fbdb3e637da9dcb4605ef71b79236fda588b3beb58c3fea16a49377cb75eb4eb8f509fd4109b32be9e975b9fca1be466e4e7976295bad1749ac4b63cb92d8319d5f98d8d88983a4d928b78667444eacb7b4e5af96d37f657d696b7fb15864646e677d1517e9f3f74d7f15b7a93bd644f793bb7918b439158f963fe943fe72f79473cedf4d6f4d36bfe96bbba4b8ccaad15591f22dac6f8649c7cf5dbbeec4d285bada54fb79fc1e49f9776feb87d713656d6d9d1e99a8ee91fbb729cc867b90c6eb6bcc8f74e3fd95913cb18756b336696e57bf97e7e2063d4fa55b9a97b6ec66d7e9ccf4783e8e8cb79a0bd2feb23d72287f313d8e5af28356a9397a3a23b570e7bd2ce61ce65b797f60c330d9ad1ed36ef8a5d9b9bb4c7fed81b9bd13ab6bac6c8f971243ecad8d46a9cc8bc1f9bb2d81a0d17928fdb4962eee5fb2203aca535ee8a1c55dd603ec71974a1d167e39ec4bdc67d919fba5716f67a7e3b1e8c87e3d138472ba3bedc9162659a2dbfad979de53d5b56a3cbc613898d7d91dde5787cb5f4fdaffc91b27d5cd2e9e369bcb13bf86d3dacdd3f9e89ac1dcfc56fb2ed6b63855697f54c2f8f6dccc8f4c778d956bfd2ee574bcce7d88ceec0e88ab19199e342f61cd874c71b91c1e34fc860d3dee30bb49bf9ed187edeb826e3a2bc5feda73360f7fa6175f6ebe5f4c7eef3dfc51477d6adf45efbebf7e33a74cf09a4f9a1440e9c0ef2f179b0d54de38648beb11d37769792b9c697f4a99d1eb16bc1c7c62635a98dafc6d7e39b30b6769eec6d2dd9955f6a58fafe4166829b05d7b42bf1bdb1dfb95b707c9bc7e3224dc6a657c766fe8e1f249661479d3d11356e8f1f6d34d1dac256ffd8796fe7b9b598c6b6e6cf18c176b4d8f4ece76b5e1ddbdf4eddb98b8eff61e4e5c0d8999bb43286b7e89eb523676fbc3f3e181f8e8f82f9d8ee14e17edbd6f8647c3a3e1bdb673fa55e3a43ce45f3dbb32256bf4efc8937b17e903d1d7cefd6c20b5ddf30ad6ced5c3b6bac7f3009fd55b2fcc9f98eb23fd246eca92d7b63fd4a30ef9b5eebdd4e221bef91f59ba86d2d9d492c52683c175d674757de99249374d29d642863cf5a1493bef515f355af3919e44fe32bb13cec3a85b5446c3ab61d27c3c9c8f517fad1adf9d8f21f06977938d89be4a343d71f1e2cbcfd926edd9d21dfe9909f7d3e61cf3574c464fc8be7bfe4f1f5775f74bdf97e32810d60eedbfecb758f369e7fd8de57fd732ad7f86132b5d6b3f5bf26b3f071328f8e260bf5474ccf4ecc68cd8c3c9f187933312d39294a73f41732e08b9dfed1fe71addab680193d93cfc9c5c4e6539dd4267599e3d65a703626ce6d4c1ab043fdd2dc3f43cf99cf8919411333c727978885999e9b9834268c55d833ed66c64ccc28b0114a966762f29898993931336ef2108cf4bc3ad61fa27cd2eed911f3d8fe21a6e564911d794f62abdb9892d3453bebce13338327d61a32bab8d7125bd77a84dfae7decfa23dcc3cab508db4bb63caf6d8d01d9a8c6e4cd8e7a911cbaf7f84474c0c4b6f387ac37f57d597718ec61cdfb1db123e8442743f785277bdb76d2fbf67b737f7280f58f7db4cb838cb8727fff6a4ce8f58c586059e697f636a86efa6e9cd9b63ffcfe7bdee3de6b8da361557372d4d6b89a1b0747dfe826db6e76ec99769c9c8a9f6dfdd9891d6fe677a377f7ae56dfef4cbd69303533646a2c99a991315363cd4c53a4465fe414adf4bed511ce5e7cdf99d3bb357d109d31ed4eb3683ded656df1d2b315f63d754446aa6c413af969d47672e045f64345cf62878726bfa037ed4f07dee774181d4d47c1dc9e699fe6e61a1b9e0c5be955300fb013c2eaa1e9d46f4c67c3d674ee776cfcc61ff16c8aefde8fe285d3c57419dc59399b64c8d794636a46e4743d2da6e6997e6ef7ddfa6e5fae7ba760056b45cde9e7f4625a999a5139adc91ea5a99102d346ba9c364be7477ee68f5cfb1db78f016bbcc3cf7c386dd97247ede9655b6247a6d7a7575123b575b91e35eda89f9a724cedec37b3717a37bd8f6e8cdf76ddbbebbf4e1fac8fc23394d1de56d7dbe82bfb523ea7a5fdccd28ff61939cb69f27fa45d602d18ec8d2efb077f4467bcc3aff826d6c534a64f18edfe8ff7b73364e7f71867eea4c3e9f679ab3f5c9460c7af9c1c71dc96c699cdfb59c6d7f465da99bec66fd3b7c1d9d47eff31dd9b6ed2027a04711ecfa43c352d3435f263caf8c1c376aebbb9fab295294e363cff4686d83db2b1ac1859bb797a84124fe49ec6c3fdb6da93b655a6c75b1fc8f90376449c88976acf91db75d8a9add919d67e2193edbaf1d4f6fe93f83d3393eecce89b5910d6273ccbd0dcea107796cf9461164e7b337b96b08328a52fb265168bde98e18c9aee61e685b5e9280f4633538659576279339346daf983fe082fbc8365d64384f344dad77ecefab2463033759f0da57c6c5feba7cc6ccccfea1a339367795bf70ed8116ffd17ee5956d90a9d61a3ae724a602beb13f81d2eff0efafbb9247f9fb63ae00fe9919ff8b1e5516efb7c3696cfefd6eabff821fcbebd538e529a3a6bec787d954f893e976297e6f733330e67c63fcd53ec3fbb9335fcbe797666df49f022eb23c1dcc8b162665a72b6982d474170385b41239f5306e10c1e668df3376cab3dff5e86b8d960e7aa8d5216b3b5fddec5441e3012f6709d62ae97f4508efdb6f6deacb0dab0f7305cd998b7bf1abdf9c3feaa3feecec2d16c9375669f7ec3c670ecfeaed985bfca3e6695998d9af666b5dec5e07e564fd799db371bcc67b69506d005764da365be6bce5a36fee156baacaeb2d1eebdf4313987cee1790a9ecf6ffbb23fd75ed69a5c78c17433bb1c9c798bd915f6122d4b670c7fe68fdc886eb265ef2f8c061cceaec70fdc851fb5ad3799af6637b3dbd9dde8507ca3e07c766f634fd65ab5bacffa0c363a3b7b907fd39f747b92cfd15f7654f8c19d9b254fd415939193d3c62610a9b56d7ff73b9c207067354b52affcdcaffbff2733636706508ffc546794fd90a7d2f7bb7e09d3a66f75007f8efef5f95642b8fba762b9ceda76b5c11f3adfbc62df8fe3d652acbf097f84e7fcac2d3b333a65f62473afbc6f89ba64774df5a7fb744a25b73ac2ca325b2aab0b6c69ad7d3c3072636666dacce43deb94ece1f36d4da9b3acbf327b95f799fc70de9b7124bcdbc4c6c4dc1e2f93dfec4de23c767d99e7aa7f5807c73e9f99f9cdec43f2b3f190d9de6cdfed2f58949ee31edcf2faec6be91ecae1cab59bd72fd647ac1eec87a26bdddb244e4477da585eb496b58cd981b0b37eee6687b9a9e7ec4874c6ec78b4999d88df36434cc7ed12c18850195cf6037cf4c747c926f8101daea3ed05ed6f75d9d93723fcaf5ed023badeb1bbc7e1573aa9a4d3766788f581edeae3ec5c2242737feed9757db7de728ed8d6838cf7818d0f5a3b81fbb55ecb673c759dfd462c977920a74ee761dbc50068eb59af6d901a7533c3cec43bd101aa070eca312d5c28f93c46e9edccf89c4c6d8c649e6445af314fe7dd7916199b7adec37cf7b7739c7e8ff50fec77f3fef4cded566c39d9ecf62ff57bee2c5ae1bfca9af4e0117132bbc6f3ee453d2313b24b2ba3bba7767d55cf2b4f455e58fd29a3dfefcc077e311fce47d68fb196e63c9f8f23b7e30fe7b1edefaeb67b4983a9d3017226aeb4dfcdea88f9c4c5d91aba67b5bce65ed9f147cc6f527f3e9dcfe6732b9dac0f61dbd5591fa62e79c3946be1af86175e61e380b66dec3ad17c395fcdd7f3626e46c3fc737e31afccab56ffcc6ba23be675aea770b41b9d7eb4d501f2b68b69fb4b9f7deccaf3ed2cb3ebea368af2a3eed819c13f7cfeda5fb5d268326e8bae7a6eff38e277d21b718dfde3eb38d3f7e1d815e16534cf0fbaad79c36fcc9bbde6bc35bfb433c6452faaa23be657f96a7e3dbfb1fb8fed2ec9f9ad1fcfef5c9fc978c27ebbd2fa886d75fb4bdbca762e7b628f3bbbd7ae619a916cdf3735b77b75cdc899cfe49cf5fc49f6cd58cfd8c640ecefe6cfd064c7d2132e467d20f1f7f98ba437efc8de9fe98becb7b1eb1ebaae7252d229bec8469bbf3b63585ec7663c8bfb3d4f249ee5f6efd85a5b3b74d2d6bdca2a1b1ebfc6b5beece5b1ab9c83782fb3657cfb853ff1ef5c4c03ef88b4e5b0d7fcbdadfbd9e61f7256d2ad539c49d4c4c6fc9c0cdc43ffec4b64d2bef325ec87f5b969abb99dcd66e4cf4ddbcc4f4aedc775809db56ceed6b47d62dbdbeec3d5b5ec93ef9fffb7beffc9735627da7eb775b29fa1bf8da169bf63f4ff90ce213cf363c43a312e2d5ba960ef5b8b746ec797952a75ecd732ff9e9fcb5e8485dd4563f4eac28ccf45207b00adae777b13d0f7a661bfe93ff737cf22df5bc48b647c1c9fa5cbfe7291e673bb00b7c8f2380f8777a19911a629fbf1647ce8d58d933df482eed962b4c887fdc57831091f2783d151d8b76b10612fcf17d3ac981c8461f438991a07671eb426d3a035bccbc3ac08a3c562b1342ed22ab85cacb362fcb4b0ebec7178bfd82c3e179b301ade4d4fa6d6951a3957cafcdefc7b3a7f595c04d5eea91f2c2ab3869f2daa8ba41ff8f1a2e67717f5c45f34fc9ed10dc345737ebd6865c5e27271b5b0b5be59dccede7c2f3ef72f1677899f98e7ba9191dfd12259dcdb7a1b1b34f13df35bcf7cc67e6ad2ac9aef1fccd0795c3c2597e63bf3bd79eecf7f06fe6d5237ff7e5ebc2c3aa6ecafe6df6fe67a5f7c24f545129f9b7a8d177b0b334216d9e2607118dd2dae17478be3ac085a8b22baec0f1627be973e79c9629285836e783d3b5c9c2ece06e3fef9e27ce92fbdec7e512c0353ef6369efc5ccb4ef8c9fb61d83cb65b8e5e9937dcef6c732faf1f9bff773fa346df7a692ff647f7867f3b5ef41b3e5306364b434e362190fefecfde9097f67fb1fe99876983e4d4683c3697b99ccd661649e4f4d7dbb66865f0607cbcce8d9ebd960b6b7ec1953bc1f1f2c07c9c9e2697cec45f1ebe42a3e35be696f395c8e867dafbdccf3e672bc9cc4f7fe831f2fa78bc4f6bfe91fd3ffe313d3573a0edca7b9a047da5bf966e7ce7226bec9c2ccc1e55cd615acafbfc4bb97dc5e5ff830f65ada9540231317669e2e57d82181f5e0d1fe560658bbd9dabf5cefe09ecfe57a592c3722d3969f78fe4c3e9d0e32d7f2c25cb66c90ffee4c1ded7d9c5b737b90c2b6eef7b1bb2996b5b033b3ebcb368dba9c0fd773118c2fedfa09e5fda07f5587301686f7c24c3f652dcadde3be64d32e0b53a6a5f5e9ccb56c623dc393b3318b91d4d1be5f725a601f5a5764a75dffb03a98eb18aeedcedb5fd695d89edcfbc0371e595e865fdbfb9ff8a4ce608c943606cbc7f53167fd95bee773cb96fc6e79293ac4ead28ce7208dcd927c8ace585e0523bb57245dc9194bbbd76269d2581a1d66638edcbf4e7f56639495527f7cab4710a759b9f32078efd2b0216ff7b42b56de59d65d1a0dd94dfced3bf35edd730dbb47ca1bfb8da5dd1f3c4b8bfedde06a1289d7e96261a75b7bd4d5d82bd9bfafb2e7b3070decae9bf63672076fdfc6badddaf04c76cbd87304f6ddbc7ab6ac16ccdd7b3ceefc6264f7397590beb1bb6dec67791f35968697a635968fcba791f16796cfcee694f7bf6fdf27dcc03ed9c29d25dcb833f11d5d47ffb357db97f70adade7af1926567f96adf0b63f2f0dc1eaf7b777eb2331e2f5f97f60dac67cb77279d6c9cab63ca6afdb85e30f7726fb1dc1f27cb03b1c8ec0cb23e1ecf71587fc1ed5279d8c622759fd9e9d7cbd9efd7b2b6bc7bef9fb86c19ecfa8addefa55104f43323398c33fd701d6037a5ddf36ba473af9dc56e1ce4a66d8c95b5b4abae2f720e24be30fd65f7661c64ddde265fd975a2e5f1f26479eaaf701e7385f39bfc1b02d24775e75b7aa5f7057c779efda3bd3ddf762db6fff24cbc603b07ddde95f2bed4d299697db71fce372ccfc54e2cefcdd418d82362253ca7f1b0f5d0ac5dc958cc17cfad2d2dd8bd59f97607caca937dbf2a03dee40a9c11077bf541e498f37e63d8af764dbadb7d747bbb8ee4375fce3e972ffa38dfddfb77ae4aa99ca6ad56466eaf2279d789f547d447aa8aae5ec5b2877a9588ae18f36d412772767f95a23daeb03b1df6b89d2d5ff62c97d63bd4f33efb9117b39fc48ffee68b33c5bda969c7b3576f9bfbb6be598b9fd7646f85dd3fb6eab6bfbe0f8c3e26fc6aab435699c400edba9cf59bf55c3fe3a0b415cafe6679ff9c5ed8f72b73aa22670b8d4cbe3576dad370d43db57b8fe2e770e4f6415a79e57a14ef1eb1f3f245ce27381df4e8ce4337ecfc5ef5567dbb276b5edbc62a9cccb89a8c54b7b855a9ed3972591bfd3e4ee25ad64687cd4858d9d3417babe1788a73662d1b430ae656060c2e8337ebb9329e6e5b7d35dab28d68aff2d5d8ee4674e7dbdfbe795779c59eeb737127fb1ec9bfe77db24647d9bd5ce9663559deaca62bab13dbbee7cacd5350ebb65bf99ccda2a3d57cd25f2d56cbf9e36a65f732dbb321f68480b562ed6871eb45ce5a95bd073666e5eaf7107dddcff4f0e3bebaf2a8b5eb23ba77e2fd1ffa7c91f2d112dcddefe5d6b8b9c3fd071d289fb6ced6c24c6f930b6f62fae4c897773dd660ff3c3a9deff674db3dcf2bbb13c993347b8746077767896de7a4865824dfb552515d62d3f2be7bc717f4c8754987bcae0a1b275e6ddadbb8cf71fbebbed4f219876bd141ee3c34623856ef0c1e569fab8b922e799788a2935b5ca17ad9eea329bffbf0073df28e5d14a7b0bbb18fa86766e1aa22efc0b5f9aeacfcc0085ad5657f17d3ed47c8d76af56ee84ef3ba3abc96e4fd6e1caaf9cdbd3f19d7b2b670909b72d9f298b65d35e59d62e5772d5a89349ac8c9b5fe427c3c2b33ed2e98d160d5b2fbc6ec3b469cc582758cf27ad20fe7f079710de1e12bbbd179f20feb9027e46b75a4a9ef4a67c9b68fe93ffd4a07d933aaab6b9c6367ffd4da5fde87a2b149c4feac54b57b2decb990d54dfbebfe8aefde359cb6bfb105709ebdc1f55ecf3732d4beb74fdedd27fe4705fb519b784f0663fc559fef8eed94cecf35ecbed5c4dc5b19ff62654feb9c96de25723599aa2cd15520deffeabf3042b9badf6a61b787ec436425cf72ac1ef26152f18b553beb8eec68f1a3b65d9b5f3dae9e448789aeb272977b95c6e1aab27a1e1fb97a528f94ff766dbbf4fddff04ef260393e58d9f3eed9aab37a9d4e57f694dabd17b9fce55d2dee9d20ab77a3bb5ac3faf0349cac3e96efe673b4f2567babfdd54170ccf527539f52fb717789db69f1cbf5891ff73b85fb76bfd63fa843ec2c3f0cee6c5fad8e56c733ec3891dd2fdbb57ab73ef25ed21d5fd231f535f6c3bcba3a599d7aab95dd55daee9eaecef1b708f8774b5acea628ecb99b35def3bff6fccef4d43b72ef9face26fc2ac314eb7efb497bf6375e3fec65af1133df22b19f8dd7b06cbb676f9bd45e5eb45cea2db13508c83db91ce5d073fdb95409de1e48791716b2337d621e2ea3bfb765cfc7ccf7ae26d17d758476d7de73b9f2bef76e33b3c86d375bc36d6dbda9ef01db575bf9abe0b70f74cfa5fbc6c2ccbae3bd9bf8fb236f2706d46f3ba676422d768ae65af5c62da6add97b5e1a9912e8b965818367665576ddd3beacba3ffbbb5687c9f60ad9e7b6275bf5d593effa7fc11eb3fd97707d8ba0fd03fa5f5f16057b7ec5cd6afb2d19bf5d05c23899daef36fc622c6a3f589ed2ab2dda7b71e97c6e977e3b96c1b95f7cf699afa5e14bec384b1229ead586bdce7abddfe5dfc06efeee3fbc7e327bfb19ecc47eba9d4d0eeee0efdf5eceb5aebcefe1b6ad653d129c1d57abe5e64954477aa71ef265aef4ad6a5d7c6b35dafc2d17a2d79592bc48d127fbbb7d8ae3e592fd7cae2856d651b45ad1b59be11dd27ebe8edc5173952fe7b7e7ff6d3f86b9e19216ba3f3d626fff5859cfb9b75b3deba9275d28f60beaeae6b569ad835605b1fbb93c24519ec0aeec356a7feb8ef69a7fdd84ed81deedeb4906ddb7577368507b27fee9fd325b20a3048d7f57543fe8252e8f6917ddd933b7d6aff5ce7b1af717a3c6e66857d0bfac4ee86cd313e9bbefc1d4a77fed39ebc36eddc5cf4d72d7eb7f37e94f2beb9edfe875fbd37befceec5f299b8eaee9cfac9557e3738edf9b6c8e5f5254e4dd93d40a675d6bb67ce4ab246f77de19c82931d26adf5cd8e5ff1c4198359627588ddd1725192511fa2d519e3b2e9db91e7fc9fa1d8a96b236ff2bbf6d73592f64fe4d35fb8522feadaf7c2d873e9eb7bc9d7e69f9e88bf61cff8bbbf8be26d756e794dfc877dafa5ef5cec6ae75c9eeae1b27f421f7067264df64bdffd039f36fff5c3babd7e94f8627eb6ed0fc6366d1ffeeafc885e0fb2c7796deab97ec6787bfd46475ccb7b78ac3fe7d6c276f7e77dd74ff6fbeffec6f0f67dbf3fd30be573d9dc67b4867cc5fcd4b3bf120b92b505fbfc87df59bfac3bebd7f5dbfa1d27801fd61fdbbd9a3fd121e7d21a7cbbcc285befadb10796e717f8b73f68b5857e1edb78967db70acf0dac0f204fed4cc30e36fb66212bc3e7d7e1647d349dad8fa3a3c4daaf27a57750eeeaccbffaee7c93763e307ab56d63fad1d1f4757dda1f87a3a8919df6fdde9d3d412be7692279bf17ac511be7d35341eff6344112bbbdb93a024bb141b6236357d8e75696c9e5b50abe85c1eed7fadb7729ee5c6ee592fb6e6dfecf3887cef347653df24d5974ffd84b70b7b6d2f0bcd728fc609e3ac9fc839e70ef2788edbb80cd9871ef862bbfff7857e794fffec8f2b77f7fa4baf3f99d5ff2b3fb5c2b29bd6784ffb67f03a4b0ab5d46c61701f448fb272d5a6e219e5b3123bc3069d8d9411d63cf22ba1de367a5a8b12feb097a26cdfa22fbb2d66ecf5b1411dec93894f559bb37c0fed585d5aebedc5d13f93b7c92135c6d792f7b11cbf99785edf1f5f6bd5eceee2ef94f5fecf69fe9de87afeda97e072d52eca5559d827387dcfbf08ffb231f523f1b81b7f9db98dcee99c41fa238edafbf9fe02c93fdbdddbf56d81380a1585be5b527ed43c6afaeb12f63d7efd8d51ffcfcb93fb2fb1ea8257cfff2f7d59dabf9e5f9ed1af5f6ddb5f29e40630f16693829ba8bb3c29d5c2a7a7ae670c76efd628fbe94ec6b9ea5e0fabb7d2bd1a8e8dbb314fdaaf82dd6e6b6766f8473cb3c87626749312886c5689e8e7c6f51189d61f7061463efaeb032392ea6bd97c5937feee3ef33aafef8d1fffab39f128bef488bdb732d5e50cc96effdf5bc657bdcc5d9e618cd9de8cb79fa7e54d211e591573e476175ee39628290d5c93e58d7494ae7f53012650d7b32fafa4e93bfdf1f717b256cffbdd8185712ef9eff70e78618ebfa690c0ef5347d5fcc83f9f8322dfaefc5a29b489b96fa49faed3a98f7faf6fda1edc5b76740b7efd4dff671f9efc1fca8477e36bf7855bfb9be7b8edff19db3909fd6e68e27abcfc2c8ee62d5feb2b6fe831dbb73b175dd0e6aab7103796792db0360d22a8c1c2e70f67e803dacc546648e5d632d3e8b8bf1ad3de1da767fa9c1b59ab90a53cec2d4a330e59efeec7dbb7fa71e698b4c8b0645dd9e99b67b538b86c8723b1b66d0893c7bc9730ee57d4e3ff826ef5f6386fa9eaa9b9d75a6f7ad0ed9dd37f59f5a67b752cc5ebbef7274e5b82af9a13b6bec22f1a0535f25565598f155b4b6edbadb4fba3faed296d5d9dff9d4eceb74876baa476a5fe6d28fefaaddd521bbbaa42c73656e16f6fc967946f63a195db23cf31b53e327b8774f2cb0ff665777bc977400d78c3f648dbdb8945dd1c555713dbe995f67cf9e7bf7888d83db952917f37910bde17ac3edf18ada83c3f587953d767d7a9da595f8c597f7ef5d7a83ec7af696568b9be2b6b82b8c27adefe9dd95257f7d8d5dce1a9a116adfd9523c743fec0ecbf4dcc870affd250ea556d67efbcbd90f3d53f325962511e1a22d116267853c6645017fad2ccbdd1b9d2af36892664518b4d59a0dffbff6feaba975a6690385cff7cff87cae2287da474eb2c12c4004033e9373c63955edfffecd35dd2d8dc632782d8c59ef7aeea2a684654b1a4de8dc579fa8cf27e27fb2f3412a9bb1707ee7c85824c8bf0f2aec59947128f37d1fd30fc977014e8ee2f7e30662f61295c513e7e8986b1532cd92e59902afc5a9a187989898d17a91ee167ce4335af8510c6c1ccd357e8f38aac53369d49aab8abcfc1b7448f39037d200174a37598017bcf6960b756ea1467071e045722485b6ea95a068f4e290f25e16475eb46e4a9afc171bfd3cbb6812fb8556223ad7be250b34fa1b6097b13f07b61b5d67eb35e4b9813e51220a000c29e45d003f0b188b8b63c2235c481ebb7814d92f84d8ed851aff05f8938c25f0017cf23b74388337d083f8fb052c27c3c5c5e272e92c13c4d7b7ce63ffacc94ee12c3dd19bfa6c5de8b1cd0d9fc11bb52df090e66de92fcbbf53fbf7d3b6a91eccdeeab337477307e8669d93d19cf808db64b6a1518f5e94c69e93269e58f5ef97956575a9f8ccb23e6b2f1b1c497f497e10587ae14f81cd68d95cb6de6bd5c2b23daa2d14bd98209251c70f3096bc67d4aad8fdfbd351f54363ef979c62e23d315b76140d7708070ab8b7da1a5125bd6ad95df6967dfaacf5068769ec2b4965c02c435cf0f21df8ef4e77a9c66339acbc2f4794a3283a9ad6ce6f96e379be9b47ccd760bad49899824db09cce52c0c7edea982a8e4e31a24a97b3515147ae3bb63eb343bd45cdef72ce91ef97225d553ce4516a4c173def4a2648719538259754fa8df258d7aff7266bfaf19f1c6dfc65e3fb3dd5d53d23bc278cf47211b53d6d6d7934e457ecaea5da01d343f25d036d1bf6a9b1da19cb154b2997cc4380b7d5210c62d439590a3696992762d3935dbf7f9a79c905f154f88181bbb14c31ed649eb14cd37b21a374a9fab7645e11f010c648111ffad2a5b1c5fbf4789c13eab7cb1cf38a22496dc04a411f205122bf46d36cec9e33c26a7e2f1bfa80a1f3e0b9c8dd08f485831df2106b6e75ae6121aaaf80ca013d095455e7aa1e7b81beb1440c02e7deec648e4c7d649d8f7c270fc1d1234ba7ceaa74285e8b109545defd84d698181c684ffe2d667e79354800cb6a79ddb900aaf1b2d0a9751acb9be52f8eb057cf5bde2eef902dd61f9507d349bda8b115b34eb13ce7ba1305434e95bae5bb7e7fc4626512fefbb073bdbc6fddf66eea374b0ffac164ac33559f5b33ec8ce5c3f271895da07dc4eaf368f93ceb3a3354b4d1e8e48c638b6be0efe91d4ddf9645f8a38065ac66f392b058eacbcec5f285f53158314e66a7cb57fdbec9e51bc54d97d987ff5e6c679725cedb61fc32338e4eb00c44178afaea77c34b96a05c1213ac737f28be4e57d3cb912ef9de18df00715dcfd7d4197731df47b5e4f2b83c88c52ffb135ebf7d3dc4ef68698a9f815d627962c46b3d867ac6474ddbd38d5d82cf4b255b2fcfc87685bc3d60d4c3ba0c9abc64da8bb8a7ce0bd1ef20af50f20c4c3bfa77f00eb3a915bcbce0fea4280f025968c80104dac5529d5f395c4b04f9fdeabd5609ca1d0122c1caa75805e820e227420635f24cf06e01d63937c4c6aeca8ccf7b4ef8043206c0b2ed30ee098ed89de803ee8b710d10dc04a3e4c0f0fd5f7ab1715f3be123871c8123b6ad22f18ec198ea290798caf06d9d53cdb2c685b7bbfaec3fab8f649cc5aad24f2302a47c3e196357686d2ce21dfb441f1169ab441207fc09ab2afcd3156f555bd5578dce01b0a5a07b089efd0a28701d67ac6d6ca81b78c678178aa656951c1fd40b2c04b904dfa38f00e3319758e8b85d96e99b73e849fd2a6aa5b41f1c5763b69ce95ccf05ea406277ac5a4e717abe6a43425c75bc008b173c45e754e21dbbcbe74aa1d9981e7613ef437fdc551463d553ad3fcdc1d6a5fd4c6ad7adde576dbc6fe2bd9e6c56bca00640e7543df28068f76a60485b8fe4d30f72012f19a76bc73c44e675350ceb8ae8f97ea5a84e50166da73ae0f951e3d9bc5c8d9a17f03381a2a879fdbfaf8fb07fa5dc261feb6a6c44177ce443dea08fe8e32bfb012ed80fc2b8c0d062250f1a3c66257e5889eb113fbaf4ebc40bea7105b4e43b6c5b881fba32e4fa22c50abc97016ac1cf2dd16f578c1fb6526335032598132fd43c48f185d582ea05a296e44ad1dd15764592f432e0e7c3b3ba4a91ed0f7c4747afa89db5e218e3a17ad62a435a3f227de01f814d0b3c44f252223e988390b60791423be421180fd4245e2122e7d40b700e747d15f4f995c7c6f3024cb595cb3c7797fcff67f5911745bf141d874fbcf232d458ba2461d9f15a9fe8236f952836a068e625b291ad72b4fa707e8c4caf31e705487e0cfaf2ea90ce5177c87e6ed6fe306d50bb7cff0cdebf3cd031afbcc27484feafa50b1ea173da291f72b1523b67754578f489413db5423dc066f50e1e536042b56bab6be82cd581e3f64f156daff378700428fc2d628732636bf1bb95e223e545b9b7ba616fabb68e0f757ea01e4fe8230635828f5f7203bfd3170fc48afa2dea62a20688dab58a2aac7e398b9ef6fe490d4b6fa2733fd26a8c6e413d1c8d03b053dbe3cfe9232cf72f5ec94ebfba33f88191a3f861f32c3e1213d723b69ff7e7d5fdf2da5baf5bbea9ed08fbe4c3f7874ee1197e07b512560f5c433865e073e4289e2bd0934033d5f880f7c1ea091cb3f63bb005564fab67aad514c465199896413c94c4f71e537ea6e00dac8a5e50836a22988cb6446b8fbf35de5f694229305fa889857168962a8d9e9ab715f34c5493d53c5efc4aa24f9e13cfac5d1abc6517f3f4b3fa08f2889504d1bd812fd8bfd29afa1acafd16726b44ea121e13ad65e41756afabb7c42471c31889052b579d730d2755c6c8d8854de4b363c959546bf5c6b84d7e0ed890743df76ae7b18b7ac573d44d7774adc27ac999d52069951295d541a2b33a74ba9573e004a8f7bb5e1dad8e9b6dd4f15b9dac4ea758dd8ee030abf100ef28fab73348b28390e76a1de864d0688e094364a5f4b3f2015dd75e4cc66b3ef6dff27f6c3b7feb47eab7d283cecb3d5f499035e4fecc1227ab0baa2ab8c22eb87538f6cf9b24755d17ff155562e715eddb5aec4c7ffc79ff08fbb351776a5a67b99769df6f638fcbce92cf06fd83269f4c948b0db52b93c87b169cc5b8380013a3f1bbf9488972eea12321de2c59c68a57c70ad1f6a4a25f0df57d7f48fc7606daaa5649b266f43f4d3913d55b3a57cf53cda5c931e7e778acf5428ae5bc8cc06608cc6275af649d9e9384dd8af50c78ef62c7f99338ba2f37e649d085928a472694c4976cd17b26db54636bc6b10f62b74b760863b1c9586a71b15a5f9aa79fd347ce880e366f56ed6417b6f85a9530d195bc1b892bfae4c833a76b15bd195a3fc7b66aba8891ec35ca24c3aa4658bc6b31bc08400ef8c837bfbf46273a70dc641f96d6f9db2a937c4f2a4d3a396c7b8b57a7981c55d3dd036736ee038316d246b301fb542f5ff59b3784673c85fdedae511e6a0fa83f56fca6981cb7a7c9c9f2daaff8478de270f85e4e4e7525bc02f9e47b8c92f19e55e37c4975ff9233d49e657f8bd633cc7cf6981db16b9fba79e4ba32b07726e7cdf7245005a7cea2d64f2e93eafd93c9baae9f8ef880ce93b348aa159b04a56df7ddee1161d770bcd6ff757d24cd7b3e47347338e2bcf24b2fb0956c4d7b36f091aaa03f9f5175cd0886a39d9f6ee64a9a9fbf918f24990fa01eb0f616de914f074873c8fc820d071e565d4f12f43e4b988c669d45adb31878c1824f0fad1f7e02f09f2478b2e345b0f6033d459d4fe6a8495d113d070f31e31bc7bbbfa9e95dcc7100627bac7609b312b63d8de17c403a0be2a5e11d85bfc48ceddd49fb597da44098ebc052ac979279d4e61bd66c4be216b4c78a7995cfa4dbf8b788e15a1cf7f3fd5bf23d3b73c69db4e54e9b8f7c872dcb3cbed0739257ce0c7891a8d6895a6189d7c110fa8348435211c06f3b45d4c0d5381f197f5c5e906daee1328e5446e34b516c755ee353fe9a2ae92a790d6b6e74bc0413b37cae9ef362f8b21fc5f7311f7dcc33ecb66b9e823e8cfaa8680a0cff6441bfe3b8dea927910557adb75e6be3c46cfada4d246f92bf2a57e56eb5a3784d86b17abc1dcdd3cfeb239253fc4a769b59977cbf5ae2facc5662d332b171f175413cf019c5bd6a7a74e685787ca5284f8bd4bbdd873ec2ef8f98db1ec75b95196fcacf7b816d4f7cd9c95bb25c6b4cb314f7ff998e5a6a135fc1b317e6e0e588a7203a3e620394f112de227aca8077a3993f62da0a9fc2f1dd877e92bca33833bc8f7e479639c04f92f78b4943ad9d86e820cf216f951a62bbe2f73fa88f3cb33ea038662bedfc028e54d2a3e8ef966ff1880db486242c432f613c5fec101d497dc43b64091a83d154cf7be6e78b8c69b49deb2331726c7054b431f930be4185212de1307e607be15f493d10a92e878c567cdfbdf167c3f3fabcd6776609d5e01ba80f928f4920402b9a8b9abd1ae7f610df118e63f2d9a22c26cf7d032a1ffb4b9e041b13b6b079697d9c0dcc925889eb776d5bf6f7eb54b0fb40f5265be9a01e8c1ab7fa6406fe591ad592451d7fe06abb24f827a4f485e6a5bbb14dfeb83e12c9cda8d3671dc50d146ca9d964626398f9d86fb40b922f5e185587ef5fbca01a19ae4bbe7a512cd7cff2f277d5ec5c4da16f465c31f2301bbfd8e6f4e80558eab134fc5e902e285f2239241e51bf21bf00ea6724d56f3b39c23c06a22b7854e28978aa543ba54cdd90475165662f92b7833c95ca43f85cc17c8cf857e27887e52f096c93717e9452f87d80e152328e6f145f37169c33c15be498de72ff9bd7672a9ca71fd447d2c65e05f6c403f0e65bafc992a211c5f7026c3158e9c98330bb26a8b7c83b04f416769ae421d964e697e4634870551b1f35c995bcae694bcaa8659b661bba997b9633fc23bb78bf57c60094f7541a37d7d573b5def04c56ef8a6065f10ad69824360f7d249b9460c2248f66ed41a9dc4b1e0ffafe39dd03e3957c4e9e244ffb8f0de4663a8e8b5c1344e6086a50404d044fd9f1b8dab441e3f5b9d15cae099017c45668c63698fd7b8bfb2cef56f136d65a7e0cfd36da3669dc77f100cb83e2b767141301ab8b3f699c4f406da6dfbc3eff0e7dc4a4dd4ddab3902d81833e2c1818f3a5b04268a42e3c327cce8916ebaac06d5878d996734e1ea7ee8917e6697c17cfd8f63d25ef9065e8f98c6c571144eab3183e62d166c4a1758b8882279f3a2a616b5be009c5c40209097e11d8b3e04f08fc4e252fa2b7e9dd8638b66668d3125d2e796949556f5ebcff294e4f8ce1156bfa6529e65efc596751bd918fa4794eb6aa24c7170432c12e6d579fc9033fa78f44f386b15717a81fd229d64f666aa6fb1215fd2678bf5eb4e202bc4ce5fa6d62d57ceee79d623d9f725209a577f494ac3e2044b7943fbea9698e19e42f7fd8af401fd9c5fb092693f025fdd91f63d43b4fce6c3e6b15dee1a97be69ab6fc9ec0488ccdc7901ac60e614beadc0ecd83484f10cc626db342e4e27daaac63c17c8af1b525198c654af19ee67836d7190ad821cf749fd17baada3f17dba0ec10b6b5993cc5ec9fadc56fd322fa66b84345b71ca8d599aa19750881cba3debb76ba23ffc7dfad8f98f415da34f057b95689c628545248aace91df975e68cf971d7240b517bbc75ee82f60dfb3b6915f504edffbd48be71bdf95a31ef78e668e0aeb28a8f38b3fedd736e2d3b0ca0543df5e5192f3a7a51fbe4eefaa63635ccec3959e6a2c2e524d8edf7ab276c913f95d509765a6f8cc50d1ee548baf3fa0bcd088de21f15e81c7d6e225256ff32eb1be0b788b956d6d361d818fac00a9b322f56fa47671e91be62aaefdac3e920bf6a6abf988d21f46aa3937f5362c7a58ddcb29cbcce7511c58b4543b314b753cc2ad3f74dcd9a5b67f503c96e72caa4f959314761a72300a8a7e4f1d3396773d3674d7fac8d4d04570843ee251dc958ed69b7a84fb751f62ef6a9d43e923211f09696c8df58620e3f829f4920a7ea3605196594749f5fb69e03dc247a457de09dfef897dee77dd9b146a9838957c6a40b919a921e212fc2becc45a43e2bb2a9e19ff16d8b81e6378c8267f4a64f754d6f00822bc6450ab2282bf7e5e3fa99734be599122e0039d7277b1bd7fb73e62d62e697a614df333aab70e6c8ff28317d49a8a70639f703f02fa2c58c2432fd03d528a1ea7c66c3f8fab3d95f2d663b67665578fe3976c93e978c443748d261383916d4db17ca464f09267e221c038c6ce81e4a56ba73f7a119b95c6cecfd18eac303290fe9de807f7d40fe434a2ce3baaf8614cfb6aac53132fac712be36ff272e103a67e68f779139f8991ac8218b25278dfe16d6aaa6b8b717ecfa8e685d859af7be2233fab8f888c2efa08fecf3a8b4a87b0e5db6ff562f7b872023aa871612d5ffaf47e5e699c3a33aeb73573729c874e7bbf086c8cde4ba2d3293ab3c0af6ec668c5f4a73cdfa13e227428cc45d1b50f51ef1e5a75ff9a6c3da0ed417c1a249a82e823eb34582a18e96cac01e90b7d41a853b49d2420cebf68e878ea4a6a564fbd5f53bc167608f40ceccec109e917a9796a915a92d4da2ba456a964e26c591d4e7b2bb21136aefce3d61557713071ae1eadfe99e71f0d5ef3813f44766c903764dc171ed53976c81d8f9dce0c6019c0fb067c81bf531f3163fcdfd6693c7802ea64cf1256fc9647752b74ed43e12322f35f78a17e82bc88acc51f5eaccf19ebf85d3c44def79c6a12a752965f40e8e77d0c46a24d83e3f26b0c1e625ed77e22fd2e95269e20985de03d03ceba828518f919ad2ed59b45de7be28ab0f353cc63e66a1e126f948515f157193c0ea880d8a5ba021ff33a7db4fbea197d36721951b94df2f231bf293577cd4b6f3dae6e5fbaa4ccd9cfeb23c44b9a4e2642eb67e34ecd5926fbbf526ac45239b6d73c8672f120a1eb2ec25e855a8d849b7b81ba8b1ee18203170412499bea14b55b1c0f0a9e73eb8478c4b9108f38e023bb9467a5a955d81ca6f2a92bac04aea5c5fe8640d208f4910df2fc47fe88185b135674fbdd292e2f12f37695fd20ea77ef6e883f0ffb58eaba750f5f12fc4ba942e52471fe7eace3e928be0df6c659e2bc59d1281007d68e957e615e04fbfd852ccb8873d07a4d33be7fc88fd73ad5395da36b9029c93875537e482a99e2bd8d8ad1467dc2f91e78c7dfa58f98f4a0697dce103fa8bf11ed7d5fb08471c23852afcc33525e807368c61237949490faa5665d7d9f2c72ccafe5e78ee567dfc54b32d4b785c3166d436a34f160027d24d64aba81bf6cb02b699b9792661acf941f823c12cdbb9ee8bcd8c0407dda9c2f0ecc7d581312522f596a624247b9a53c1f6d53cc5acf171ec67160c0e44fdd91ff475ba96ddec73638ade71c501e3f3218fa88439e908ca0ebe40a768de90fd9271ff9797d24e3881fa11ad89a0487556b6744eb13057f9cbaa719951a4e88c3d276b003a631409e035a99d265525eeaa176552fa61e139d55dee9f693e50163de2f347dc4a8df18b827361fd9350f21dc587704fb5542560bd1d27087304ed691ad8f7c9c3723ff23de20a869c5e720bd8037203265c63c20f554ab06188fcf610cb0e46d68cf6c29f55c7d207ba11e9f5767068caed602f926a962eac57c16f3887bea7f4aeda8d45ba7d93caf9f75e64eb171ed31ae89a19f887e75483111a91222e197add4417980aae6ad073d3f337fda38af6a0b8c3f8ee803732366e2dfd6474c39b3eeadf311c9272b501c52f9358c9cd7d5a6abf4bdce2df4087faac7f7e976bc20ff1bf96a5db542526a46827adc39eb59dfc54b4c1f10aab95d87345e6c422269691bd711c7fdda3ce3a3c6f789d513ee498f48a9fba68e69d7d4180955c765dd132d1f9cb275f9887f7fe2456d81291ac71eea144b751d8b8f006d15d2584add0bc870e003a809d2612cce40ffe27ee3b929cc19acd4e7e4a7d115d964ee24deedc48bea8f19631ebfbbfd34be56a07b301f89e66db057b0da87be91a8a52ea41e15afa8ba3f6e6b3c13f5bb2c67691d53a68d8e132d710daa3367562da62edb0fc97cdaa9f4aab78df374826ba9160cfd63d7fa8859eb8bce2d066345ab356268c55b93e72577e36030d4df7fc443626c4411694ce2aa9efd5be8246958ca1dc71d8c189bff9178089e07dc43f1d5e3ffee73ba9cae242ace9cb16332acc321c3ebdd59805a4177d1fcc7789ef6f1ab96ae564ef46f864e11b5c0d2358ecebff7a2befa279c4f3cadd42e49a6d2f5fa23fbd3319f88cf52d74cd28849f0265cc7395c2f6983fffffbfa88f00ec9f130692ff6f00bd333752edd20da03bb098e405383dc5a874f84e3b3505f35a0419e17d45f94baaab0d9a49b54174feb28dfe10fb17988bceb05c55811b2911746d698f2bcbf051fd932e2437855bf48fa08de7f7a67acee472fc0d417fd007a4953f5a17ae985f52c3146252fc8cb48b7587fb17819763fb023b54f43f418758f749b7cfa66ccb6b6ad614e3b1cff3cf002ff7992d745200b3c7bd1f562d7baf9ee35fa73fa88d005a2b909ad2f987e697058e80b0f4a16559cbd964a77577ebf8a382d689fa087abace3b69dd9bc3d705cec984e2add43fd11e786b11605af575b86d5b9fb64bea1deb0fde8cfd2fdca99fe9dc89db63e62d62f8c9353b7d547425bcc62557116e8bb44aa07bc80fd09c44708eff7539fb57d3ea861252b5e7ce16a25be1356632fef8f5ba26db38d0978591a6bf91745914ed5ca1eff727e4d4fd86e9866db9fc7b56aef9c597a605686667f869aa3f410baa347b506091b6c36bd2584229d2bff64f41f1ecea4bad7c899f5d26a3e808d5562dd12e3fbe22cd2132751ed266e03bf888ceb2e6d8f7fbf3e22ffc7ed55db270e8c73252da4a7145f54e61cbb3647f2c186b2945cbc82417f0ad173dae67e66d1235b3f31e995f9bbdfa55f663dbe53a04dafd76c8ad06227f4b307da7c1c9ff80c7fcce035da2f7243f4fdbd49bc2ab8fe91f4044d75801cb120be9b9e6da6d7d0abc6cc8350d141f75bddab31f2a2b93a1c5305de8ddfa7e7ebfa481abcdcc4e735e75cdd37bd54f3fb66ad955de29e7cd67e5e1f31f76a6e7daf1ab23c8e1afbb676e98fdfa735bf754248d21aade092626287d7cbe777c5476a0b67361a63c65827a17b1731e3880b0eb01873461fd4736a59431f09ebb22e029e60f6eb335e22d7482cc183534cafc8feafe3aa6c1ec0f92195d2308a87cfbfa3efe8983cb0f5918f790d284843edcee9eda00dc4d3ca0bf398fb5a1591f5a8b43aae371bf5a61e2fe08e28de6df1443d4e7afcdcc1335974a56a27f84f0fba0470c104673fa5b15b8ac00f4857d46a4fa65390fa827eb1b499567c0a71d04e1803c13a90fa2ed37e4c67cb039d9fffc2f734e6eb7f441f91ff63f76acc9e16f9946356d38a46a6735c8f43ed9a96a255e93c69f011de60e81d01968879df38da6fe72efe290fe17705fdedb0ef23883af7425a2e345fd7f432f985f81dd89614e8335bdabdb092313eb0310d946ed0bbe0e73d132f4e5f514c17f4151def86f71e7ff05ed031c43e77463b10b15e7a5e245f90710a344f820e03a4d4297b169d9097226619a814c1b5a6dc80eb9404d8bcb2d6cc77ea90716bf4e7fd23b2576d395f68356328d2aaa59827e46a8f045fb0b77c84dd0631abc8f0d508ca3a5b95ed311ef3204fe935ea1e65f8e44b4e202f9bbc2ad047a4a6b7cd137ec796928edc47f5bb72561d92669bbef5421b8fe4e8dd73fe083049ccfaea461e39f2da41bf71fcd47f22d7956815d72f17edc5ab3faeff22c92a7d47f158a39bfe207d4fb9efce893f460e8feaf3630caf9fe9f85bf0e249b9071ba3aee7f248be975943d3faa2e29733e730a8e1a27d50b04d35ddde0d50f6a8de8c17581550050395bf2336c034cdf7ead11f6bac46c5bb462bae0d83f9bcf99ff28fc8ff9bf411fbb3994fc858533adfa4a3661d362cb522d20f6a54cbf49d796d402353065ea31daf25b8281217b449eedd96a798f779a65a5288ba087884914fa1d145c12b1e0cfe61c46069f9fd51b26bb7e0212646cc3df9d061f71b5e1325692bcd7bfa8b69b89983835d90fdf8bd10c7a591390e884705310fc29f390e5b68bef6ad287e907e22ec1bc16186e505f92dc1f5c6b8c1ee987eae34d24a42832ea7e78f6380f7c64bfe767d44fcee54175e8f0ac77c2a5aa27d2039c51b8018ad565a1395237f0d8b7d356b3dd53a18f5bc13faed5ff8f39953d4715b05b6d384f5e3173a7f646ef4c36c66fdee6d6898fc2ec7bc042bebd2af94ef0d9b9365bbd2188ac867bf37f2330c5b15be4fbfa45fdf9fb6c0a9628c18b9bfaea800d49dc47b21fd9658f43ace225d7216e301c563693eebe97a5e88bbee46f006e8bdc5b6a5f135617d004f9b239bed6e35734e823973b56f25c57825391aeb9ae2e5a87132698f5ad32453844bca241e61a7aed56756d46f099e5573d207f5515abd7b4d6a54ee5bc6f93bf591381aee7d702fb659a186d3f894ea7547eceacc77342d83b473ec85b67fd173e4735c3fcdbefca95ec2b1ac5a6bb77cec92d787cf917c76c3d398e67ae4a63cbfa905750c4d0dfe95f48fde096143a64f897ea7b976a2b64389bc5f8d197f23d60dba55fa9cee87bc791d2797611c2c5327111f17d70841dd4550b3f69c7810785b5a741973bc247ff3848e13b7d12ab3cd6da7f859dbacd1bf571f31f5019c175fabc77e0fa91fe209eea2da1d6aa57593e94b20ecf460edbc637a96d3b59a52fde9f826592a77c6a3cac9eab29644959bee11be231fb2839c45a9c73e3572e06d5eb22dfe96f0c6291d1b6a770e3b821f16f2108dfec6982083638ed7b27608647fa977b5753c97d8ccdee87af0928c9349a0eae8fcb4e7f43ae501aaa6a58f190739e390fe567012d6fccca86201f35cf59b767f76803c98ca61c6ef1eeb772d46e623c7c7943eaff953bb54eeb513f0fa564e52d7a41765cacbe74cc5e0cdf360ec16f0b367aace385373dc4c9d7deb9eb33d2fffdfd0473eb283dbf9841ec9bd19a59f649a4cdb385e0b3a0baa84c2af92511ae658d1ae4c5bad1aac2497f054025a267a8a6db38fe30d9fbd9ff93b8e17c87404cd22d45e45a2425e47df8ee5b57c1e412ee227fa48246f5cce3f91b6debda7382aacf2b4e4fc9bfa59ed93b14f139e3d2a77eaba2e675ed456283cf9951beb1035b11582dfab39cf74393e4be404d137e477eabe19999b7ddab3a4fdedfac8e6df87b486ce1f38240b6394e74e31d3af9f64de9b8dccc0716b3789ce3cd54d0045e21db6a37a669819553c8da8833a4f09d2f0e799722f51d73274d179e51aed39877089bd20aeecf7311cd35ac7d1fc0cd24242f5e91dd1200ee755948c3c731d0b3b2f691c31ec9e52c5d3194b8f849dd25fcb2bf9e068c6e4ca0ee3d862608f61a70c67feedfcd21fd765fc44075c293e227a9aad8709af3f2bf79a4a8f582432e30c24a09431173927cccfc9b00e9975168389d3cd4c499f68ba9debcc6c389ade06f5c41688a7d0fc8c9ebba8018fec36d1c9a8f14b562a27ce25f5afbc70d6f483ff417dc4a4d59b6c4ca60f5be8cf03db3fd2437f04d48043b22ca2163b383b625d6117923c6d39f6149fe92819b99ef242599ae3bd6269cbefc4099bfe9602d3d053d258237a4589e3a71eb89fe721ed5fc321f90c0f39c647227c085127fa399c47329578683b7eee335f36749b37aa675b35e7d4f62b19f7c92cbc805f577dba87d631f01bd15b3ce3a87ed751fc3ea3f86ef517cfadccf13ef8c8dfad8fcc2d1b939ccf18df9bfe07f1ef66c886d43d5acd32ab4c1208caa8d35e663f36ea7e138d36564d81337c4efd714dada60c66536b8db86779d06a1b7c2467b48fdecbf405934eb2108c46c44d6532e42b89e46d14287f043e045d59075afaa5ed27d9929798fa4809b9e3747ef41e4635229a1d988e3a362b6df091a991cf638ebfd818339abfbab51efc1ed397641258ee819e48d7dc05b1b9aea356b8a3de197a08e2b2152f255fcb1dce6b9f0a70e167b31bf2bf346af089284dbdeab8ab2ba7db01f548ad668b7bba3f6aadec55c6f97bf511931699d7d87926568c4fd00ae43b862e92567467207507cf3897f132dc2592b3870a074d608df4092f57cbca71b5da7fc73f228d311a2163a37af238676051de4bdd46b53bb39060d4b373148fa6f1b31c838f6cc3430c5d26c0c57a0c71abe47d61290f72fd8cb1cdb8dee77c44de0fba5dceb8470c0fd131d6a7a423ea6a6d175ea8f331bfd0fce4997e03dc67b947a543715bd34114f7662fedefd64722b6728b87449bd85066da26a5ed5f780b4763fa81de7572dd945e6dac21131695c44711edd5e86f57540324931f2486a3cc1562bf60f3ca5c6bbf40d4b6b52d8f0cfb4ffe9807c26c498fcabd4c81aa8422661971021deccce3cccde2b596ec22c2c66975118da8eb146e63cbb231474a95001f992cccb5aa8e8279216c9486b37c6ce7b8664926c22b9bc11ca4acf7119c5d3aaf734ca617a3d7f62bf349cf09f33b52ac23e6fbbf2031a1ee14906633bfa66fd507cd4b161a778cf43e5d37b8bbca5c81a22d8789ce3b706fd4f7d5fbc46dbaa87847be3cf027ce4ce36cfda78f98b468132fb1e99c60c29af766bb3c72a4a59a3256499c7fc1bf26ab2c22fc809b8bd599b9f5a275dc4ddeb0edfb99581e19a28b520b16ba4046491c997bc22906b664a2c1fc0bf5bd5ec80f312f6ce717319b44e0a35a28aed331bac25f3c923e6b6cfbb3fb5bbdfb60aee433e79883b66bfa6ed46834e37fc11fea40007f217d2fa39e9d61db95e62fa2c360ee5019f48eb0f0338f466de19431b7df8d3f60bfe7dfab8fd8727f141f58ec3026bf014d2bf23584d7f8007f87a2d59541bf2c1e35f161dfafcbefc3c7102914d6595458c3caad65029f7c54575a7f8f28cf9b1a3a13be3b203f4ea54374103e99d4c8592415bf025658d785ac5e9feb77d1b8244ed19ff79cfae9f20e39e49a0f3e0b36ccc7bc44dbca4ad821ea7d9f08a581f0ac88b7f419eb4bd763c906745f8f63a2ef24ac9882a88d4b6c55922b7212f04bc2e7273d92e2743daa115251ef58ed38eee8977f9451cf6fbd388b96e87cea37a88f9bec977b4039d291fae0313ef7cd633fcba1c1c3e2622136afafffabfa88499feac6e76d7303b6f19d7894bfb06c84f536827a8b563d0c9d69540869b5ae137e46f43ec09c159da210d30fc9db8b7b874dbccfe499122f253c959f01f91cfc0c3c4eef608ee10aea81b03e63f391f76c98ff1fe8288267f516f2aa35ba8ce7d67e73ec6dbe6adbb4d43d331c2f9c415ea4637d7fc1185e45aa8b997931c604dfdb3e2b390a66a37cbf8bb5638f45d5ba4e5f1bf091ef6fe24baff251e2a7dcafde3b79c6fbfeae73bdca8a2d87f329ae65e584f2bba0514b9e869ceb1ef8a0f7820fe2b21f1a3e04a2a5af8caf32774cbfcde7fdb76956d8aa5aaf129ff28d532ccf6a495d01416a95d878bb7136ad7b8a5bc335a8be4d98c29ceb584705674597616fba31e21984dfcd99af7fa559b1d38b7b6791812ef29629650e38730a3a89ea43e6703643761c223a813c01fcafcc91fa4ef1d9aaa64ac46bba6ea31cd80749f7046ec12c83c822c2bc91e71703de77e0cc3876c235fbb375bbe1f988aecf9fe023ad6fba37e8d709e34939a14d47ea0c9a476d793d655a8d95f64231ada8671bd8b6848e0876b9498f0a46fb42bf47ae75ee9430826129969a52c20b237e9ef3101b45e77500d78a637303448963b20e683de4cce8b74557279ff1916d9b41f7c1b7106bac7dfb40b7635e832a759953aa26a479a3e2252344df4ca8de6106bef673fafdc2e655199a071dc79d339e578ae9435cbffe643e74db0b1ff1784fdee8f6a8f7ea4d4083bfca475c455f5c6073f4f3acf132fe94f010bb61874ccbe4770f2a3aa8d597b9e877bbc78a9ec12af9c0f4a810e97fc83714cd4a384ee86bfe3d7a35d375ae6e942e206381fb43abbf7c9fa112b3ee27c76c69c9f03a7c27b3e19cbad5693641b439ebf3b5a80e77972d23beaaaa768df64ddcf0bbc4cdc757e778ce6343f75a3487fe385b517c62de9d25105139251f4b2f4116048dd9029b9bdadd6db55bb2d5ea45b656f5ebaf3507fe96cc63b69e6d50ec173e5793ea9867bd3307bd0736302543f8fe98f9fb4ce305df713f3c5e5be15afbb8d9f321f37c13f09104efa16f3c6a3d04f25eff1beeafeedb50ab63029c11c5b197736ad0cc91eb373ce3e3234959d372b6996df1f903da31ab5ab6bd442df0ece8708cd588d8a631e757005b12f4b6c5ef015c41dff8fc87fdce76f83eea39d92ed51c1e6327abd5b5ba23dc14f41b4769780734bc278e59b5f2b26a4cb3eff42e389f1d507d3060f22b461419ffc9d36ee7233be4fbf87494f365f40d590ce78d87049ea5c6b876961d57a03bddd198f7cbc8ec45a465a59e9d8c0eb353bf27f3999d118fcb222602c8a7e0856a8cb20b3a6a3c1735fed965f4b9724cfcfa8df76885f3b1febde623b277beab613f42ae3cd0f4a6b5f6dd57efafeedd386a4fe7392fa8590bdb8e641ce9ca0685308e56fbb42b74d4e70fe8fc027478d5d5a8058d97f614354f90afa26df4738dd315d2fc03876d5706adda762c6c3e72cbf91a4afeaecd076d68b9bd838a17f04287a42f34bc93f0c7808fa855363c244c32d067d069d88c6a97ea9e8842a4da8cb68e143f1f7f3abf26ed453ba39887fa05d0b713b344d59995678e9b594ddfc63e6560c15734bd4f775ba99ad3cad486d9547990159bd214f988b00a4f53f0ed77949e9228f8b3eacba00ddc7b60e234a0c7488ea9c9a3e378c747fdcff071ca983d37d1ebf6a88f484b7cc33dd3c4b12131bd5b5823c87b086c5825d657586f11bd44e4ff6c86f412e47da046baae197e4ebef8005fc5d683b6b59bd832728169afa927a863b344fe1ae821bdc3757d4a620544af42ae5f4fd151d4451c5ed17559c4af15d9e760dd7fadbfbb9c0fb9f719e924f3348de7fbaddf9b3cd079f097e63de104675dc24deba871c82a0a97cd877e92d90dfd3e0b4bf239fd6eaeee9f55bb3e5ba0d88820f6ecabfdb6e7635d1fb1633d777dcc39a1dffa86eb8f48ada9cc0eee3f0726971afd16cbb9412cac17d40d0ca20639666bc0689e22ef8b1f426afa968fb2373ef48382e3766fa66f29b56b925746ce89d93eebdfba5d7fa17df16247b933304096149d018b6dd86fa3b6d49b17c47dc1af032b716b5af1da88a057bc278b28c6fbb9932868ecfc22db868afa7992e761cfc797c7df7837fd0eec2b7a9ebe205e387b0b7f7b2297e8eb671713a7ad45b3e257d456d091a8b5c93495bdcbdea7b3555fe918646f4b65bdec43d65b5df9e3446eda6f1c977bc30cc527d49085966ba616afcea2bb74c88735b5fa239fb7991fdbae958abecf5f10afb50b3aa0560850a8d77cd3864d2812737bc15186669c93156bab7750896c33f8434df40097f04ffb6ce7c1c4c51c3c137e15a446c91ff1a56a0efb7960e105cfccaa3e77eaa1cd4b7f5fa49cff203e2a673ddbe67dbbb26bd963c2f82bd927c288c16e101ea36b58aad55e61de9c3ef67b1d45e12666cc9c110f5c57bac9ac4cf8c4908c75c508252da7cd3951bfeffffae2bc54adcfa17fe4fb7decaeb12fab5bf94c7fe7587016994a3701ec0f2d6d4450dbe2f1a8869263ce79173a3750bee798db408f392404e8e4a473dd0cfdfb519cdfcffa19177bb6213e087825bd27b6e40a968ae11fd128d76a970caad9e72c70ac9ea88f3a36ed1eb5db8125a331afc82e17ff7cc1a209fd237f3afe769c178d8df623a11fc06f863daba6decb1f42aff374ad138d79a2aead749d5fb5b3ca59efda71abc002c66e2ae89c46f2bbdf386ef665d5eedcf9e3c615538357a222d9d7c4bc3657e78ffabf9cbbcac9242eee6c1bdfbb391fd638fd10deef269af6a72d47ba837f69f8a44d1e1113af151b0f1587afcb988ac0bdcdbe71cea3195fb66d3c575c33630ef83df07f0b5a7b8f56bfcebcb26a0d4b6e481658bacfb49b468cd535bba23cf2c0a790def06ce9db36f923bfcb47ccbc12d5dedbd983ac5af9038e4f90da31121f57e994b38db2818702be20710e8269af7e9f547df51bc6783864bfab0ffd5ef6484967c75e887793f2b69b1b737eec1810ddf612af65f3119bb67ef5fe9ece512f22b6b67760ee10c9cd5bafeba7d1df6cccf652fc758810d4d5c91c4270e3fa26eb3992dbf39078ba253c57bdcffb9553ecbef8b7e4338ff64feab6674f54638b83aeb98bcf4a7a999f4cdf10371591b5ed67c7cdc7578f26cd36e3a015cf182b9d2baba858f622e1573b895b8de7bf7474ed43c54716ce3df33dc159cbb16fe48175a897f24023e2ad329de66dc583de098ad885c7f2b93eaa4d8055a0780fe29ad77057b69a9fbf898fd4bdddf211894bbd209bc71a8a82c439597c24825b65238a5ab5a7a4d62c625413b6df769bd8d44d7cc4967fe57f648279d178b2080f618b7015769e4bc67ce4fc45ec1ec4adadc5226f1af3bab79b39f8e83c6220e0af425f6b8499827cc600070d630a3b15e703e918613366ee21ac09807869fc41b2ce94282eac8ddc98672b67f17778c9bfaf8f300d731d37d13db556ff5b68b332e579f091489e86cd438c7ae454edb9e2a1f6794f6288f0cc03a6777fa68fcc2274cba4f779c7ad4d81956ff2bab07fe02ddacfa36b0aba3e7426b74c3b04b9fb6ea5dcd37cc47336c5ccaef3915df290100b20c033436e885b7566d57bf094fa22f3bc6abb3a07d1adbb8dc6b9db745b6edbedd47a4e7199ccd6870e61b7e878e194c619283a2fd0d5eaa9d1aff14d323db81da931e9e4d57dba9c452c3cc7e623dbce4f8a6dae3fc747e4ffd8d8caafdd5bd318ac945e983b1244309af5c6df8c78ad0b2326f8d1c0a9f2a2bf973c14c43fa1ee6f8001b20bdabb2127d3edabf64e96dd35bd49f01c5f48fac37bc096e50ebcc0ff335c1afd3363cfe278499c6d6d577cc4fc5e748b02e58b061829aa7feeb0d2d0f85a29f2eb747b5e88b1c2b6b9c0d793a2ead9ee283cb754e3e26a6474efcff411e963ac8d6f2ffe119b6ed936e8dc17ef8f1a7a9a7e287aa2ebf25a1821817f21c4561f9e19fe07337ffc9e7788601fbe51dd0e48369d5fb524b01fb56fd7c410fe5dff4846fa6dc9bf920bcf7ef7ee9be4531a7a9399ef8ea343f889b32b97aa7bde137aa93be57ccabc81976bf7973e57bf3cfe1927ea8f90fb890f2cc5f45d78d892f251ca0bce6f5f3a0b7748d85cddae3fabcd027c469d9782fac9f07fe975f3aa6d7545e752e927397dfd223dae2f56f944c59df16f72464b6fd97fb1f1997e3b3eff17f84776757fb5eaa72fc8800d7902a4a47e4cfe88f090585caa18fd05bf73e7de6e6b869bf9d3f63d1953a57d1e2339c6f87fc03bdc05bd07f2f7e18fa04aac5e7c3d4133ff6517fac8b673643ec71c4bd14984df18b88df556390b9cc9e9947fcb3cdc5d1af73563b04d5c813f9d8f753ef2fdfa48485b7e075f6bdba3a76965116fd47e4d7781dd889852ac1e77b5d93fb275de38f2334aad828edd7a60dff5b63613db7f1095df858fb8119ae7211fbc9b685d99b50837e7b343ba6c2cdd64d9e1dc11e005df301f79d67e88a2a2bd2d57af285d276411d8e4a6413ecff7cebb39df266dcfd0fb3a35d431738a15485959ae05537016f5c3e5e37cea14dfeb9dcbe1d8a7586bc53b600168649d993f34c633ce96b5adbefbf7e7b3ef8a2e2bdad9ef52541ffc22b1f9ec25c33f525a6fc1ef0dfd05f15b880fd2f9e9362dfcca98d8f6f874f82e33a020f9466ee186a6f5ab1b450dd264d3c2e7aef009f1419c517e466d62f45b9eb52bffc857c641f23d61db3aa1237cf4ed09e597a0924695e3b70403d3cda0a29d17ad1960fa84be321feb7c641f3cc4dcab9b68eb9f1e53864f56ad0e17f81a39f69dc7e5839b7c246697d83e7ad88f5c1718c3865c8d77996f89d911c7334d7d44f0ee83715112c6312152e8a8934f781d76fcfb7d73d19a7841c463fd387886eb622ca0d5e747358da39f336c3fd31dfa47b67dffa83e44e309abed9de3d6b0faaf563769d493bc74afdb45c2c007d2d272e4507ec899b368568124d8b91b25992786b6b428affa5d19e7e7f2d9f7a18ff0ffb097b805da2541ac6c4c3e7b8826647c6f1fd972dcfbc5b88ec2af4c5af5a734d8967f2dfed463bde9231e12485b979c15c0b997a941782ff03fe497b88a0e37c41e9733faff19deef77af0b7936d74549295dca55e3ed2a3ee2726d60bc17fe7718771eef94e638b08e6d63b4df655b9ef26feb231927e44b39a7582f396eab4015aae1d388f292187de4de3a9ab4fa9122e95df881cffcb1c6880af587108beb2bfac84a9fa77b6a4c4a2515f9443fd7305d628e5a1a7b619bd635495a33baff227598b972d58e1f43377ba89c683afc6ae83ff31df947b69dff4c4c7b55ad46b83689a1fbd87e025f9c3d0a4e9a605b767e75ae5df5ddbca1c6a64eb1d17dd8b2e6fc3eb66ded7778c9ff863e82e6b1cdfc8272d351a3bc6fd3625b1fc1b9a7f8b82e91f75b8c798e7b0798b542a3fe9406dbf2afc19b10cf54166c932df888f873504d0d357375de0be35ac1a73d3ca61a523a46c0c60fdb873eb229ef869bf8d0578efbdc7927ea00de01fd4a5799636ccb3eaac72a0914f9a2f8dcbc25c97a2dd6c1d6effe643ea27ce4ffba3e92e5fc01dc53e38b00270bd1d76e71d9617fc947fac8a31d5b1bdd51ddd3f640e3d6e6743eb5590f2bd42376a58f68daa7a422442a16ad78ad8d47c2d5d2117ed7fd47f7057a92e2790f949584e847f0191d6b9675421d809e97f8b6f9b6f50f9b8fc8fb02b7d17766ee6b37051c159db5c05553096793e647c761ab559c4eb96fba0a1e223fcfd2e5d68313ea87612d99a8adf03f7d24ae71ae9a5bfa5c1f89d45167db166647cbf76ab6122b6fbd46c92ef511532ec77d9f2997705bcc78f41748df8b33aaefa57dd8afc48f705e6bf64d2f5a7b446c5b4f5f7887afac05f169708d46a0c9428faa705d7bbb663de2d1b47e891de487d82ffe01c7a7e5ac67fc2e2ff9b7f511933e1d18fc448d4ef362d92a9f7ca48f6cb069315615ceb907e55e50274b9e65dae03fe389bfeb1f51f4b0fdeabfea4a719b70b5acfa23a0a98da253740f518f50cdec0beeafa413c63df67ff959f7886bd51a7dd6388ddfad8fd8fe9014e7449e39b3660eb8ff6a77e45b05f718b995a4176287e85df2e8df9a989315a9d51b447656bca5d213db41053fc39f4fe3bc88ccd5ffb63e62c7cea25d9056b7b57f84b5747d7c269a063ce096600d4afda63ff5e5dafdb5f347e47ecf843e8ae8ef4f717fb9efef4a4e0f560a631a8236030b11abaa65faa2f7ad8fd8efcd3924c8515fa25a7599f4284dcd9ebda00e7180812fd804e7eb3c063106a92b9219024c619387fc4e0ec9bfab8f08a6de2b1f8536237e4bc9a6dd974ff411d31fc21183b01521a210928aaba322f89e1ed3a53963a5d8b6943fd14732d6ef804938571aac2ff5143fe625c86f41de8cae52f04cef9ff451933173d5e3ace471ce1f374e0dff8ec8ddf33dea2399e0fddce989e3baa76e71ac28106ab94f8e29eb18e31ee4849648c2ea1b7e2c1d775032e6eb8d28d952ddd33d631f5954dfdaaebefbbfaf8fc4c5b3b25c9f2a7cae8f04fc43eaa31f52be34ea082ee03f105fae8909181707f53bcd967f4dfdc6a3d8d8f7c616fa086335f62f39bf0ff7e0dcbd296bb6a34bc67689ab1bb24fff88cc0ff0fd536473838517fa45e7c49817838f5095552fc06f0e6221e433f052506de9867cf36b6be03f7d2467b4687cb1d64760050536f9a7f15a467d7444762076b655e8dfb7d4b58ce7a171d1959c1fcab9730363fe2bfa88e92316591abad408b9889fd71f1129e41d517fcf0ec51d3c386ed72d0ffc1cf9113a3a2a9df511799ec9d7bf7bdee5bdf859ee7962914cb3ff0abe0f919e1c89c11649cbbfa55d52abea9d125007fa9df60ddd9394863a98a3b1c1477e27aeeedfd747e26805e8c205d1aa4ffd236f5e18430b6b2fec2c52afd7ac8928b8bfa69f7a57fe1193ce624523e7714b7d04ef83b8a6a07e0ae7f0019f1d3c7188efccfc49539fda873e62f178d8a1908b831d52ab729c00ef927625baf38379c2ce79e27ca0378ac513bf092cdbb8befdee45716bfed3476c7997e28fe8dc0be528241805c8d64702dc78eb3cbc52493573ae46a4d1f4b8a835e01b43960f7de2a1cffa2bfa88c41be5023ea8e3c01aa7992bf803627987f1193b64e1ad8eda23e613afea5a17f7ada792a0af47f586ae494fb53dc2da9339633ef631ff86ad69de280f3a29aa0a81958ff9181cdb39978c85263ce691b06a82df3d528c81447d425e40d5711d4b20e3fe3bbef67f5b1f3179099e05ba9923f954631e5a762b9d3f724047b1bbe33bf8e4878a36e9b8a038fa13476f7719af65de4bad8624accf82b3f5e405182d1541b6f06887b817949bb7c6ef142faa2dd95f62c41447fab1affc11f31d117ff518f284a0b6704cfc9cde45bc73345a600c768dde290e61567666d6b37e878fd8328e9619fe097d242a5f8718b0cfce625c37d0e6c4a77e4fe8d2fafc93926b79c435d646a9f91cf8d4cd5cb5aff6ef33f9375a339d72f72ecabdfe15ef88a7505f82dfa67c49ef31440dc5b7d5d1424b7f1a6b8478e9ab3fd6fa538af2c0b90f8b4037907eed025febb36348cbc5a6e6d64ba97c73caabdbc01788f0f6c770bef44e30eac5c4c5726397745f17b544819ff5ea8476ad4db1c7618e66888b62d92aff117d248e97a4c896d3b63d854ca3ccfa23e32ac9c5dd21d5fff892dfe377c6a46ef4dbe6231ef96546092f5adfdda8cd8b2a37e07d885cd1bcc2acbbf5ea45eba4d8788de67cec2b5e4b9e8de8ff25c591e9fc97ebf01820249dd16713057c936f48ff9eadf53ddf7896f9eccfe6e2dfd647e4dea6dcabe5eecee5ace605bee8d0f354f1c4ae85363f22090c79e1ee65e544c9ee517bfe2edefb237dc4a46538deb0fd2c4d96035df3a96e68ae1ca38c1d32eb79939cd3bead971cf25f670d5b5b4adf2bc4f80d63a3d7e7e3bbe79d9ecbbc52adbc3baa182a3e73c1cd948a75828ea473f44dcc1ab1411abb446a276bf9e0dc59d40f780ca61b7888bdfe8487cb7c98fd9e3b8b7f501f91868ace6a16de575ed46f6b5a4c2f429a8511465476e0538fa3b9bb6ca63e62d359f9fe9978046c36366e98ae3baffa9fbae738e185b7ce2b74748617e67ca7bca8dd47e6631ffa8869db82dded9c6d8ecf848f1f8973f0580a3b33ea429afcc30bf5333b9eab6adb1b7f175f6b4d2ffca7f4919c611757e706e5fe7d2b6bd42d37685180af75ef05d8f2bdc5f8265130f2da4c1de13bf591d0176cd44ed7582fb3e989e213098e123f8cee12e8537ebdf7043f0ae5b27814a725b570a96e6e584737c5bc66dffa4894e733afa4f805d4a3d73cfe5d7881d20f5fbca04e4cf745bc8a060e9ae82166acf6a37f0bed7ed6e925344f7d0d702add98715fef5734ee21e4bb773fc247be531f319fa3e847b2cef5482c395673f233d6d26f49cacaf9ee73aeecadc7f77e178db5f511fb99ac17c1df9eab90fe14d871cea9ffb92ac529e95a1d292f8a8f6bf22bb9b7f9bf391ffbf28f98ff3f938fc4f49deb0a431764cbd398fd77142fa7d15acf42bdccae0520d837d85543aea7f847f3578be9efbfa18f84be54c32ee44d9aeef2b16bacac00978ae55f1dfba3f8484e8d4caedecbe41a0ee532d834fdab3c6f1b7d24d4a75ca92dab3fabfecc1ba31bf8fd358d7d23c90499b9fd9b6675a9add4e039de2488e9255f3ad1c267a3b6498a6397f7ad8f649ce83890bd6dd67ae839dd9a17d6393ea29880de7dc5eb1ff9e3f7e2e0763eed0fa639ff28c77a99d4b08c48676cfdc5795d01c3ce97b779c8a6f9583a89006bd8e025ff983e62d160f8a93b134bd67da3ea36429b746dd7ae1af52b2fea53ff4e1e22f4bdeaadc710dbcfe5cc5d8901061236fe06238e4fb2f946ccf59fcec7bee37e313f67403822dc01cd23de28f61775787b8c2fa6e3e49e292726d7422e65b6895d02fb5580c3cc1218e2bd1609e2bb1b799834d3ce277371c635860b9ec583fe297d44e83ee590b8ab9ee3fa81cddda8057540d535736d8a5c443460aee3b8e585c6748ae61fc4c4ef7c833eb24e73c3fcc4595bc9d653b59a4073735d3f9b7e7366bdeef42d072caa0cd795cd84bf0f9e638fb34d43f7a58fc8fb0bbf7c205e594b273a03c79bacd42e1f9cd7cf5b8aff0309dc45e5bdc700ab51eb6bcde1aa9df995ebe7de590fbb09299fced57c01d57016c92b7ec69d919b6abf7f8a632772cea22675be701ef529cfd6b16efe417d24c3f9d18afee406965fe12dc4fb5da088d890ec20c3b2119bb50f1e22cfb0f3d9e3fe4f11fe6ded063b99f40fb420c6d7eeeb36fddeb73e22cde269b911d571472d4b603106f10d76cc849aafb4a26a5db54372639692bdd006066d7de13396a3e0fddab93246d3eb43edaa1ce344a301735ed7503eb17fff8fe92342ff35b608326cfd0bd3274bda3ab8726e0a8d30371b76298aa30a9ca613aa8711a1c5bbeadf67fa88795e9e2f7c21a5e99dae6fa577067040607b2b10b67af0dbe907cf33e5f19fd447f0fc2ccf91a2d958d5f0f466150faf69d43ccd3f8a814e059900317359f5ee4ff5457bb83aeafe2209193112e29747fd329dc5807191dc1e53b688be3fe2f0502f3299a3dfbbba7664ba7a077b5ba49ee2bfa78f1874b5c5f13b9a137ba1dc0a4e8d6c1e2db92c58a63fa1a6e98b1dcff45d3ef74df9ec71b4ef818f268d145c5cef8331dfc41ff6ad8fd8be8a9217c404e85d7f66bc5b4c5e3ae605fe1ffc76a6f8480e3efa8710a312b114b995757d5cec82b4173afac3c47dfd857518257754efe2e6fb9fd047e47e62db56f427d15fb573498e6b327cb33aef1b517e8a76e5d408642eb5fc099a463ee91b431edd959cfe793e7b48efe6fc7f385eb320b72ec77ef46b67a6eb35a53486fac2e01d8233b508c62263f5e327f411b30f78fe0bf311ec8a39e98039c2472972bfc9fec6b92eed16d52f211d862a5a03a1afcf3829e315b2192ad7ad14df57c623942b22362d8d48eb117e7df5b93ecd659c62eda6f5aa74986aa40e16cfdb3fa28fa4d79f05ac586dd3923a828f64e91da8e7232a7baef847aac7f4ccf4437b1beefb1d6362e3fd7ec4031eaccf422f4f365cb72d1ff96e7dc4ec47cc3cc97b04d86585e8f9604e72e1717ac178c86a4cdad02bb21cafa63e277defe3bc918cf11c60402a6a39468d328cc393d54fddf77f421f11fa2434589d4b0cfa83729d6d5986e5b7a334c3f7b7f203b4bf453fa8ed4af43927ba8c4187b6c961fbaa3e62f29118fbbcbe3e1b609ad0779e81f115de5778d13a1ff9597dc4cc2f9f39e203ba09f8c522877c97824375800b016e3c5d23c71ce33a2b9e8f7a243d64528fca0354481da1424f100fe684b10ba6adcf9c07fcf64e3d57edb877c4c30d9d59d775ba465e4dc087fe217dc47a564b4954a850dc3f0f7dea65458772c01a872f5664e07dfa06ccf651fd914de73e3a1ff7dddfa68f989ffff499a28f315e41fd80751abb4ea5c9471e8ce7caefb84e7cb54cf57e35a67e22aedfff843e62d34e4563d323ff7501db4789f1a7a0d55d39ee60dcb8a8979cc5a4ca7159991df7e34ff4915df3d48ffaf153fac84747d5ca73f6876ce2c1260f446d441cef9cae3baa8f12d3c9236abfb3cee2aefdfe81f349b35e80ac048c824ebbdece5dafda9d337f5cbd57bfbbd5f3b1165bf18fe923429f148dce15c20a378809d5987e152f94553fb09fefa5d9fe917d3fdb9c8f9f1a832f34e81435a53f34d4dcb6525e68ebb3df53f48f07b28da1417799abb590030af76db816b47f646d2cfe097d241aafe522f6d59ffae34a92f3a1b90e49a294fbd5d33bc499e56e8d9a7bfb78ef4d3c7553fcd0f78d7ffc7cfc140fe163c04736f16033275474b14367b1b8f326cd42eeae8add21ba5c78bd81b7e68f1db6a575d4ceea29ca99bbaf8e3a4567d1043ef454eb3f4dad27e1fa69f8dc7f441f11de207ce4816a76b72fc2ac9db6fadd08f4c4f6a3fe0dfac8bedb4fc66beda219b50f1bb04d9e1975776dbd44d64421f4b134d47a484f152f01e6d8b3715dec7cfc13fa888da1f4ea2c205fa6ea946105df7af250697737ce42db3f941ea2f5911b87f8c83ede7b134ffd4f1f89f2918f787024de8a63ac4e1de8118a0750be8d3fa4638467aa63a54b7e91eeb259ccc172f35099e51e956c01ec8202f39a17e7d1096d83c1f3ff317d841be845b247b1b2e021d821c3438eed35f3f1ecbeedb3fda78ffc597fa5f1fc21ce2a32a7361f91f35cab17b98fb907b21c4bad48e135895f71cffa27f4918c139557e74e32f7d4b9ae5f867986c977606639ae3f6479151c9a7098fed3477e9287f0f1537d24daff20c6c01fb28d8b7eafe3b002bf888cabae214c3ba476e6cf66955ad2d799cd0ec52be4187bac60f0d469f8dc7f401f89c997489cf4968b4418a785789e865993dca043ffe9233f3806fb784fd3c78f3570e105751523fef8b8f9f897fc23141f3a15ffacd24366e9a4e03322a36afcd8eb346a4c2fd435938a41b7f6f1de9b78ea7ffa48948f7cc4836d3d23ee7cf4fb68ac0263346bccca2856251d250fd1cc47cafd13fa884d2bd284279be6a86920cba03e928eed34ede73fcd47fed347f6f39e968cb1969f62feb61c374eff843ef2ca7c84730650c7a93f55bbe48122a7c7adee0cd56a225853d0474c3ffb77bff7269efa9f3e12e523dbf2e06ddf338a8d12d6434ec7fcfe96f9483a7addbfa98fe85ce9996a8a77248a542f49cb9f8ca71eb17ffca78ffcdfe623196f7d0d7cb446ecd86333fef8df8ed74a87adbc70dcc6d1f83507741a441d289ed275f1c69cb7b75274a417f847f6f3de9b78ea7ffa48948f6ce209f67a89d33be2de378c050fe3b0e439d3e03bfa0c7d24b5fe9c7f401f316983d085176f929d7b93e6ab3769e57b4bf8dcd7f2d20adee7f4e7bbc7e43f7de4cffbfd3bbffbe8b3996f538b39f76fe823c29784a6bceae32251cd15732fd3d79cfa9cea391a1b70a35d6bdfb473dffac8265a3cfd0d7d64d338c5db9462797c6c9b1bf31167a3dad696b5e977c21b24363cc4f334df6b1def97afdf131f31f7a68d05b24b1a26f7132c8d7eee2d575a9647ea9999f9e830a8c361d6a1dad7bbdb72f3c6f8a03df4c33cf727fac8363a80d9d29fb4b87512778f5daf45f37f733e22efb7177d84ec0982bf5a8dd0a45dd170eb5e95aef6a92f9c436fb2b8f7c783e9f4a576ee4da627d4974935a02fdf1faf15f7ae391e8b9b6f7eaecd4332d67ccc793e3e93ff3f6ae94faecb399ff111b79675a44e58886b66df3fee39dbb68fd7e7fa7c18ed07f848c23ab72b3e62ee7dd8ae047391f349847f44b04ff0ddeb8e9eff27b4775ffac8261a5cf0d66d399fd1dd8fee6f1fbf3a3e9fdd3f0e2739ae6ddb071b5f20aa8f7c6713ba40b42161d0ce306f7b17cf90fb119ec6c2996247705e34e151cd025ae5732ef5ae9ebf5dff84362d1cc2fe48e87eeee3f9664bb15c4e7439b1c535ae930bc6c9b53e7f7eadd895e0c33a303e1b3c23f18be72615fbaced9eb1f9f8f9dc6434ae6342c76ad0b9c056b6473e2234bd669cfb2e3e62da25848720be53fcecc23b3ec2a7da65db44d7f6a58fc4f90784cfc6e98776cbc5b46de9b6f06af3fb57eb9cdcd3fbe4de329771facc2ef84822e65ec4473eb211ece29873423e329dd4024c41913977f11c537e159ca502d3cbb937d1f8afb06b31fd1ab9ba0f6e70ed77beff7aff088f65ea3c46e283be729c7ff27d38ce8b00434cb798f9b05bc87336dbe0ccdfcaefa7ceba7fc2e6216c5fd2f391fa603ee2d689f8cb53cefa18c7f57fd311bf09e76311b94f68d7aa334dfba6a38ecbc767c543b21d3a7ef7f3c66ffc19b4019127496f32c93236782d7780dfe9fce5c4f7bfbf7d1cb9f45c3d16fb787e2d7ad4cf97cfc8c52b73b37ee70cb995ad368cbfefda519eff44c7dca1f159dd6752e5cfe5d1a1be6f8fc7e3b3fbd6a2f7ddf8dc9dcc47c047beb3493dd71b4d337ee9bd3a75ecfa4a7fdad6ef930dce1166df52c779528dc4953aa23ec915d32d9386eeb369baa569f82ec661113b0ed2a64633e7e380e763a5c76511cc8b34397fcb2dee73f41a798ed9171d67abeb6931edc7ff89778d4d4271daf8fd95be1fd58eb1fbf13b2d1573fd67e317f0119e0f6b3dec511f9156dbf3f34406377118cdfab33fd9be4b1f11d95d3ec3ce2735dbf199f16ea1134c32c6351fe914e66f1eaccf252fd42f1e8c67caf566bd0f23177dad0e88cc8f3caf64dc4b9add17f319f67bffee1cc7cec75ef411910989c654bf4d1f91fbadd9c63dc2f04b132fc9a837af293ed238c20830c6ec3ef49175fa5edd993e62ea09e633d4e796faae76caf9dec0474f219b591db102b34e2b66ccc42624f741ec82db701db1c949bd5ed2f93cc64fd4bf57cfb171267306e662ced04b3cc12c718a895f6cd3421e21304c80095cd2f7c5ef8bfadc837e0737d2cf8cbe6611fc6fea34264fd86e7d561d5b2fdb1f1f31f7fb77d1ce8f9a4779cfbaf6ecb3e2f2854a6388aacd477f406b763926dfc5534dbf109f13ecf5488c81c7f361fe3e8e87487b357e2778569ef13b7e4e10cb20cfc26f042b1ebce0c50bf99ac9df6c9e224d303553deba5dcd7c5fab2fbb990fcd47be9b86466d1ee4cb34cfefeafe9b1ae53ecf5c20d31d7b9376d39ba4ef1d1788d8b913835e7ef7fbafdb7faa3b7b8e69634a05e7d9b6571e807fd450c1065538dfe9e800d5756ac41edb4deef76abc8760ecdf514e9fbebfde09541fa5a69ed938f526f512ea510287c699e54e9d59e59c7503d4b03ad07e2b578dbdb62d02b364f2c67d422b305fba56d7afd05ff5ff9d33ab3eaa6bcff89969ddbfa2e6451e788c8ee9e6cf06afd9767e36f191fdf947cc7dfd9df15a9b1ad7df1bbef496fd43aabbd7291a74edbb9fbf694cbe93a70aad9723ea442187e69c723257334fd3786dd3d914476563b7e33ec027bba07ba09e16723e751cdc05e1ceb4d52a5f287e93529f9b556a99153fff84efa1be6b1c7a411e8fc6eb4d7bd13c73ce3dc7fd076d45cdb836a27e96fc26e5ade3fd7fa4577d3417f67c04d7ee297fc4dcd7df1fafb54eb315ed5bcd50d76adc2244a1dcb9b6abcc02f9f67bdf3fae8571a6a92fdedfbe5ee20c966a8697541f0ab862ee69bd302bad8e926ffe78f15a3f71af501b2a51019d0606b234e796ae635a4df7d2fa1c300ea72fd54ee524f1d09bf51c7f3c2865ae528a2f2d2f3ad7ed66eea28dca487d6f922cf7d3be925c062fa8ff8b4a16ed66baa2aecf75ae474da73877da83fa75ee32a9eedd56fc67be6a36862ffe6c39ca5ce53afeec7da8cecd12d7d3c3cea59bf5c733c597f24ef57579df4dccd5ee9caa3e76516de94ae94935d5c7bce653517dc4aebff2f1fc84f361cdd51ef988eccbaaf1ffaef8c86736995ceea0adf491b6da2503458fbaf7444ff5f7a51d3cff77fb27ed9be2b5829834b467aac5b268d07b57d5731b8a6e27d4f9016ab068fdccd3345bd713b469b9e814fc1bf08e7c82eba6abfb75d4774bb51b3b2375ee95723fbbeabbd63b654a0367f9fd9e6a8a2dd54e4d28a92aa3fa9044ec1cf0aeb26a17299ee62bea95f7e9fbd6b56aea5cb94535ab50d955675eabf19aaabe0f81483a57f7549f07d78cb175eaadd79fdf767dd9f31199a7adf247c4bfba0b9aba8bfc914d74d98c199d925d5ed345c5fddfdbe01ffe6d7346d5def2657fd65d8acd24e67d455e35db2e789adc1f72ef92e3833e9297c5576de659cb3bce49c6877e01f91fefaa7d11f83c2cf7564e6252bb290fc66ac5fa07b4a2a58e208e7a45ab7bcf9d7e37a9f483b9e3bfce1dc76dcf6ac979da7151d7a3bb22bd42eb18cdf14d4fe90eef73e2c5bab6cb4b58331d3866bd0342fdd3750a0fa4a67178ae7c48b899a8af2e0d5593f215c2d49cab1d5551bca8a2ee39e8d2fd9a33d5df17f4bde26994f30455aaeea27a2a106b07b3d9cc4dccdab7f5c568599fe7abce0ce3c17acc624d5fcb396b3a4720e384e783f5c47c242efec53cc67d6fda2d64cf6dcaed33aed3bed6b8fb9af625d35e21f7f7bce8feb63f9bf691025502eda132a81ac9e1886850e5996676a4662c5f633bcf677d8e1b179b1f70ac518039cb36a0866bdd9beb6640feae2b1a39e11a1891e79a74fbcca0e7f85f72f1a51fa0e9eabd7ab754d7a9c7efdd519420df209a8c9a5d159f28435063f88d57af3adf2fabff517de2803e830780e6af147d7f573b093b2cdf54b43f4fbc02558ef47d9ed4fbded278e233ee27f7b78f664d6354bab08fe553e37afb7ef77cbd755eefb8537a2ff0aee12df1b486da612d5826d4580d212b9c5bebe9848f2f3c9e9e319ea28fc4f3915c402f176bb4739d9eba6cf3261f6681fdbc520f358cbd25db834993898f446331e999e135b2d7f52a7150636ac6b6787daf6a9f6df399a0feea4cff4f75cadd4caa72517eec5ce6d52a6c4e2b5e6b4e68a6ef638c3461c8f7665cc735cc5958ab9bb7b14569901be903f555eaf2119f52ef50eb693a3f6bab9db380c4703e9be5dbf94ef7bcdc7d7faf2fe66a6652a3cac9cae9e67be9faa2f3d09eceaae5c1fbb473d97cac9cf4c00be6f50534dd66c11f27c7ab76beed8f51b939afe86dbe47727f67b19c244f99221c50fd47da15525b385a63b87c34e8e1a8cf3f1a752351031d55d592cb650f3b51e918c363ba26a82ff91877dfdf3dd22e19bc1bf5c6fee03ea87ba9778d43bb1c481f8d5faadfefb383a6e2afd05d6a73e82fcc5fa06fa5746d7b93b75783dcc4104bc5e42326efb0f7529c0c67c66aa60c3a9ae1a3d8416c9adbdc702ff3c8f7d4368c336ea75e886772e685f69a94d10ffefc3e181dced5b37a6a16cbaf542514dc5eea790fd40aca5e311db16352ed7e65ac71896b621b337dc469ea3f6c3da0f1dd1b929ffb905ace8926bf9788d6a3c6ef44d1695f7db7043ed81dd1764813a0916dc5474625da052d753fac5afce1bd502318f23ef42cff9c7e8755a2df7360ae3aab79448b27237b758634ba794bf7c373c063b0434c5ea4af2b7df08c6d5ac9b86fc9baff96d7077d609ea36b961d53e571e84dbd5f34d618f756827977c15b5bcb938ab50f343fd77cc48e595a97f36db92d3c9fd27e56b69307f770f99cab6b9e9bf13ca5c9732487e0d571993785f56caf81efed8ff383c4ace3555f1bb97a01752260cbc8a895ee1e414e56fce4499d3b51d73d33bfb9a3d61cd54f06155a79ed34c9b77a87bcf9b7b51a8d647ee868fb4fd267ffb0f9bea12dcefde0fdc3ffb38ed4c470a5566c52ad64c8f3ab97f14d7e44abbefb4cab0d2bba7c8236e8a17f22ab3756520942d14648858ffeadac72fc062bc9ffc5ed9ade07bb9ef8a392e52f58967748121a0c6ad528ad8fd268fddca3c130e00dc24b9e154dbe0c6932faaaeff9c2ab50ee07fa7fbc035ea2ee337c64a9ebfccfaea75d22bc508dcb13c6407dd67da6f7812e8335911f67aef29384ef98f92924232422f202d779dfd2ae15679391f3c24fcc7d29745ee46a693837dcf00c432e6c29da9e6f931f630a4e3fed389922d9617a5da2cb3e6650ad8aae7afb461dab51ad16c5a312eabb8a4bb616d062ade5496d5d8ce833d974741fc1435e36bcdf261bd9a6ef3cae6da1fa38573c61a5e8ae7b473619d4636c4127b8a095a76d3d6a65778ea95fa8d98886ff753df937e6797ccccfe83aacc8619d6c46f939d1dcc14928b7bf8f425a2ad7f7cfc3dd61d368f42b8e8f681e7349fdd5dab868e86fc65176c857f9084b7d5fe2494655589115deb3a1be84392f4b5dcc73c65bb3f560531f8934f68face786a11d382606d1faf7a297202f43f18c1adb929a6a266a8abec22692af2626f5e3ca49f3b17eb2784d74eac7f5557e41951ed1dc73aa0101fb7d17b6fc1459223b1763b7a3becf2fc98601cb1f68311a248eda5b3fed1f38453feb67a16ff4b2f955efd871df1bf80eb85af383acda551dd040754c1e54bc60b5a8d5d6873f173cf0c0d03f4c39d46c531e0be133af4e14cf29ad7dc0b3761fb5c3d3dd91479a32e87df93ca4e19a462a391eab9acee5937ae59f100dd4c712fd7e70429fdb15ff96760ff51f3b032b33dc5554ef51ff7f4ff7c7fbd60ee9fcf034ca3b36eb23e1efaa59be97b92b1e896789beb22e69fdac3e621e032a23fdbea777d576bc553e35ba72dce60dfb7c0a2cdfcc9da89fddb071321ff98c86dae7cc3df84cbed099a2754b456f6655427d833e3050ab66f440bd835cdb9c926c08991a0d16495fcdc88c790378809b255b0af800e4c9f113bd2d6880b6b7b32d0335aa348d2e91f531387fce92cc19af4aa1a93ca3b036ae44d711fe67dbac3ee3a5396b1c8026a1ee0b1fbe7efe79947605f4edd15805f08aa5bd807780c6d70ee3e571b1e500bb18bf89ac268bfe6ae94c2417e703da6cea2371df3f7a6bfd2e9fc7dfe74b7ce4abfa88f4d51c0b93c7b10497b9e82df319d645326c737cb5e6f62d6e1f047e76d3266cfa09c42e6f606ec3f60c3b817b5e4f65faf542db4bccf36a65e7ddf762ab4b741e9638c8ded51cf550ece7e5c3c1102b19964669d048f17bd8667a6a97b46bfe512691cfe595c402db4ce549c9d5d8292c2743bed4e70fc8deae3ff3f7d0d6f477daca4b3424a081588dd07093fe71e7a6fababca01aed8901d93a8c1c87a8be61dada44767da66b14bf5c2c5ebb37d0c4810989f79c1db33cfcccb3f448bbbcd60c79048eb5c6682e2b582ad2c5d2e647ae33ffcc7a8a4133710deea7774f839ff564c8e936cd363e933e32f46c5a2cfd0b6d57f67de47b1ed79fd647827e84bb431a3e634d8c0bed615e51e54c8af3541eb44dcb357886bb2906c4f28f98f6f9e7b041c6467c4e0236168ff844fe9a6d2c25a69d6f7c3c229a8ed522766c99797cc668986f10d8c79907689b8c69cf37e9af671cef43da13274f4766d7b3eea3ee9f47dddd36d99adc2bf21f07ef1ce727326a82cb780c5fc85ea5dffbc0b2f39736f42d46c2b0edfe7147d34f10797fa1a3f2ac4796c34d199d9fb9511f89e9dbdae7b8f7b179e31fb62feb2396ff25721f354ec90449f55a07b5f55f23966062c6fd06f38f3d02db3d68e2a04c713dd527c7d5b130b9ca49329bb9eadd341bed666fba9ce46f206bf72e487ad2924f82f6e9fc8269f93dd3bc0db607ff9a69a749e3c426c13270b0ab3ea255b65cbc89d6c97dc546f448b60e78ceb42f173e5e25fd3516e96ee2b23f404c11ec67da8e3ea0463e6cf239b79c7a2a39aebeb612cd2a78e6f48e76b3f082d8d564cf3cbf63f97c4836fdf3e8f591e39b415befd78f7ec1a0f5a66d4776e19a6d6b5d1fd96e3cedf7326c485fe12116b5f8701e3f9adfe0685c2ffa93d3afb6eeba09e8baa95ef5ae71515f941fabafab4262965773ed2a89b4a63405a5a3741b4712ab10d42961bb563343b6a1740b9535158d54aba7a7686d2e4976fcde3dd999612f07cdd4d6d433da1d364d5ba3a146837c0c3e62fa6423ed31a409b1b4ec23fa65cbe506af0af412ee9f5ed53ef7234316e25197fc1379b5ea1b4aca6b252966b5b5245e01bb9a12962633f85d94fed07ba0880c6d5b3af6d67786c9f32c5e213c1634fcb7e56ffbbdbde8fb06beeb33de09b71bee63ea23969eb471a76fe2275f695fd547ccf567f058fddecc5331bfbd278a1b802f1e5139d08ff3f7142fd65414b3aac621c536afbc4747c42c38e7d8230da5455495bee1677bc7a91c623669b5688d986de3819c8ff6423e4d6d773ef7368fa0b93b5827f1af873ae646df4ff4085bae3469da8734ec031b8bf17bfddc42785eaf0cd87b947c3f3f227f84f63ab1b68f11852e857a8af0e2e958e13a35f16fe07ef30bff76766c3c3f8e863d867d90a3f00ebf309a073cc2fc7d1cadfd8006cb7bf50e3d6bdc797cd7c6f3637d2476bc3fdc413fac8fbc7996655a64071ecf22cd29641fc83db95a68eb42c37c4263984dfca37cc159f4677eb63f7366d574a33877441f014dd4deac63f2dbc2670b8f16ecedb0e36b1a78493615cda1cfd8ce7f465af087b4a6e405344bd3dcf7d08e2f7b7d4d76fe8c86f1c8c4ca9fe6bdc41e736ae93feca7c0f307bcca250a4ff348f60b68df7581c645dbca4ec3f78ee8099be8bdcdef2c7da2f2f0c1f55b501e737c3f1c0773bc8cfbafe923dbe879f6f73be0275fd54736c58999f162b26e4dff8e5c8f6a808843cb3f504cb4d846493fc61ea1f84dc86d6c5934f766408348eec48ec1eac0ce88ec8e8f6696ef45b69b418fbc52c65edf441b2c5a134bbb6cde12acd0284f32bd5de8c740bd67fe91fc0ada1ef4c636a37bbeef7dd8e49dc5eea4479bffafd56dfd28466f7ab48ec1f7f3927ec6672be323e967edf7162ffa607c491f11db5a8c7c1f370fa6dc6ff3ce3f3a7a5fd74762fb698cd53dcd6be037e1dfe9cf6c33a43886c1d0bf086524997fe2239af3f35ed6fca2492d79109d01b1e347f48688c6f8f14ce339c255833d1ec31b02fde129469e8eb36d99e7ed26b4dc7886c423e9880d5b5a8a93cd0daa1119e992419b6c3dea33ba68af8c8f7e6bdedf6ef6f98ffa6f5d1789d72a19f78b7b9ecd033f9aebdf69a51dc66b6dfafe39bcbf50765306d05e53752eff443243f47acd470cfa44fe5bf2f16235c867cd5f1ea3b451dbd137d99ce2e4eb12e9239b24a735f972d37db6a695cc430686ed855790d647021abee93e3caa4dbe5e6c381be4fb753dc1babf79d4ef1e43c3b7399ae3f2e4ad8fcb9a8d2afe3e14c3c4f31177ff381afdd9bcfcc97117fa88fdfe46bf484e083f4bd44f649dbd212661346f2fac3559123eb2339af0c97ec7de5d8d7ff3ba1dd8dfe36c60b13ee33d363c7f75e77d4c03bfb989bfea27c741e623b26a7f683e8696bc414df311fddf1769c14747e639e0a8b5fa7cf4edcffbf0482dffccff7fc283beeb081e5dbe9c97b45eb6c7f70e69ad7fab75aa839f9e0f3ae69f7ff0f9180fac878321c57158dfef918f987b754fcfdbd8fe44eedd71131afe23fdb8ff6f3eb69e0f2fe423dfd938ceaa14fa47227e95bd8d4425f48f8c423fc5be6723c8edbe1ccdc96fb38716d1fd581f3967ff489cad6c1b4bc2aec60373f0b0613ef6b43e3896b0277e2cf33cf1916de285be720c7a7116fa96bff3799f1dc9eac97e929fea87436361c6b5edeba8fd0585bf673e341244e1e7e7637816ce87f0b6b2f6b393ff5bfce0bb3f0a7dd0b91255ff0ade19f1717ee77337f607b9da79de25e7fb7fbef8fd25067aefef2ff37144f311998b1f9a0fcdd77f7a3e12341fbdc3e858b07f447cc7df75647f0476c732c5a3f19dcffbec28f15a092fcc0ddcf3f3311e188bfe0f3c5f68b6c6c19afce03cc8f184e7e3d08bc632ec713e300ff962cc7c9c628f0c0e47f3c1e1d0fbae63e561349f8c06c3c969f7b635c9bf4ce6fed5773e6fd3b1fb88e360382d776ff3afcdc5e474345fccf6df8fc121de1fe331ade48b83e1f73f6fd0c3f3c27118f4866743a4b6e9f9d8fffb478f988f6995e683fa89feeeeff96a6df62633c5432ae17c4c46f2fd60f8fffbfffedfffe7ff0f035432c6</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>frmMap</sender>
+ <signal>signalTz(const QString &amp;, const QString &amp;)</signal>
+ <receiver>CityTimeBase</receiver>
+ <slot>slotNewTz(const QString &amp;, const QString &amp;)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity2</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity3</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity4</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity7</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity8</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity1</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity3</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity4</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity4</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity7</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity8</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity7</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity1</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity2</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity4</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity7</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity8</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity4</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity1</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity4</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity2</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity4</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity3</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity4</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity8</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity7</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity1</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity7</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity2</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity7</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity3</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity7</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity4</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity7</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity8</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity8</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity1</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity8</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity2</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity8</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity3</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity8</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity4</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity8</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity7</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity5</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity5</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity5</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity4</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity5</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity7</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity5</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity8</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity5</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity5</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity1</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity5</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity2</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity5</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity3</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity5</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity4</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity5</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity7</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity5</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity8</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity6</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity6</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity6</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity4</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity6</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity5</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity6</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity6</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity1</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity6</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity2</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity6</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity3</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity6</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity4</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity6</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity5</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity6</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity7</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity6</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity8</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity6</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity9</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity7</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity6</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity8</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity6</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity9</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity1</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity9</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity3</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity9</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity4</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity9</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity5</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity9</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity6</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity9</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity7</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity9</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity8</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity9</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity9</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity9</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity4</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity9</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity5</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity9</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity7</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity9</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity8</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity9</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity9</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>cmdCity2</receiver>
+ <slot>setDisabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity1</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>CityTimeBase</receiver>
+ <slot>beginNewTz()</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity2</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>CityTimeBase</receiver>
+ <slot>beginNewTz()</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity7</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>CityTimeBase</receiver>
+ <slot>beginNewTz()</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity3</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>CityTimeBase</receiver>
+ <slot>beginNewTz()</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity4</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>CityTimeBase</receiver>
+ <slot>beginNewTz()</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity5</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>CityTimeBase</receiver>
+ <slot>beginNewTz()</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity6</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>CityTimeBase</receiver>
+ <slot>beginNewTz()</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity8</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>CityTimeBase</receiver>
+ <slot>beginNewTz()</slot>
+ </connection>
+ <connection>
+ <sender>cmdCity9</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>CityTimeBase</receiver>
+ <slot>beginNewTz()</slot>
+ </connection>
+ <slot access="public">beginNewTz()</slot>
+ <slot access="public">slotNewTz(const QString &amp;, const QString &amp;)</slot>
+</connections>
+<tabstops>
+ <tabstop>cmdCity1</tabstop>
+ <tabstop>cmdCity2</tabstop>
+ <tabstop>cmdCity3</tabstop>
+ <tabstop>cmdCity4</tabstop>
+ <tabstop>cmdCity5</tabstop>
+ <tabstop>cmdCity6</tabstop>
+ <tabstop>cmdCity7</tabstop>
+ <tabstop>cmdCity8</tabstop>
+ <tabstop>cmdCity9</tabstop>
+ <tabstop>frmMap</tabstop>
+</tabstops>
+</UI>
diff --git a/core/settings/citytime/findvalidzones b/core/settings/citytime/findvalidzones
new file mode 100755
index 0000000..f9e8b5b
--- a/dev/null
+++ b/core/settings/citytime/findvalidzones
@@ -0,0 +1,38 @@
+#!/usr/bin/perl
+
+# A Little utility to help tidy up messy zoneinfo directories.
+
+use File::Find;
+
+find sub {
+ if ( -f $_ ) {
+ my $a;
+ open T, $_;
+ read T, $a, 4;
+ if ( $a eq "TZif" ) {
+ my $d="$File::Find::dir/$_";
+ $d =~ s/^.\///;
+ $D{$d}=1;
+ }
+ close T;
+ }
+}, ".";
+
+open Z, "zone.tab" || die;
+
+while (<Z>) {
+ next if /^#/;
+ if ( ($cc, $north, $east, $z, $comment) =
+ $_ =~ /^(\S\S)\s+([+-]\d+)([+-]\d+)\s+(\S+)\s*(\S*)/ )
+ {
+ $Z{$z}=1;
+ }
+}
+
+for $d ( sort keys %D ) {
+ print "rm $d\n" if !$Z{$d};
+}
+
+for $z ( sort keys %Z ) {
+ print "zone $z, but no such file\n" if !$D{$z};
+}
diff --git a/core/settings/citytime/light.png b/core/settings/citytime/light.png
new file mode 100644
index 0000000..2aab906
--- a/dev/null
+++ b/core/settings/citytime/light.png
Binary files differ
diff --git a/core/settings/citytime/mag.png b/core/settings/citytime/mag.png
new file mode 100644
index 0000000..9cbd32b
--- a/dev/null
+++ b/core/settings/citytime/mag.png
Binary files differ
diff --git a/core/settings/citytime/main.cpp b/core/settings/citytime/main.cpp
new file mode 100644
index 0000000..e8664c6
--- a/dev/null
+++ b/core/settings/citytime/main.cpp
@@ -0,0 +1,30 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "citytime.h"
+#include <qpe/qpeapplication.h>
+
+int main( int argc, char** argv )
+{
+ QPEApplication a( argc, argv );
+ CityTime main;
+ a.showMainWidget( &main );
+ return a.exec();
+}
diff --git a/core/settings/citytime/qpe-citytime.control b/core/settings/citytime/qpe-citytime.control
new file mode 100644
index 0000000..fcec4a6
--- a/dev/null
+++ b/core/settings/citytime/qpe-citytime.control
@@ -0,0 +1,9 @@
+Files: bin/citytime apps/Applications/citytime.desktop
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION), timezones
+Description: Time-zone / world clock settings
+ The time-zone manager for the Qtopia environment.
diff --git a/core/settings/citytime/stylusnormalizer.cpp b/core/settings/citytime/stylusnormalizer.cpp
new file mode 100644
index 0000000..62de28b
--- a/dev/null
+++ b/core/settings/citytime/stylusnormalizer.cpp
@@ -0,0 +1,98 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpoint.h>
+#include <qtimer.h>
+
+#include "stylusnormalizer.h"
+
+static const int FLUSHTIME = 100;
+
+_StylusEvent::_StylusEvent( const QPoint& newPt )
+ : _pt( newPt ),
+ _t( QTime::currentTime() )
+{
+}
+
+_StylusEvent::~_StylusEvent()
+{
+}
+
+StylusNormalizer::StylusNormalizer( QWidget *parent, const char* name )
+ : QWidget( parent, name ),
+ _next( 0 ),
+ bFirst( true )
+{
+ // initialize _ptList
+ int i;
+ for (i = 0; i < SAMPLES; i++ ) {
+ _ptList[i].setPoint( -1, -1 );
+ }
+ _tExpire = new QTimer( this );
+ QObject::connect( _tExpire, SIGNAL( timeout() ),
+ this, SLOT( slotAveragePoint() ) );
+}
+
+StylusNormalizer::~StylusNormalizer()
+{
+}
+
+void StylusNormalizer::addEvent( const QPoint& pt )
+{
+ _ptList[_next].setPoint( pt );
+ _ptList[_next++].setTime( QTime::currentTime() );
+ if ( _next >= SAMPLES ) {
+ _next = 0;
+ }
+ // make a single mouse click work
+ if ( bFirst ) {
+ slotAveragePoint();
+ bFirst = false;
+ }
+}
+
+void StylusNormalizer::slotAveragePoint( void )
+{
+ QPoint pt( 0, 0 );
+ QTime tCurr = QTime::currentTime();
+ int i,
+ size;
+ size = 0;
+ for ( i = 0; i < SAMPLES; i++ ) {
+ if ( ( (_ptList[i]).time().msecsTo( tCurr ) < FLUSHTIME ) &&
+ ( _ptList[i].point() != QPoint( -1, -1 ) ) ) {
+ pt += _ptList[i].point();
+ size++;
+ }
+ }
+ if ( size > 0 )
+ emit signalNewPoint( pt /= size );
+}
+
+void StylusNormalizer::start( void )
+{
+ _tExpire->start( FLUSHTIME );
+}
+
+void StylusNormalizer::stop( void )
+{
+ _tExpire->stop();
+ bFirst = true;
+} \ No newline at end of file
diff --git a/core/settings/citytime/stylusnormalizer.h b/core/settings/citytime/stylusnormalizer.h
new file mode 100644
index 0000000..d5e44a3
--- a/dev/null
+++ b/core/settings/citytime/stylusnormalizer.h
@@ -0,0 +1,70 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef STYLUSNORMALIZER_H
+#define STYLUSNORMALIZER_H
+
+#include <qdatetime.h>
+#include <qwidget.h>
+
+class QTimer;
+
+class _StylusEvent
+{
+public:
+ _StylusEvent( const QPoint &pt = QPoint( 0, 0 ) );
+ ~_StylusEvent();
+ QPoint point( void ) const { return _pt; };
+ QTime time( void ) const { return _t; };
+ void setPoint( int x, int y) { _pt.setX( x ); _pt.setY( y ); };
+ void setPoint( const QPoint &newPt ) { _pt = newPt; };
+ void setTime( QTime newTime ) { _t = newTime; };
+
+private:
+ QPoint _pt;
+ QTime _t;
+};
+
+
+class StylusNormalizer : public QWidget
+{
+ Q_OBJECT
+public:
+ StylusNormalizer( QWidget *parent = 0, const char* name = 0 );
+ ~StylusNormalizer();
+ void start();
+ void stop();
+ void addEvent( const QPoint &pt ); // add a new point in
+
+signals:
+ void signalNewPoint( const QPoint &p );
+
+private slots:
+ void slotAveragePoint( void ); // return an averaged point
+
+private:
+ static const int SAMPLES = 10;
+ _StylusEvent _ptList[SAMPLES];
+ int _next;
+ QTimer *_tExpire;
+ bool bFirst; // the first item added in...
+};
+
+#endif
diff --git a/core/settings/citytime/sun.c b/core/settings/citytime/sun.c
new file mode 100644
index 0000000..d3f3731
--- a/dev/null
+++ b/core/settings/citytime/sun.c
@@ -0,0 +1,323 @@
+/*
+ * Sun clock. X11 version by John Mackin.
+ *
+ * This program was derived from, and is still in part identical with, the
+ * Suntools Sun clock program whose author's comment appears immediately
+ * below. Please preserve both notices.
+ *
+ * The X11R3/4 version of this program was written by John Mackin, at the
+ * Basser Department of Computer Science, University of Sydney, Sydney,
+ * New South Wales, Australia; <john@cs.su.oz.AU>. This program, like
+ * the one it was derived from, is in the public domain: `Love is the
+ * law, love under will.'
+ */
+
+/*
+
+ Sun clock
+
+ Designed and implemented by John Walker in November of 1988.
+
+ Version for the Sun Workstation.
+
+ The algorithm used to calculate the position of the Sun is given in
+ Chapter 18 of:
+
+ "Astronomical Formulae for Calculators" by Jean Meeus, Third Edition,
+ Richmond: Willmann-Bell, 1985. This book can be obtained from:
+
+ Willmann-Bell
+ P.O. Box 35025
+ Richmond, VA 23235
+ USA
+ Phone: (804) 320-7016
+
+ This program was written by:
+
+ John Walker
+ Autodesk, Inc.
+ 2320 Marinship Way
+ Sausalito, CA 94965
+ USA
+ Fax: (415) 389-9418
+ Voice: (415) 332-2344 Ext. 2829
+ Usenet: {sun,well,uunet}!acad!kelvin
+ or: kelvin@acad.uu.net
+
+ modified for interactive maps by
+
+ Stephen Martin
+ Fujitsu Systems Business of Canada
+ smartin@fujitsu.ca
+
+ This program is in the public domain: "Do what thou wilt shall be the
+ whole of the law". I'd appreciate receiving any bug fixes and/or
+ enhancements, which I'll incorporate in future versions of the
+ program. Please leave the original attribution information intact so
+ that credit and blame may be properly apportioned.
+
+ Revision history:
+
+ 1.0 12/21/89 Initial version.
+ 8/24/89 Finally got around to submitting.
+
+ 1.1 8/31/94 Version with interactive map.
+ 1.2 10/12/94 Fixes for HP and Solaris, new icon bitmap
+ 1.3 11/01/94 Timezone now shown in icon
+ 1.4 03/29/98 Fixed city drawing, added icon animation
+
+*/
+
+#include "sun.h"
+
+#include <qpe/qmath.h>
+
+/* PROJILLUM -- Project illuminated area on the map. */
+
+void
+projillum(wtab, xdots, ydots, dec)
+short *wtab;
+int xdots, ydots;
+double dec;
+{
+ int i, ftf = 1, ilon, ilat, lilon = 0, lilat = 0, xt;
+ double m, x, y, z, th, lon, lat, s, c;
+
+ /* Clear unoccupied cells in width table */
+
+ for (i = 0; i < ydots; i++)
+ wtab[i] = -1;
+
+ /* Build transformation for declination */
+
+ s = qSin(-dtr(dec));
+ c = qCos(-dtr(dec));
+
+ /* Increment over a semicircle of illumination */
+
+ for (th = -(PI / 2); th <= PI / 2 + 0.001;
+ th += PI / TERMINC) {
+
+ /* Transform the point through the declination rotation. */
+
+ x = -s * qSin(th);
+ y = qCos(th);
+ z = c * qSin(th);
+
+ /* Transform the resulting co-ordinate through the
+ map projection to obtain screen co-ordinates. */
+
+ lon = (y == 0 && x == 0) ? 0.0 : rtd(qATan2(y, x));
+ lat = rtd(qASin(z));
+
+ ilat = ydots - (lat + 90) * (ydots / 180.0);
+ ilon = lon * (xdots / 360.0);
+
+ if (ftf) {
+
+ /* First time. Just save start co-ordinate. */
+
+ lilon = ilon;
+ lilat = ilat;
+ ftf = 0;
+ } else {
+
+ /* Trace out the line and set the width table. */
+
+ if (lilat == ilat) {
+ wtab[(ydots - 1) - ilat] = ilon == 0 ? 1 : ilon;
+ } else {
+ m = ((double) (ilon - lilon)) / (ilat - lilat);
+ for (i = lilat; i != ilat; i += sgn(ilat - lilat)) {
+ xt = lilon + qFloor((m * (i - lilat)) + 0.5);
+ wtab[(ydots - 1) - i] = xt == 0 ? 1 : xt;
+ }
+ }
+ lilon = ilon;
+ lilat = ilat;
+ }
+ }
+
+ /* Now tweak the widths to generate full illumination for
+ the correct pole. */
+
+ if (dec < 0.0) {
+ ilat = ydots - 1;
+ lilat = -1;
+ } else {
+ ilat = 0;
+ lilat = 1;
+ }
+
+ for (i = ilat; i != ydots / 2; i += lilat) {
+ if (wtab[i] != -1) {
+ while (1) {
+ wtab[i] = xdots / 2;
+ if (i == ilat)
+ break;
+ i -= lilat;
+ }
+ break;
+ }
+ }
+}
+
+/*
+ * Sun clock - astronomical routines.
+ */
+
+/* JDATE -- Convert internal GMT date and time to Julian day
+ and fraction. */
+
+long
+jdate(t)
+struct tm *t;
+{
+ long c, m, y;
+
+ y = t->tm_year + 1900;
+ m = t->tm_mon + 1;
+ if (m > 2)
+ m = m - 3;
+ else {
+ m = m + 9;
+ y--;
+ }
+ c = y / 100L; /* Compute century */
+ y -= 100L * c;
+ return t->tm_mday + (c * 146097L) / 4 + (y * 1461L) / 4 +
+ (m * 153L + 2) / 5 + 1721119L;
+}
+
+/* JTIME -- Convert internal GMT date and time to astronomical
+ Julian time (i.e. Julian date plus day fraction,
+ expressed as a double). */
+
+double
+jtime(t)
+struct tm *t;
+{
+ return (jdate(t) - 0.5) +
+ (((long) t->tm_sec) +
+ 60L * (t->tm_min + 60L * t->tm_hour)) / 86400.0;
+}
+
+/* KEPLER -- Solve the equation of Kepler. */
+
+double
+kepler(m, ecc)
+double m, ecc;
+{
+ double e, delta;
+#define EPSILON 1E-6
+
+ e = m = dtr(m);
+ do {
+ delta = e - ecc * qSin(e) - m;
+ e -= delta / (1 - ecc * qCos(e));
+ } while (qFabs(delta) > EPSILON);
+ return e;
+}
+
+/* SUNPOS -- Calculate position of the Sun. JD is the Julian date
+ of the instant for which the position is desired and
+ APPARENT should be nonzero if the apparent position
+ (corrected for nutation and aberration) is desired.
+ The Sun's co-ordinates are returned in RA and DEC,
+ both specified in degrees (divide RA by 15 to obtain
+ hours). The radius vector to the Sun in astronomical
+ units is returned in RV and the Sun's longitude (true
+ or apparent, as desired) is returned as degrees in
+ SLONG. */
+
+
+void
+sunpos(jd, apparent, ra, dec, rv, slong)
+double jd;
+int apparent;
+double *ra, *dec, *rv, *slong;
+{
+ double t, t2, t3, l, m, e, ea, v, theta, omega,
+ eps;
+
+ /* Time, in Julian centuries of 36525 ephemeris days,
+ measured from the epoch 1900 January 0.5 ET. */
+
+ t = (jd - 2415020.0) / 36525.0;
+ t2 = t * t;
+ t3 = t2 * t;
+
+ /* Geometric mean longitude of the Sun, referred to the
+ mean equinox of the date. */
+
+ l = fixangle(279.69668 + 36000.76892 * t + 0.0003025 * t2);
+
+ /* Sun's mean anomaly. */
+
+ m = fixangle(358.47583 + 35999.04975*t - 0.000150*t2 - 0.0000033*t3);
+
+ /* Eccentricity of the Earth's orbit. */
+
+ e = 0.01675104 - 0.0000418 * t - 0.000000126 * t2;
+
+ /* Eccentric anomaly. */
+
+ ea = kepler(m, e);
+
+ /* True anomaly */
+
+ v = fixangle(2 * rtd(qATan(qSqrt((1 + e) / (1 - e)) * qTan(ea / 2))));
+
+ /* Sun's true longitude. */
+
+ theta = l + v - m;
+
+ /* Obliquity of the ecliptic. */
+
+ eps = 23.452294 - 0.0130125 * t - 0.00000164 * t2 + 0.000000503 * t3;
+
+ /* Corrections for Sun's apparent longitude, if desired. */
+
+ if (apparent) {
+ omega = fixangle(259.18 - 1934.142 * t);
+ theta = theta - 0.00569 - 0.00479 * qSin(dtr(omega));
+ eps += 0.00256 * qCos(dtr(omega));
+ }
+
+ /* Return Sun's longitude and radius vector */
+
+ *slong = theta;
+ *rv = (1.0000002 * (1 - e * e)) / (1 + e * qCos(dtr(v)));
+
+ /* Determine solar co-ordinates. */
+
+ *ra =
+ fixangle(rtd(qATan2(qCos(dtr(eps)) * qSin(dtr(theta)), qCos(dtr(theta)))));
+ *dec = rtd(qASin(sin(dtr(eps)) * qSin(dtr(theta))));
+}
+
+/* GMST -- Calculate Greenwich Mean Siderial Time for a given
+ instant expressed as a Julian date and fraction. */
+
+double
+gmst(jd)
+double jd;
+{
+ double t, theta0;
+
+
+ /* Time, in Julian centuries of 36525 ephemeris days,
+ measured from the epoch 1900 January 0.5 ET. */
+
+ t = ((qFloor(jd + 0.5) - 0.5) - 2415020.0) / 36525.0;
+
+ theta0 = 6.6460656 + 2400.051262 * t + 0.00002581 * t * t;
+
+ t = (jd + 0.5) - (qFloor(jd + 0.5));
+
+ theta0 += (t * 24.0) * 1.002737908;
+
+ theta0 = (theta0 - 24.0 * (qFloor(theta0 / 24.0)));
+
+ return theta0;
+}
diff --git a/core/settings/citytime/sun.h b/core/settings/citytime/sun.h
new file mode 100644
index 0000000..2091621
--- a/dev/null
+++ b/core/settings/citytime/sun.h
@@ -0,0 +1,57 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+/*
+ * Sun clock definitions.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <time.h>
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+
+#ifndef E
+#define E 2.7182818284590452354
+#endif
+
+#define abs(x) ((x) < 0 ? (-(x)) : x) /* Absolute value */
+#define sgn(x) (((x) < 0) ? -1 : ((x) > 0 ? 1 : 0)) /* Extract sign */
+#define dtr(x) ((x) * (PI / 180.0)) /* Degree->Radian */
+#define rtd(x) ((x) / (PI / 180.0)) /* Radian->Degree */
+#define fixangle(a) ((a) - 360.0 * (qFloor((a) / 360.0))) /* Fix angle */
+
+#define TERMINC 100 /* Circle segments for terminator */
+
+#define PROJINT (60 * 10) /* Frequency of seasonal recalculation */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+double jtime(struct tm *t);
+double kepler(double m, double ecc);
+void sunpos(double jd, int apparent, double *ra, double *dec, double *rv, double *slong);
+void projillum(short *wtab, int xdots, int ydots, double dec);
+#ifdef __cplusplus
+};
+#endif
diff --git a/core/settings/citytime/zonemap.cpp b/core/settings/citytime/zonemap.cpp
new file mode 100644
index 0000000..337f4d9
--- a/dev/null
+++ b/core/settings/citytime/zonemap.cpp
@@ -0,0 +1,670 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "sun.h"
+#include "zonemap.h"
+
+#include <qpe/resource.h>
+#include <qpe/timestring.h>
+#include <qpe/qpeapplication.h>
+
+#include <qdatetime.h>
+#include <qfile.h>
+#include <qimage.h>
+#include <qlabel.h>
+#include <qlist.h>
+#include <qmessagebox.h>
+#include <qpixmap.h>
+#include <qpainter.h>
+#include <qregexp.h>
+#include <qtextstream.h>
+#include <qtimer.h>
+#include <qtoolbutton.h>
+
+#include <limits.h>
+
+// the map file...
+static const char strZONEINFO[] = "/usr/share/zoneinfo/zone.tab";
+static const char strMAP[] = "simple_grid_400";
+
+// the maximum distance we'll allow the pointer to be away from a city
+// and still show the city's time
+static const int iTHRESHOLD = 50000;
+
+// The label offset (how far away from pointer)
+static const int iLABELOFFSET = 8;
+
+// the size of the dot to draw, and where to start it
+static const int iCITYSIZE = 3;
+const int iCITYOFFSET = 2;
+
+// the darkening function
+static inline void darken( QImage *pImage, int start, int stop, int row );
+static void dayNight( QImage *pImage );
+
+ZoneField::ZoneField( const QString& strLine )
+{
+ // make a bunch of RegExp's to match the data from the line
+ QRegExp regCoord( "[-+][0-9]+" ); // the latitude
+ QRegExp regCountry( "[A-Za-z]+/" ); // the country (not good enough)
+ QRegExp regCity( "[A-Za-z_-]*" ); // the city
+
+ int iStart,
+ iStop,
+ iLen,
+ tmp;
+ QString strTmp;
+ // we should be able to assume that the country code is always the first
+ // two chars, so just grap them and let it go...
+ strCountryCode = strLine.left( 2 );
+ iStart = regCoord.match( strLine, 0, &iLen );
+ if ( iStart >= 0 ) {
+ strTmp = strLine.mid( iStart, iLen );
+ tmp = strTmp.toInt();
+ // okay, there are two versions of the format, make a decision based on
+ // the size...
+ // Oh BTW, we are storing everything in seconds!
+ if ( iLen < 7 ) {
+ _y = tmp / 100;
+ _y *= 60;
+ _y += tmp % 100;
+ _y *= 60;
+ } else {
+ _y = tmp / 10000;
+ _y *= 60;
+ tmp %= 10000;
+ _y += tmp / 100;
+ _y *= 60;
+ tmp %= 100;
+ _y += tmp;
+ }
+ }
+ iStart = regCoord.match( strLine, iStart + iLen, &iLen );
+ if ( iStart >= 0 ) {
+ strTmp = strLine.mid( iStart, iLen );
+ tmp = strTmp.toInt();
+ if ( iLen < 8 ) {
+ _x = tmp / 100;
+ _x *= 60;
+ _x += tmp % 100;
+ _x *= 60;
+ } else {
+ _x = tmp / 10000;
+ _x *= 60;
+ tmp %= 10000;
+ _x += tmp / 100;
+ _x *= 60;
+ tmp %= 100;
+ _x += tmp;
+ }
+ }
+ iStart = regCountry.match( strLine, 0, &iLen );
+ // help with the shortcoming in 2.x regexp...
+ iStop = strLine.findRev( '/' );
+ if ( iStart >= 0 ) {
+ iLen = (iStop - iStart) + 1;
+ strCountry = strLine.mid( iStart, iLen );
+ }
+ // now match the city...
+ iStart = regCity.match( strLine, iStart + iLen, &iLen );
+ if ( iStart >= 0 ) {
+ strCity = strLine.mid( iStart, iLen );
+ }
+}
+
+void ZoneField::showStructure( void ) const
+{
+ qDebug( "Country: %s", strCountry.latin1() );
+ qDebug( "City: %s", strCity.latin1() );
+ qDebug( "x: %d", _x );
+ qDebug( "y: %d\n", _y );
+}
+
+ZoneMap::ZoneMap( QWidget *parent, const char* name )
+ : QScrollView( parent, name ),
+ pLast( 0 ),
+ pRepaint( 0 ),
+ ox( 0 ),
+ oy( 0 ),
+ drawableW( -1 ),
+ drawableH( -1 ),
+ bZoom( FALSE ),
+ bIllum( TRUE ),
+ cursor( 0 )
+{
+ viewport()->setFocusPolicy( StrongFocus );
+
+ // set mouse tracking so we can use the mouse move event
+ zones.setAutoDelete( true );
+ // get the map loaded
+ // just set the current image to point
+ pixCurr = new QPixmap();
+
+ QPixmap pixZoom = Resource::loadPixmap( "mag" );
+
+ cmdZoom = new QToolButton( this, "Zoom command" );
+ cmdZoom->setPixmap( pixZoom );
+ cmdZoom->setToggleButton( true );
+
+ cmdZoom->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0,
+ (QSizePolicy::SizeType)0,
+ cmdZoom->sizePolicy().hasHeightForWidth() ) );
+ cmdZoom->setMaximumSize( cmdZoom->sizeHint() );
+ // probably don't need this, but just in case...
+ cmdZoom->move( width() - cmdZoom->width(), height() - cmdZoom->height() );
+
+
+ lblCity = new QLabel( tr( "CITY" ), this, "City Label" );
+ lblCity->setMinimumSize( lblCity->sizeHint() );
+ lblCity->setFrameStyle( QFrame::Plain | QFrame::Box );
+ lblCity->setBackgroundColor( yellow );
+ lblCity->hide();
+
+ // A timer to make sure the label gets hidden
+ tHide = new QTimer( this, "Label Timer" );
+ QObject::connect( tHide, SIGNAL( timeout() ),
+ lblCity, SLOT( hide() ) );
+ QObject::connect( tHide, SIGNAL( timeout() ),
+ this, SLOT( slotRedraw() ) );
+ QTimer *tUpdate = new QTimer( this, "Update Timer" );
+ QObject::connect( tUpdate, SIGNAL( timeout() ),
+ this, SLOT( slotUpdate() ) );
+ QObject::connect( qApp, SIGNAL( timeChanged() ),
+ this, SLOT( slotUpdate() ) );
+ QObject::connect( cmdZoom, SIGNAL( toggled( bool ) ),
+ this, SLOT( slotZoom( bool ) ) );
+ QObject::connect( &norm, SIGNAL( signalNewPoint( const QPoint& ) ),
+ this, SLOT( slotFindCity( const QPoint& ) ) );
+ QObject::connect( qApp, SIGNAL( clockChanged( bool ) ),
+ this, SLOT( changeClock( bool ) ) );
+ // update the sun's movement every 5 minutes
+ tUpdate->start( 5 * 60 * 1000 );
+ // May as well read in the timezone information too...
+ readZones();
+}
+
+ZoneMap::~ZoneMap()
+{
+}
+
+void ZoneMap::readZones( void )
+{
+ QFile fZone( strZONEINFO );
+ if ( !fZone.open( IO_ReadOnly ) ) {
+ QMessageBox::warning (this,
+ tr( "Unable to Find Timezone Info" ),
+ tr( "<p>Unable to find any timezone information in %1" )
+ .arg( strZONEINFO ));
+ exit(-1);
+ } else {
+ QTextStream tZone( &fZone );
+ while ( !tZone.atEnd() ) {
+ QString strLine = tZone.readLine();
+ // only pass on lines that aren't comments
+ if ( strLine[0] != '#' ) {
+ zones.append( new ZoneField( strLine ) );
+ }
+ }
+ fZone.close();
+ }
+}
+
+void ZoneMap::viewportMousePressEvent( QMouseEvent* event )
+{
+ // add the mouse event into the normalizer, and get the average,
+ // pass it along
+ slotRedraw();
+ norm.start();
+ norm.addEvent( event->pos() );
+}
+
+void ZoneMap::viewportMouseMoveEvent( QMouseEvent* event )
+{
+ norm.addEvent( event->pos() );
+}
+
+void ZoneMap::viewportMouseReleaseEvent( QMouseEvent* )
+{
+ // get the averaged points in case a timeout hasn't occurred,
+ // more for "mouse clicks"
+ norm.stop();
+ if ( pLast != NULL ) {
+ emit signalTz( pLast->country(), pLast->city() );
+ pLast = NULL;
+ }
+ tHide->start( 2000, true );
+}
+
+void ZoneMap::keyPressEvent( QKeyEvent *ke )
+{
+ switch ( ke->key() ) {
+ case Key_Left:
+ case Key_Right:
+ case Key_Up:
+ case Key_Down: {
+ tHide->stop();
+ if ( !cursor )
+ slotFindCity( QPoint( contentsWidth(), contentsHeight() ) / 2 );
+ ZoneField *city = findCityNear( cursor, ke->key() );
+ if ( city ) {
+ cursor = city;
+ int tmpx, tmpy;
+ zoneToWin( cursor->x(), cursor->y(), tmpx, tmpy );
+ ensureVisible( tmpx, tmpy );
+ showCity( cursor );
+ tHide->start( 3000, true );
+ }
+ }
+ break;
+
+ case Key_Space:
+ case Key_Enter:
+ case Key_Return:
+ if ( cursor ) {
+ emit signalTz( cursor->country(), cursor->city() );
+ tHide->start( 0, true );
+ }
+ break;
+ }
+}
+
+ZoneField *ZoneMap::findCityNear( ZoneField *city, int key )
+{
+ ZoneField *pZone;
+ ZoneField *pClosest = 0;
+ long ddist = LONG_MAX;
+
+ QListIterator<ZoneField> it( zones );
+ for (; it.current(); ++it) {
+ pZone = it.current();
+ long dx = (pZone->x() - city->x())/100;
+ long dy = (pZone->y() - city->y())/100;
+ switch ( key ) {
+ case Key_Right:
+ case Key_Left:
+ if ( key == Key_Left )
+ dx = -dx;
+ if ( dx > 0 ) {
+ long dist = QABS(dy)*4 + dx;
+ if ( dist < ddist ) {
+ ddist = dist;
+ pClosest = pZone;
+ }
+ }
+ break;
+ case Key_Down:
+ case Key_Up:
+ if ( key == Key_Down )
+ dy = -dy;
+ if ( dy > 0 ) {
+ long dist = QABS(dx)*4 + dy;
+ if ( dist < ddist ) {
+ ddist = dist;
+ pClosest = pZone;
+ }
+ }
+ break;
+ }
+ }
+
+ return pClosest;
+}
+
+void ZoneMap::slotFindCity( const QPoint &pos )
+{
+ lblCity->hide();
+ // given coordinates on the screen find the closest city and display the
+ // label close to it
+ int tmpx, tmpy, x, y;
+ long lDistance,
+ lClosest;
+ ZoneField *pZone,
+ *pClosest;
+
+ if ( tHide->isActive() ) {
+ tHide->stop();
+ }
+ viewportToContents(pos.x(), pos.y(), tmpx, tmpy);
+ winToZone( tmpx, tmpy, x, y );
+ // Find city alogorithim: start out at an (near) infinite distance away and
+ // then find the closest city, (similar to the Z-buffer technique, I guess)
+ // the only problem is that this is all done with doubles, but I don't know
+ // another way to do it at the moment. Another problem is a linked list is
+ // used obviously something indexed would help
+ QListIterator<ZoneField> it( zones );
+ pClosest = 0;
+ lClosest = LONG_MAX;
+ for (; it.current(); ++it) {
+ pZone = it.current();
+ // use the manhattenLength, a good enough of an appoximation here
+ lDistance = QABS( x - pZone->x() ) + QABS( y - pZone->y() );
+ // first to zero wins!
+ if ( lDistance < lClosest ) {
+ lClosest = lDistance;
+ pClosest = pZone;
+ }
+ }
+
+ // Okay, we found the closest city, but it might still be too far away.
+ if ( lClosest <= iTHRESHOLD ) {
+ showCity( pClosest );
+ cursor = pClosest;
+ }
+}
+
+void ZoneMap::showCity( ZoneField *city )
+{
+ pLast = city;
+ // we'll use city and country a couple of times, get them to save some
+ // time
+ QString strCity = pLast->city();
+ QString strCountry = pLast->country();
+ // Display the time at this location by setting the environment timezone
+ // getting the current time [there] and then swapping back the variable
+ // so no one notices...
+ QString strSave;
+ char *p = getenv( "TZ" );
+ if ( p ) {
+ strSave = p;
+ }
+ // set the timezone :)
+ setenv( "TZ", strCountry + strCity, true );
+ lblCity->setText( strCity.replace( QRegExp("_"), " ") + "\n" +
+ TimeString::shortTime( ampm ) );
+ lblCity->setMinimumSize( lblCity->sizeHint() );
+ // undue our damage...
+ unsetenv( "TZ" );
+ if ( p )
+ setenv( "TZ", strSave, true );
+ // Now decide where to move the label, x & y can be reused
+ int tmpx, tmpy, x, y;
+ zoneToWin( pLast->x(), pLast->y(), tmpx, tmpy );
+ contentsToViewport(tmpx, tmpy, x, y);
+ if ( lblCity->width() > drawableW - x ) {
+ // oops... try putting it on the right
+ x = x - lblCity->width() - iLABELOFFSET;
+ } else {
+ // the default...
+ x += iLABELOFFSET;
+ }
+ if ( lblCity->height() > drawableH - y ) {
+ // move it up...
+ y = y - lblCity->height() - iLABELOFFSET;
+ } else if ( y < 0 ) {
+ // the city is actually off the screen...
+ // this only happens on the a zoom when you are near the top,
+ // a quick workaround..
+ y = iLABELOFFSET;
+ } else {
+ // the default
+ y += iLABELOFFSET;
+ }
+
+ // draw in the city and the label
+ if ( pRepaint ) {
+ int repx,
+ repy;
+ zoneToWin( pRepaint->x(), pRepaint->y(), repx, repy );
+ updateContents( repx - iCITYOFFSET, repy - iCITYOFFSET,
+ iCITYSIZE, iCITYSIZE );
+ }
+ updateContents( tmpx - iCITYOFFSET, tmpy - iCITYOFFSET, iCITYSIZE,
+ iCITYSIZE );
+ pRepaint = pLast;
+
+ lblCity->move( x, y );
+ lblCity->show();
+}
+
+void ZoneMap::resizeEvent( QResizeEvent *e )
+{
+ // keep the zoom button down in the corner
+ QSize _size = e->size();
+ cmdZoom->move( _size.width() - cmdZoom->width(),
+ _size.height() - cmdZoom->height() );
+ if ( !bZoom ) {
+ drawableW = width() - 2 * frameWidth();
+ drawableH = height() - 2 * frameWidth();
+ makeMap( drawableW, drawableH );
+ resizeContents( drawableW, drawableH );
+ }
+}
+
+void ZoneMap::showZones( void ) const
+{
+ // go through the zones in the list and just display the values...
+ QListIterator<ZoneField> itZone( zones );
+ for ( itZone.toFirst(); itZone.current(); ++itZone ) {
+ ZoneField *pZone = itZone.current();
+ pZone->showStructure();
+ }
+}
+
+void ZoneMap::drawCities( QPainter *p )
+{
+ int x,
+ y,
+ j;
+ // draw in the cities
+ // for testing only as when you put it
+ // on the small screen it looks awful and not to mention useless
+ p->setPen( red );
+ QListIterator<ZoneField> itZone( zones );
+ for ( itZone.toFirst(), j = 0; itZone.current(); ++itZone, j++ ) {
+ ZoneField *pZone = itZone.current();
+ zoneToWin( pZone->x(), pZone->y(), x, y );
+ if ( x > wImg )
+ x = x - wImg;
+ p->drawRect( x - iCITYOFFSET, y - iCITYOFFSET, iCITYSIZE, iCITYSIZE);
+ }
+}
+
+static void dayNight(QImage *pImage)
+{
+ // create a mask the functions from sun.h
+ double dJulian,
+ dSunRad,
+ dSunDecl,
+ dSunRadius,
+ dSunLong;
+ int wImage = pImage->width(),
+ hImage = pImage->height(),
+ iStart,
+ iStop,
+ iMid,
+ relw,
+ i;
+ short wtab[ wImage ];
+ time_t tCurrent;
+ struct tm *pTm;
+
+ // get the position of the sun bassed on our current time...
+ tCurrent = time( NULL );
+ pTm = gmtime( &tCurrent );
+ dJulian = jtime( pTm );
+ sunpos( dJulian, 0, &dSunRad, &dSunDecl, &dSunRadius, &dSunLong );
+
+ // now get the projected illumination
+ projillum( wtab, wImage, hImage, dSunDecl );
+ relw = wImage - int( wImage * 0.0275 );
+
+ // draw the map, keeping in mind that we may go too far off the map...
+ iMid = ( relw * ( 24*60 - pTm->tm_hour * 60 - pTm->tm_min ) ) / ( 24*60 );
+
+ for ( i = 0; i < hImage; i++ ) {
+ if ( wtab[i] > 0 ) {
+ iStart = iMid - wtab[i];
+ iStop = iMid + wtab[i];
+ if ( iStart < 0 ) {
+ darken( pImage, iStop, wImage + iStart, i );
+ } else if ( iStop > wImage ) {
+ darken( pImage, iStop - wImage, iStart, i );
+ } else {
+ darken( pImage, 0, iStart, i );
+ darken( pImage, iStop, wImage, i );
+ }
+ } else {
+ darken( pImage, 0, wImage, i );
+ }
+ }
+}
+
+static inline void darken( QImage *pImage, int start, int stop, int row )
+{
+ int colors,
+ j;
+ uchar *p;
+
+ // assume that the image is similar to the one we have...
+ colors = pImage->numColors() / 2;
+
+ p = pImage->scanLine( row );
+ for ( j = start; j <= stop; j++ ) {
+ if ( p[j] < colors )
+ p[j] += colors;
+ }
+}
+
+void ZoneMap::makeMap( int w, int h )
+{
+ QImage imgOrig = Resource::loadImage( strMAP );
+ if ( imgOrig.isNull() ) {
+ QMessageBox::warning( this,
+ tr( "Couldn't Find Map" ),
+ tr( "<p>Couldn't load map: %1, exiting")
+ .arg( strMAP ) );
+ exit(-1);
+ }
+
+ // set up the color table for darkening...
+ imgOrig = imgOrig.convertDepth( 8 );
+ int numColors = imgOrig.numColors();
+ // double the colors
+ imgOrig.setNumColors( 2 * numColors );
+ // darken the new ones...
+ for ( int i = 0; i < numColors; i++ ) {
+ QRgb rgb = imgOrig.color( i );
+ imgOrig.setColor ( i + numColors, qRgb( 2 * qRed( rgb ) / 3,
+ 2 * qGreen( rgb ) / 3, 2 * qBlue( rgb ) / 3 ) );
+ }
+
+ // else go one with making the map...
+ if ( bIllum ) {
+ // do a daylight mask
+ dayNight(&imgOrig);
+ }
+ // redo the width and height
+ wImg = w;
+ hImg = h;
+ ox = ( wImg / 2 ) - int( wImg * 0.0275 );
+ oy = hImg / 2;
+ pixCurr->convertFromImage( imgOrig.smoothScale(w, h),
+ QPixmap::ThresholdDither );
+}
+
+void ZoneMap::drawCity( QPainter *p, const ZoneField *pCity )
+{
+ int x,
+ y;
+
+ p->setPen( red );
+ zoneToWin( pCity->x(), pCity->y(), x, y );
+ p->drawRect( x - iCITYOFFSET, y - iCITYOFFSET, iCITYSIZE, iCITYSIZE );
+}
+
+void ZoneMap::drawContents( QPainter *p, int cx, int cy, int cw, int ch )
+{
+ // if there is a need to resize, then do it...
+ // get our drawable area
+ drawableW = width() - 2 * frameWidth();
+ drawableH = height() - 2 * frameWidth();
+
+ int pixmapW = pixCurr->width(),
+ pixmapH = pixCurr->height();
+ if ( !bZoom && ( ( pixmapW != drawableW ) ||
+ ( pixmapH != drawableH) ) ) {
+ makeMap( drawableW, drawableH );
+ }
+
+ // taken from the scrollview example...
+ int rowheight = pixCurr->height();
+ int toprow = cy / rowheight;
+ int bottomrow = ( cy + ch + rowheight - 1 ) / rowheight;
+ int colwidth = pixCurr->width();
+ int leftcol= cx / colwidth;
+ int rightcol= ( cx + cw + colwidth - 1 ) / colwidth;
+ for ( int r = toprow; r <= bottomrow; r++ ) {
+ int py = r * rowheight;
+ for ( int c = leftcol; c <= rightcol; c++ ) {
+ int px = c * colwidth;
+ p->drawPixmap( px, py, *pixCurr );
+ }
+ }
+
+ // Draw that city!
+ if ( pLast )
+ drawCity( p, pLast );
+}
+
+void ZoneMap::slotZoom( bool setZoom )
+{
+ bZoom = setZoom;
+ if ( bZoom ) {
+ makeMap( 2 * wImg , 2 * hImg );
+ resizeContents( wImg, hImg );
+ } else {
+ makeMap( drawableW, drawableH );
+ resizeContents( drawableW, drawableH );
+ }
+}
+
+void ZoneMap::slotIllum( bool setIllum )
+{
+ bIllum = !setIllum;
+ // make the map...
+ makeMap( pixCurr->width(), pixCurr->height() );
+ updateContents( 0, 0, wImg, hImg );
+}
+
+void ZoneMap::slotUpdate( void )
+{
+ // recalculate the light, most people will never see this,
+ // but it is good to be complete
+ makeMap ( pixCurr->width(), pixCurr->height() );
+ updateContents( contentsX(), contentsY(), drawableW, drawableH );
+}
+
+void ZoneMap::slotRedraw( void )
+{
+ // paint over that pesky city...
+ int x,
+ y;
+ if ( pRepaint ) {
+ pLast = 0;
+ zoneToWin(pRepaint->x(), pRepaint->y(), x, y);
+ updateContents( x - iCITYOFFSET, y - iCITYOFFSET, iCITYSIZE, iCITYSIZE);
+ pRepaint = 0;
+ }
+}
+
+void ZoneMap::changeClock( bool whichClock )
+{
+ ampm = whichClock;
+}
diff --git a/core/settings/citytime/zonemap.cw b/core/settings/citytime/zonemap.cw
new file mode 100644
index 0000000..8e8625e
--- a/dev/null
+++ b/core/settings/citytime/zonemap.cw
@@ -0,0 +1,21 @@
+<!DOCTYPE CW><CW>
+<customwidgets>
+ <customwidget>
+ <class>ZoneMap</class>
+ <header location="local">zonemap.h</header>
+ <sizehint>
+ <width>200</width>
+ <height>200</height>
+ </sizehint>
+ <container>0</container>
+ <sizepolicy>
+ <hordata>1</hordata>
+ <verdata>1</verdata>
+ </sizepolicy>
+ <pixmap>
+ <data format="XPM.GZ" length="220836">789cc4bd59732acbb2adf97e7fc5b6936fc7cab87492d0433d8010926804089080b27ac88ebe134280b87fbe32638ce19a6beeb99add9d5a662ce6a7c88c708fc6c33d2232f9dffffdb761a7f5b7fffedfffebe3e01fe6e1dfc299bfffdb7f479febf5d7fff3fffedfffe77ffd57319bfd5b3ef9146e8ab77fcbffd7fff5bffe2b5efd2dfc9b974dfecb95525e44e2422ee5c9855ccc65533ebd8bf3b729875b7229ebd2a3a318d7cf3e8d5dfe5f6571dea5c7afe410f7af8bc6eefac9ad18f9357c31cacfdf890b906707ce65915fb83176f9f94731e4095a62c8f3f5252e3afdf7757291fa7d8a71bf7f12e3fe69c6d8c913293fd6cf639b4c7ddfa94f9ef2762e62dcdfa2fe7996ff1e93999fff2246f977ca8ff9d73be04216f537bf729cb40eda777c12177dd7fea1f8caf58fca1759fae87ab6e79331d26b1931dae3b224b3fd3eafc5b8fec8eb13fd5c7e777531d20f7b32f56d04c6eefa774f0c791e28bff47f8ac428ffebded85ddfbe88517fc505b8c0fef14efd0b6cef21f52d509e1af529b2fd9e8664b657be9272dadb6e02571f5532cb3b9fc5688f55518cfe57f900ab3f444b31eaf7ae29c6f5d32399fdd1ff2497907ff799ccf2a38e18e9770fc62effa78cf8caf58fa82dbe29a4bc2517285f6743667d753ec428ef93e517d47e9f625cdf1f8a91df23f52bb0fdb6bcbfc8f15a2f90d91ec7bab1cbefd5d99ba47766216fff815c447fbfb4c9ecafc1b318e9eb0199fdf5b417a3be465931eae775042eb03d8e1199fd79fb48a67efb3e99fa95a762e8b7db8a311e7b336357dedd0bb8c8fa3ffb648ea7cd5c8cfc8e2cbfc8fc87f7c6eefee731f88af662ccf2afae50bf634f8cf4418e7c8bf4b91b0f496f65fdeef364d6e7ec400ec1bb5bf1b5d32f5c830b6cdf55498cfa0eb262d46fdeae477d2c9be2926bef498e2cfbfc2a467ecd8bb1d3ffe5598cfade7e92695f170f62dc7ff4c490c7ff3276f21cb662c817eec9acff9aee677f6aec8cd1ff250fed41bd2c867ccd1e58e321781723bfcbabb1cb2f7b12633ce47c63679fe603b2fa6b20863eed2299f3fbfc057cc5f2f76fe42b8ce7f1907ccbfed42247485fa2fd6ef325b4d7eb52ec872e7f31f51d42bedb02e7abcbb318fd677c11431fbf452ea2fe665b31daa3d7155f3b1eb7c5a89fc998ccf17a1f89519fb58618f9573fc590d75f1abbfc1f4e62c8bb7e11df165d7ed287ed9fff12b37f493fd647e1d118e369042e72fcdec762dcffd03646ff7c27d3bf6bb4c4283f5714e3feac5dcff1bb13439f0af52fd29e6f2b62ce376763cc5f3d31fa6bffc518f3cf5a8cf2ee2c3fe87fdf21d37eeda53fc7d3b96aecd2fb3531f2ab2dc0eabfc7bc31fc939218f9ed8de91fde18bbfc3edfc8579cef5a62da8b1cf916e9eba518e9f7ec1fc9f8807da53cd7b7b0e74d967793a37d873dba2d91974e9f424ef351ee0e2c7b38fe22b3bdf22d31fafbfc22be75e36fb323b3fe274f628caffb1e59e373658cf1d414a33c7f61ecd2bf1ec5287fb314633cec299ffaebcbbd18e575dec5cccf23d3befb6731eba320863cab1732fbdf626fecda7f7d25a6fdd818bbfcfa1f62c8b31818bbf4e1b318f59fdd92d55f2f629457cd89515ed03486bd2a8b51de970f56ff3dec8c317e4a62e4df198b917f3f34c6789e8a39ffb1bca43fbbfbcbaf62e457dc88694f1662dcdf7e23df223dbb16a37e3e1fc811f27fa988391f37c490b799055fe738be57c6eefade0d99e3affa64ecd2eb7932e7a3cdd418f395f2e7f83c3e19bbfb47ecafd71c9fe399b1bbbf5e13e3fe11fbd74d0ee9a79e98f690fade50de25fa5f321f603c0c2fe2921b6fe793d8c77c31100791ab9f2999e3697c3476f767ba62f4c7cca331d2db62e437e1fd45cdaf6763d77e83b118e5f9cfc6c86f224679a33b63971e0562ccf7719dccf925c888517ef7c1d8a537d762d8ab7841e6f89decc4e86f8b9518f9554fc62e7d9b17439fe6bb18f2175ac64efed72b31ecd52514a37df60d32c7efaa20863ce70f31e4d9bd1a43de9298f659f2b3fd96185f361fe52fc6b0876b31c6636b650c7b722d46f95bb6b7c6f7c78d18f9750a62c853a1fec9fc85f58a8198f14f598cf20f4d63979f7f1053ffa5b14b2fb3fe641f4e2531e381ba31e2b7bd18e5bf9d8c919f2f663cb53576e9ef3931e429d8f590675704cbfebc1f8d5df9ef1331ca7fef1ba3bd59dfb24fb5b531fcc90731f22fb3bdae599f77436397df3dc7a3eccd7a21a6bdbf17633c3e4462f49f0ae54bec11e2c71b31eedf5d89517ed41523bfda1799fe7ef149ccf58dbc31e623d66f89f670332353df8cabcf624ef627d304cb5e3c8ec5811b5fc32199fe4bcb1343bfe1abb1bb7f742546fea3aa38bc725c3176e9f72a8ff6e1fc2986fe8b6731ed5bd118eb3d2d31ec43612b86fc930f31caafeb7ada87cd468cfed8ac18bbf4ee488cf2a3508cf21a0531ec6b9007cb1e043963f847cf629417978d31fe2331ed37e54fec03e6e32f31fd938cb1bbbf5210335e507eb4276fc6b09f31f595fda8768c5d7e4f9e18f9b5b3c6f02fba64da83cf8231c6f3b598f2b68c311f283fda83d39331fc61e6277b305b8b51defad618f3d94e8cf2f63d6397fe7625467945df18fad4c8b4cff3be98f167c918f1f1b598eb056d63a46fc5282f627b5f331e69f48c5d798d8a18e50d76c698af2c1de5ad2363ac8f497edaa7ea8d18f9dd53be1bd667361623fd301263becfefc4e82ff7d447f627ba1323bfe154ccf9a16f0cfff54b8cf19d3f8b31be6ab44f37f40feb0f62caa7f26e717dd113633c360332ed75f1d118fea5f4e3fcd6b812737e57fd44187ffb15b844fbfd702346fd36698f4ab4bf8f0531e793580c799f395e4b6cffe1814cffb6037bebcb3f5a6ec8f44f964731f25b3c8961ef6a2fe02bfa8b8b9698eb757563a7dfa426e6fac84c8cf6def68c5d7f187d91d9dfb77d63f43f4f8cf2efb3c6aebcbedd8ff2e67931cafbb4fc505e7b4d66ff6e9dc418af7e594cff2d678cf9f355ccfabf18bbf4fa500c79a662daaf73490c7d1f3bc6981f76628ceffed918f6682ca6fdcd19a3ff5b79d0dfbf13a33dc377b0ec59e7468cf28e6b6357de692b46799f763debdfae67bcc3fa90bd9b94c4286fd33346fb0ec528fffdda18feeebd18e53f7d89d19ef94f32edd97e2c4679ab9331e64bc9c3f9e7e1da18f347284679bb8db1d3efae4066fb859fc6eefefc8b98f7bf1bbbfb3f31bff8b297f1b3b1abafaf8398fee83763fe7c12a3bc6345cc78ef468cf243d687fcb946284679fba198eb612731f4eb7a62e47fe6f8be617cfdd21353fe6b31d7ff2231e47d91fcb497cf6f625cfffc29c6f54ddaa712ebeb6e45e6fcf034216b3e72ed7b95bfca46ce3f1b3f92af30ff4c3ec5180fab5bb2e297ba98f62663ecda6fd613737e991bbbf481e587f13f691bbbf25f2f62c69b2f62f8b7f72199e37d267dd87fee3d31caef67c52caf2c46fe830fb0c6737d2ea63f1c8b915faf600c7bd71523bfcb82ccf1bb50feec1ff74fc6b0af0731eab3f3cd287f2d66f9ef6294b710733c4f8bc6589fef8b693f32c62ebdf12a46f92bc9cbf63b7e193b797a3b31fd7fc9cbf60a57648effcac518e3b322a63f3e32c6fee4b318f21c0ec6aefc4a550cf9ea963fe4c9bf8961ff2e1bf00dedf9dda331da672ce6fa69d618fed3a718f294236327cff3448cfac90fc428ffb545a6fdd8dc88399fdf19c3ded7c590e775658c78632ae6fa54d718f1a49547ff91f5237fae5531c6fef78b18f2bcbd19633e6e8821cf8be507791eefc5ac9fa5b19327d713a37e3e9b64dab353518cf29f7d63d847c9c3fef261d7a3fc07f61ff9877151ccfaa47eb2879db5b1bbbefd24863c837731e43952bf12ebeb59e5d1dfafefc448af703cdd529ea1f34fae7cad5f16cac6ae3e4e186fbef63b1f037211e943d8b3c45f427f1aeec488e7c71531ec793e43a63f1d6fc48c9f4762d8f75cde18f6f54d8cf8fdb162ecd26b4d31e70f8c8fc4bf613c70670c79d762f4c76a568cfca65762e4b76a18c729cf7d32c747b32c467dd6d7c6580ff2c4b00f87a118f2bd3e1b637c7e89215f6360ecd2572331ea672ef9af503f8b83b14b7fb1f220ff94f529fb3b51791c1fd5400c793b4fc6586f517dd2debec6c64ebeeaad18f29f25cf2de4dbb2fd656fcf7b63579fd38b18f5592d1ba37f1ec5902f181a23fd2c867cedb1b1936f9f11a3fe16ecbfb2bf93be98f1455b0c796adfeccadbedc59067766decd2975762c8336b183b79165f62b4effb8d18e321df3376f2166a62d4e794fac97eafbac6384f9017a3be1f8bc6f0bf6fc5d0efc3eea77e6731fb6fce18fed38318fab50231f4c95afe90f7783176fa5ceec9b467ad500cf94fb118f25feac6f08f3ec4dcdf8c8ce1afa83cf6e77ad3d8a537d47eecaf5bbb9ff3b5da8ffedef3540c7d6a4b32e7878bca63ff8e9ac68857aa62c81b6c8c317fcfc45c5fb5eb59df9f62d477e5510c793fd93f35ff349ec5a8dfed9798f349410c799f6f8de1ff0762c8fb7e67ece4f9b0fb216f8efa6bfde36d2846799ff7c6f0bfea6294ffd533c67e41438cf21a2f64add75f89e9bfb48cd13fec7afa9b4d63cce7b4a725b6d733ede92ded418de3f196fa3429ef2de7dbb9f3afaff3852cc67324e67e593e47e67ed5b04fe6fc5bb936c67ac42bb8c8fc864d32e7df684fe67a75b56a0c7fae2fc6f54103acf5a071991c613e58eec08a2fee1fc5b03ff737c6aeffe70662f4ffea511cbbfcf20fe2c9b52b4fd7737eabf5c4a88fe9b5b14bbfbf13a3fc59d7d8951f4dc5283f776becd2979118f3f773ded8c937d88863275fa6638c742b1ff2df0764da8ffb9131fcc95731c6e36665ecf479cc89a1effcc9d8a5676a62e85bb5fca16f752886beed8131fc15b517fdad85c90b7ddf2c7fe8b3527bd2de743c31f45b3d1bbb742f2b867ee7576327ffb42a66bcd93746ff95fef4efbc0f63277fe524a6ff3213439fb7a618ed3565fd68be1e5dc45c6f2b88b9fe7934c6f9bba998fe83e5477d8b62e8eb5d1bc3ffda8ba16ffbddd8a57b563ef4dbc762b457ff534cfdd85e9a8fe32731e5df1a3bf9b6c6943f3276e987ba98f1f0c2d8c9773c8bb9defa620c7fe44d8cf6f237c64efe9631daaba8fae0785bdc1abbfe77c7fea0f97c951743df554f0c7d2f0d63a74fa8f6e0f87b2f19bbf4aeda93e3efd9ee87be33d5a7e6f7b531faaf950ffdcaa198facd8c5dfa4cf5cbf1f6207d38ff871f629eb72d18bbf4f9ab98ed7b3676faac3b62e8bbfd6697feaefae578dc59799c6fd43e1c7f0f8f62fa2fea8f1c6faf596397fe3e16a3fdb607b0fc85cb5c0cfd5a37c6380f711443bf46c318e7453fc4d0efe3d518f6a82b867eef5963a74f6e21467be6fa62e8f769d7737e90fc5adfb81863fd50d7d3ff58bd1a63bff045ccf3f8beb193b75516733fe69b5dfa5b550c7dc61b31c6d785fd53fe4aa323863c77256397fe2179395e1eed7ec6e7d762947fbc13a33fbc7c8a517ef662ecea6f7345667f0ed49e8ad7dac658ef903eeccf7ecfd895ff247dd87f2f0531db8ff2dc72fd7c743086ff7f25e6f996b331d6d32d9dfbd33563eccf64c4f4b7585fb73a5f3711f3fccede18e70b8b62e49fa3fdbde5fa79c513f37986b998ebf10b63f8a32a8fedfbccf6b9657d6f385e7dfa9bf74d63975e647f0af2e0bcf3a7affd02cf1fe4eb62b4ef06f2fa3a1ff6be10a33f0e46c6eefece5c8cf6293f91b9df38ee8bb91fb8045ff13c5a2f4fe67c7d0f797df98ff70531c6e77d8dccf965f22246baf765ecd2dfd662d8dfcc590cff2df32186bff3726b3c71f989393fdc17c55c7ff78de19f3d8b519f998531cecf2cc590d77f3086be5762c85bf58c9dbcf70331fdd19d31f4998ba18f7767ecf499bd91391f9c6ac638af771143bfcc9331f48bc4d4cf37867fa6fae57c31088ca15f570cfdee87c64efed5b598fa79c6d0cfe4837ebec90ffd0eb027b65fd6bd16a33f7a2531f48fdf8db19ee68ba17fab6decd2cf4731fdd3d818f14e530cfd5b9fc6a89f8d18fa2f4363c457961ff5bf3346bc712586fe01fbaffcbfd6d118e7117262faeb1563f8af7931fdf5a1319ef7b0eb511fc1ab31fc5be9cbf969723676fa7a563ec7e79531d26fc4a88fc9bdb1d3b75f15a33e9acfc6f037381ee40f7edd183bfda696cef3753963f817d28ffea0bf3676fa15240fc7fb7a2786bee599b1d3e7a8f6e4f85ecc8d5d7a57f5cbf9f0291043fee3d218fb731d31e4df378da1df8b18f247cfc64efeca560cf93f4263a4ab7f713c1f8fc658efec8ba1cf8767ecd2fd9518ed377b3446fb487f8ee715f591bf57a918c35fbd1243dfa7ac31d6e75ec5d0775b3476fa743fc4dc7fb5fb793e2410439fd5d8d8e9f33115d35fbf3776faecd87ef20f271b63cce77d31cfcf7e33d68f5a62ae9f8e8ce1efa83eb47e1a19bbf4e68b18fa772fc6b05f763ff47fde8bd19e6f0731f47ffb32c67a7153cc788cfd49fee649f547ff72a3fae3f88bdf8c115f4ec4d0c7df1a63bd6925863e8f9eb1d3677c27a63e2763977e772b46ff7d793476fabcaa7d381ebb0563d863da07f35f553f1c9fb1a543bfbb8bb1937fa3fec8f179ae18c39f55ffe1f8fcb2fce83fa97d383ef3ea2f1c6f35d68ffcd5cec9d8c9b7bc1143bef3c418e3e9494cfb5733c6f9db0f31e45b5b79a8cf915d8ffaacefc590ef8ef3abfcdffd42ccf3465d639c3f398a21eff3bd31e21fc9c3feff7230c679a48a18f595b5fb21efa3e4a37f1d5f89215f762a66bc5d35c67e82ca677feede18633ea57dbee57e6f2332c6fea9e461fcd3fa32463ca6fcd99f3a7d31e3db9d18fdfb8bf6d3677cf37225663c7a234679839931d6a375bdcff3596c4f3fe6fe09fdcf20cfe78356c6989fdec53cff4afd826bdc7f6c8a717f3143f6915ea07d0e59de4b4bccf354ae7fde140a3c6f1dafc18a27c64fc6f037b6e422c74b955cc2787a3883751ed1cf80e54f67b662aed7de1b3bffb1f946e678ed1e8d5dfebe27e67eb05d4f7ff8da18fefe49ccf82527a6ffdb37867ffb29867fe33d8821efee60ece49de4c15acfdcecc5a8af7d470c79b63531e41996c590a7d617331e7b3576f254c762c893b7fc204ffb83ccf968198821cf6c24467d457363c407d762c837793446fa8b18f5e54562c6074331e5b3fb21dfb04ed6788fc5b4975331c6e340f9717eda958c31df16c4e80fcb6fc6faa8cae7fc346f183b7d1ed43e9c9fc6563ef4cde5c45c2ff5c5689f8f8998faf5c85a9fff32c6faa8e467ff5e6d8ce11fa97ed9bf7b4363e823f9d8df3b3b63ac5fcfc4d027affa657fafd8f5907fdd1543fe39e5977f383b8ab91eb13176fa7c3d89793eae25e6fec2de18fb495931e47f3a18637ff924a6bf1b19c33ffa14439f4f9307fdb17511a33f76696fe4efc58fc6f0df953fe7b7695f0c7d1e0ac6183f4531d7a7afc41ccf763de48bdec99cef9e0ac6d8ef577d71be9b0cc5dc2f981863bdf54e4c7f6d61ece42babbd381e4e5fc6e83f963fe47d2919e3fc89e50ff91bba5ee7eb1ec47c1e73618cfd8e9198f1d2d118ebe5ea2fecffadb3b193afaff2b5deb833c6f904e9c3fe9d7d31c67e00eb53eb8db97b31f72ffa62c8bb7a1343dec7a1b14b1f5f8bd91f2c1df2be5bfe90b7f821e6fafd4accf5ed8918f53ba81bc3beb37ee5af2d6a62eee75b3ae41f7c89e9bf2c8d719ee9564cfbb936c6fa63560cf99fba62c87f67ccf5b29d31f42b88a1cf59f9b1bfc73d63f82b1d31cfbb4f8cd17f6231cfdf968db17f24fdb47ffb4c66ffdc287ff6cf8f6fc6790dbb9efeed8731ce178ec5c8ff692666fd70be97ff1766c55c6f7f34c6fc66ccf78b648c711ea32c863c5f9c6fb47efc5917c3bf8bee8d71bef241ccf39e7b63f8bb5b31cba7bfe6d33f0c5fc5c87fd43386ff6ad723ff5a854c7ff2fe5dccf74f7c1843be404c79289fd6c3bfc662dc5f8b8de15fefc4287f78678cf579b667e20fe3bcffad31e45b8af93c41608cf66988f93c23fb8bfce78bf263fdb4aac6b0dfecff01eba3bd11f33c6ac518f549f943ca538bc4283f5b15a3bd5e381f862cff79610cfdd9bef2efebf762e6ff6e8cf3a9b48f11ebbfb210b3fd56c6d8bfa07f1851de16fc9f40cf671e2e64ee2fcc72623e3f9a3776f622467b047a9e69d41463bc953b628cb7d950cc78b860ecf2fbba8839ff62fe09142f54f262fa53960e7977a8ef40e709ca1731f79b3d31cfd754c4f0979edec8b4bf5f0d31ca3f18339e2a1abbf4412ca63e2732edddf051ccf3634363777f3d2b46feaba918f22e3d63f857be18f3cda22386bfd46b8ba15f7541a6bdcc758db11e3013f3f9b01b31fb83e4a3bfbafc3476f2b4fb62f6976b63977eda8921df51f5c3786cd43176f2be515ef9a7872731fdb78198fd2b2fe6fa6b60ecca5f5dc4906f5e1073bdfc5dccf5d59d31d6cf7362c8b7bb27eb794a95cffe135e8b21efae25e6f31a7563f81f2b31e47fed1863fdf8538cfa0c6fc43c7f3d31c6f923e9cbf57edfca833ecf3532e7ebd3544c7f6f6e0c7ffa20a6ffd13676f2bf8562aeefbf19c31fb4fcb9be5830c6f987ad98e795d51ef45ff77b63277f4ef5c3fe5e3079d09f9aca9ffec2e224867e6f5d63ac2f8ec4d4cfd2795e58fd91f667d234c67a86ea8be3e1f52c663c7a30c679fdaa98e7e54ac64e9ff64c8cf67b817f1ce879829d31f73b1662e8170f8dd1bef762e8f7b932c6f3f33331edeb9731d68f6fc568bf879a31f4198b19af8e8c11cf9ec4d0275b3476fa76389eb5de59e889b91f1719e3f9b28c98fef2ad319eafec8b391f7d33eced9d98fbed8131e2938e98fa9a7cd0efa966ecf46be4c41c8f961ff43d5f91e94f8f545ff49f0b96cef3a85531cf23d9f5d06f751043bfdec018eda9fea0f5feb531da53fd81e36f581243bffeab18f27faa3ef4bc56cb18cfd77c8a795ebf680cfb3111733faa678c7840fd8fe3ef2536867d947e1c6f4f8f62c8fb7a30c6fac2458cf668523f9fef276a5e89b9df742366fc712de679b1ac31e20bcb8feb4347633c7fd015f3bcc7ded8c9dfea8bb9feee89a1cf82eda378e0f0628cfd154be7f9fb9231f683a40fc7c7a0608cfa0ec55c9f957e1c0f3dda6bc513355dcff8615331863c65319fa7bd18bbf2da6731e469f58c71fe99f3ade28f42648cf85ff2c58c1f1e8cb17f732be6f382cf623ebf583576e5bdb27cc52f8d1b31e38bbe31e2b72731df57f2688cfe5315335e7d37863ffa4156bcf0698cfe561723fffdab31e29f9698fbf3b4ef8a67ee1bc688873a62be8f6426c6fd7bda03c5371fe490fad5ee8df1bcdbbb98ef8bca19633f55d753bffbbd31e2a5a998cf9b4ec45c7f3266feac0fc54be76763777ff54acce7693f8db1df62d723bf06fd03c557e79698ed7130467d6fc49c8ff262eeb7b3be156fd53e8ca1ef59ccfae4f850fc1586c6e8bfae7e4b05bdef21f0c08a5f66af62cc47ad67639c8fbd256bfcbe8879bee2ced85d9f3f92399f94951fe78fe1580c7b34a819e37c7c48a67d7edb8a517e67224679870fb09d2f35c6f587d818fb1d2b31e46f54c590a77b25867ddf505fadff56e7629e4f6e89b9dfb51723ffb7ba31e2ab408cf25a3531e6c3b7bc31d6a7253ff74b961963172f2cd97ef2b7834f31df0ffb24e6f37d2531e47da919239eb574eefff8c638cf771043fe51d9d8a50feec58c7f4ec64e9f99da87f3ffbc6a8cf8c2ca837ef91b32e7fba331f4db14c43c8fa0fa627f99178db1fe5d1143bffec518e72f4662e8d7537b73be5f34c4907ffccd4efef2408cf67a0e8d9d3e5f6c7fad3f9f2662e853be32c6fac7548cf61b6e8c11ff95c5d07763f943df7a45ccfdf76b63ec6ff5c43c8f69e5419fd149cce77f3ac64e9f40f2d21fd8dd1943fe9c98effb8bc48c577bc6d81f2e8ab91f373286ff3513a37d0ab131d2f762b4d7e3c0d8e9f3d21733fe3e88a15f2cf9399e9aba9ee3691e1be3f993b618fa2d6bc6787e6f2ba6fddc1b63fd49edcff1f6fc688cf36a9f62e89b0b8cb1befe2586beaf3b638ca7b318fdf5f4608cf1d81443ff3ec797fce9eacc18cf47a93de84f6faf8d11afbe8b799ead668cfa507fd07a4fdb18e7fdd55e1c7f4f1fc68827d47f381e2fea2f1c8f17bb1ffa4d694fe57fc75531e6db75cd18cfb3f7c55c6f3919237e1a88a1ff62648cf67c10f379efb5b14b0f8f62e897ad1b3bfd1e8dd17e4dda0f9fef17f8ba15439faae4a5bffed236c67eb2f4e7f8dc9c8d713e6a28e6f922c9cbf1f9b61743beec9d98eb27d762c6a3eceff2d78307639c9f1b8be93ff78db1dfa1fc7dcee779639cf75c89f9fe09da2bf9eff5c018fea0e493ff9e37c6fa4543ccf79f548db17fd613f3f9ab2f633c1fcff947fefa7d5dcc78b5668c78a522467997a1b14b2f1cc5b4f71cfff2e7ab5b31cffb948d319f34c5283f9b35c6f87d17f37d6b6c1ff9f3e19398fb892f62be6f47e5b33eabaccf90fa9ee7c6789e6626e6f9b6b531dabb22c678a8b17f87d4ef60ccf5a8d818fb811331df8f427f28647f7bac8939bfd27f927f1ef68c71fee95dcce743a98ffceff642ccf7b7b9fd8a52a0f3451bdc1fc83f1e3c9275fe64648ce72d9ec57c1ff14a8cfa9864c95adf288a917f1018c3ffd6fdb49f6d95cff5bf9c31c66b07f565ebe1cb3b31d7bf6fc4f41f66c6785f8531fdc18631de173a27737e3f0cc4cc6f698cf52e4f8cfc56763ffc8dbad2391f6f32629e2fae89f9bee7b131fc8b4f31caeb34c5286f3c32867fa4f2395f5eec7aca5322b37dc62b31c66f363486bdb888198f497fb6e7d7560c790e960e795ea50fe7bfc6464c7ffa564c7fe6cbd8c9ebb3ffc89f6c8e8cd13e7d31ea2fca1863bd7d2e86bc77964e7fb22b86fcfb6f467d6fc53c8fb316733ddaf2633cf029863ee5b631eadf27eb7d026731f777242fe7b7c137231ecc89393eed7ee83ba988a16ffc618c78a82a86bef3b131c6474d8cf60a4c5ee8f7a0fa60ff8ed83fe46f6627c6983fca62be7fe44b4c7fe3c118f19cea9ffe656e6f8cf5f3500cf9dfe6c6388f782f86fcbd3b63c4a7d29fe3a37d10a3bd06d7c64ebf91cae378e9aabe395e96556327ff7625867e95a3319e7f91fe1c3fdb9cb193bfa7fae6782a4c8cb1ffb511733dd7e4e1f3114331fa676f6decd2d74d31f47db574e85b833f60ebbb8f5331f43d6cc4d0e7b41473fee81ac33fce8b39be26c62e7db71073ff676bece41d5e89a1cf283076e9679397ed773176fae458df7a9e31ae89e94fe78c111f8562ae47583adaf743e5697ec88aa9ffca18fdd5cae77ec2c218cfef34c5d03fdb30463cabfaa4bfda36f9a0fff84d0cfd1f383fcb3f1d3d89217f311673bda9688cf5abb298f6236b8cfd6d4fcce739d87ffc98bf679611733dfc51ccfdc6a398fb350d63945f11f3fc59688cfec6f2e5bf6e2e62fa8747639cff7f1573be6d88f9fe848918fa9d387ee48fb69ac6781f512046790f96cef30da118faf5b7c6aefc665eccf541da8f40fb03928fed776c8b39ff293fd66fdf17e3feb3ea87f5fdd531c6f3b14f62e4978bc4b4c7ec6f5aef6ecdc57c7f6b20e6f83889b95feb8b31fe5ee95fca3f3e3d8bf93c84f267fd0d9662e4f7bc11f379da1d99f5957d12b3fdbf8cf1bc9be465bc753f11b37d551eeb2bbc33c6fe16fb83fce726db27627fb8e37c1fb37e3a6e3cde16e52f2fe762eeef2fc5d0ef6cd743bfd62b59fe7153ccf5e7ac18f662f8cdf03f1a62aecf7a60f9bbbd8a98f1fa8cacf76d348d619fc662dcef378c315fe5c428af51236b3ff545ccf5ea9398e7b32764ce978d92319e57d98b215f253486bf321423ff75460c791e7c31ca7b88c15aaffc5a89b91e9215439ed1d018f67e2c863c9f7363f8934731d74b06c658ef33e6796a9307f24691b16b9f49474cfff864ecf439e97afa831f4363f43fddaff7d72e8d61cf7762fa83d287f351e55dcce7876f8c9d7cf1590cf9a29931d68f3fc9f4ffbeeac6587fbb16f3f99a92b14bdfa8bee80ff626c6882f9a62c8ffe219233d23e6f3d1763ffa7f640cfd661563ac37aafef4fc7bcb18cf47287fae371e8b62be5ff2de18f19cf4637fefbe1a23be7a11b33d1e8de1ff493f8efff597b19377ef8ba9cfb331e6eb8618fa6c3e8d713e8ef561e7779fc5d0a77830863e6b31f4799f1be3f9aaa198fed1d118f173530c7d77df8cf78184623e0fdc3276fa546231c77bd618f391c9cff74fcd8c9dbead2959cf47bc89b9df9635863f178919efbe1a23feb0fb21effbc818fef7bb98fb317363bcdf53fa69ffec9b9dbc15b6afd6232b3d31d71f5bc6381f22fde8ef6d3c6397be1e8bb99eff6a0c7f2827a67db5f2b9be2a7d7daeaf9e8d118fa8be7dc6cb260ff46d5afed0b7fb62ecf49d2a9dfe4db41543ffb6fa0bfd99f6a731f4bf88a16fe1430c7d3f06c64e9fb5e50f7ddfdf8c5dfad3b518fa764ac6d89f517f8ba1df52fac7d0afd33086fdee83b5de5a3988b9de3c33c6f3266531d7977762b46fff680c7f371073fdc3eee77ad242ccf8ecca18e99f62e87b588979fe93fd47fe70bf24867ca78298cf371e8cb11f581733dec81ba37f49de6bc85357f9d78c7fd91e818ff3808357319f8fea8a79de666b8cf8f646ccfda192b193afa1f2385efa6a2f8e97fabb31ce83d37e6abd395b33463cb214f3798d9118e58fde8d713e4af2d03fafb0bee47f3f648ce1af9ec5f4ef3d63bcbfea24e6fb66be19cfbf733cc83f6fbd1be3bcd0a398fb6d0d63c407763dca0fa99ffcf5a6e4657b14cec6580fa37d0819df148df97e9f9298bfc7447b2cfffc4bccfd85c1404cff9dfd39a23c0f185fa1fce543d918eb0f4f628cdf21ec4128ff39b317d33faa1823bd21a6ff60e9183fbd1e99f3c7ebad98fe7dcb18f94dc52c2f30c6fad6418cf2326b63d853ea277f3c3716a3bcc2dc18e53d88595ed518eba10532fd995d478cf11084629477f934c6fc7e14a3fce3abb1cb3ffb2846f979cb9fcfe3327ff9e38da2319eff9b88b95ed83346fcf221a67ff86c8c78aa20e6797d5f8cf2f76d63f84fca8ffef7e39598f6e2cdd895bf1c8a195f05c6787ee241ccf7994b3eb6ffd38bb1936f9317b3bf9d8cd1fe3b32fdeb93ea8ffef5e7cc18f567e990afbc30c6fb764662d6572c867cdebd31fa534e4cf9d6c64ebef53599fe74f54b4cff782be6798b37633cdf501533de8d8d31bf1fc4a8cfd1c018fbef0d31fb7bd118cf877b628eaf8231ceffb0bee52f57c662c667df8cf86621e6f3cf45638c9fb598f1c08331cebb95c5d0675a3746fcb213b33d4263b4475f4c7d4c3ee8d3d1f53a1ffb658cf5d02b31dfe73935c67a5e5b4cffea534c7ff26c0c7deec4d0e7c337c6f33d5d319fe79818bb743f12b37f1d8c9d3e47da57f9c72fba9efef13c23467b1446629e477e31c6fb8aaa62cafb600c79541ff47f5775638c57c947ffd7eb193b7937aa3ffa07e3a531fc13e943ffe0e1c518f62716d3df0d8c315e9ec4dccfce19e3fd458f62bebfe8c118f1a6fa6b0cfdba763df4dbcdc4d4cfe4837e31e593ff7bbc1643dfeabd98cf4f3f18637da321e6feec8bb193bf781643bffac118fe6557cce715d6c6881f4d3eee3f583adf376df9f17d1a2763d833da07ad0f3f491efa47e5b531cefb3d8ae99f558da1afa573ffd5f283bee73b31f4edd48da16f45ccfeda13f3fc5fc7d8c9df7d27d35f9b6e8d619f55dff49fab0363f4cf4f31cff7fbc6783f84da53e3ad610c7b118ab99ef62146fb4cd45fe80f9e6762c873dc18431eb50fc7cb73d718f3a1f4e7786959fe3cbfcbfce56f9727629457b7743effbf14f379afbdb1cbaf45fb2f7ffa5015f37d8a96cef7694cc53c0fbd22b37d7aafc6389ff324a6bdbb21b3be0a2731f72b32c68807d8bfe45f577762969715f3fd87ac2fad8f5796629e47a4bf27ffbb9d1323bd497b16317eda71bed5fa7ac1d58f5fb4f7ede48db11e1790393f7befc62ebd7f05d6fb681ecbc698df7d31d78beec89cbf86b762beefa0640cffe1468cfc875b63bc6ff3410c79f6cf64bdaf53f2d01fef47c6789f654bccf5f63199fe4ea56c8cf396ba9ffaafce609d87290cc57c7ea82ba63fbe3286bf7010d37f7817d37fb0eb595e9bacf3f65b31f7038ac638cf3b10d31fff3046792d31fdb3d018e93331e5d918633f4ae5ebf735243ffddbdec218f654f2b03d5eb2c628af2ea63cb131d2cb62caf365ece469a87cfab7f54f31eaebe9410cf9366b63973eb5fbe9ffdd19bbf21f553ff267ef8d11df4a1e8e97b79d31ce033c81ed7d230331e46d2cc5b06fedae31f6178e629e8fad1a43fe7b31e40dda623e6fa7ebe95f5ecec6382ff229e6f9f88231e2bbb118e51f1f8c117f5dc48cafe662beefbf668ce7338d694f3cb27e6fe856ccf7010d8c11df5f8b21cf3434c67aeb49ccf3e09131d68f1b62aea7aa3e144f7db393ef8ef651cf274e46629e2f53fb319e3a6d8cf1be949d98ed171ac37e4cc5f49f5e8c313fefc58c3f86c6b0b76a5fc5535963f84f64c54beb4731e47ddf8921dfe3a731ce279fc57cff71c618fef9bd98e3e3cd18e3f7454cf946c64ebe90edabf799ec6b62fe3e4a57ccf8efda18f19fca63ff6dc6c6b0877762ae0f748c715eb12de67a68d518f56bf9b3fe0363e8f72aa67e2563a75f41f5457fad2179e8afbdd78d319ea41ffdb5d69331e2d9b998f6aa6d8cf9d3ae67bc5433467a53ccfede31c679348e0fc547a3ad98fe5edf18cfd3aa3fd1dfeb748ce12f1fc45c1fff30c6fa554eccfda97b63c4df7b31edc9b331e2a78218fa4c7d63a74f96f5a5f5fee24accf32bf7c6f00fbfc47cbfc8de18fef449ccf3aa763fcf67f68d616f3c31dfaf66f951fe400cf91f8fc64efe33eb47f14f6d28e6ef53de1a23fe298a793e66668cf6cc88b99ffd608cf315963ff7aff7c6680fbb1efa0cac3ce8737813733d8ff657f14b7d6a8cf396af62ce3f6d31d717d55eecef03d527fb77376fecca7fb5f2e8cfd27e28beb95b1ac37fbe11d39fd989b99eb710d31fac8bd15e05bb9ff11ec75fc8f3e34d63febef49b319eef2c89f97cd146cc78a029e6f319b7c64ede1ae5d5f9a0afac98f19cca677f795c1b637faf2de6fb0aaec45c0fce1be33c8be4e5fb906a2731ec7753f2f2f982e151ccf3d2ef62c6473762ee7f5b3a7fef94f383bdaf742be6fb878ac678beda13f33cedd818cf4394c5dcdf9919bbf2ce3d31e4b9b3fcb97fa5faa43d7bb2fcd11f8ab4ef7a9fd2e5460c799f76c62e7d3a17f3f7cd7bc678bfedbd98f16cdd18cf1755c47cff84678c789cf389e2c7e6c018cf8f9ec58c5ff3c6eefe5e53ccfa9818c35eb2ff446cffc154ccf78744c678fe48f971bde3f322a6ff477b1eb33e5a77c638dfdd11f3f94fdaa398f2b795cefdcbf2ad31f6df0231fb23db2366bcfc7c34c6fbfe7c31ebef608ce79b38de268aafdfc4bc9ef74ff4feae9531ceeb35c5bcde3346f9b48f13ca5f30e6fea7f29ff079ab9c98cfb340ff50ef73babb17f33ce097b1b35ff73e99fea83716c3de2e2d9defcb7916733f0ee3c5f6f75ef362dcbf681be3fcc29798cf23b23cc5b3c19b98e7797d31f29b6cc9fa3d9c9d18f71f0762c6035d63c46f924fe7d5593f8a1f3b67319f17d91be3bcca8398e7350a62c8f7fa668cf5ce8698ef179a18bbf2df597f8af73e32c68827dec5d0a75c36c679e6ba98eb335963c45f961fcfafbf92b5df3612f37cfd8db12bbf2ff9e84f3f2c8c11afeec5906f7e67ecca1f3c8bd99f0ec638bf23f9e94f3ff6c97c5fe4a824e6fbb90ec6989f743fe3c359418cf20f1531e3bf3763b48fea57f160c3d8b5cfe72799fbb52f4b31f707aac638cf2879f47c4f688cf30eaa2ff69f782766fd7c19e379a40f31cf37158df1be6cacefd8fe58211443be6e648ce7f73362b6e7d418ed792de67a52de18fbd76f62c85bf5c5acbfb231d6433664bd7ffe51cce7b7be19fb952531fd918c31d6974662aeeff8c62ebd1288b93fdf37c6fef88398fb61a131d67fa4aff6c376c6389fc9fea4f363eb9e18fa3caec4fc7dc8b331f6a76b62c81fc4c62e3d527bd2ff3d3d1ae3bc9431cfc37d18c31e75c5fc7d9a8131cec3a97ee9ef7cbd8a19efb4c5f4776ec490a7db3386bd57ff617c7627fde81f051d63acff90edfc55dd18f1fd488cfadb4f8d113f66c5dcdfe81ba37e8d21ef9d95c7f5b19e31eaeb45ccf67e36c67933f62fc55b5f6f629edf7832c6f9a39c18f21f8ec688b76a629e2751f98cbf72a131de673016f3bca631df7fb833c6ef2f713eb3fda64731f757a4bf9e67991a43bfae98eb5b9fc658bf5a8b51dff99918f296ed7e3eff7627e6f9f51399fef84bd918ed6fcce7f54ac6587fa888b9dfa4fec0fe5a5f1ac35eb07e159f15dfc5b047b92b31fdc9bab12beffe590c790a5963d8db9218f28c2d3feee7d29ee8bc57f42ae6fedfbb31fcf7ae98bf7f75658cf72b2cc55caf647f533c767732c6f3ea07317f0f6f2de6f3b54fc64ebee2a798cfa7d78c112f4662ae2f778db11e6fe95c9f933c8ce79e1a62beef696d8cf761cdc494f72c86bca79531f6bf2d3fc8d31c1ae3f904b53fedd13de7577bffd2de18f1ed45ccdf5f3f8879be7b648cf1d514f3f7bb1662be0fa4668cfeb21473ffdde4e1fbc22d9dfb3d9c3ff5fea7fb85317eeff043ccf71d0cc4fcfdf42b633c3f5f12f37c4ad918e74b252ffbdfe7c118f1f944cce74bde8ce13f4fc5a8ef06e7b788eb07c38a18f23c7b62c8f3b132863f7027e679d8ba31c64b5b4c7f4cf5a5fe726b8cf77b583a9f0fab19637da42fe6fa2dfb83e2d37ad118e7333b629e876d1ae3fce852ccfeb011d39f65f931dbe7a52be6fe78db18e7874e62fe3e796c8cf50cce1f8a77c317639cdfe578517cbbdf1ae37ce75eccfef126667958bf0827dcdf9ecc8cd1ffca62e4bfec1ba3bd1fc47cbe85f5a97879ba34c6fad8a718f9cda6c6887f55bed603743fd703661363bcff7321667e33633c9f26fdd81f1bdf8cfe217926983f1e4b62fede6cdd18cf4b15c43c9f3e32c679887731cabb3b1abbf216ceff0d6cff785e22eb79d66731c6dbe4c118fbb74532e39f45d3d8dddfd88ab93f7345e67ac0e39d18e9830358f1e87320e6f33f6732fdf3c6d118cf83e87efae7ed480cf97bcfc6aebce71b32e3bb8f7b319f27f0c53c6fd412f3bc94aee77ede712ee67ee39db193ef521673ff682fe67e45df18feaf31dfcf60e5a13e56ef62fa974fc6d82f62fd295e0b0fc64e9edc8718e5ef56c6f02fbec4287f773146bcd012a3fc304766fc55d4f58cb7b237c688072c1dedf7f92ae6fb02fac638ff7525e6fb7aad3cbedf616e8cfd27e94bff32927e8c8f1e2ac678fefd59ccf8f4648cfd979198eb213b633cff64e990675e36c67a96da83f1d04ee5d39fdca97e180fd547c6e8ffd29ffb57fd8d31ce2faa3d190f45944ff1d0bc23e6fb270662c6bb2763ec7f67c53c9ff6628c78f7594c7b5113f3bc6a9bccf97bf726e6f3b313639c6fb474beef626a8cf3cc2b31f4cf1d8d5dfa93a5f3bc26fbafe28dc6a398f1d1ca18e7c90a629ef7d91ba3fc8c18f997d9ff144f043563f8174f62f6ff8231d6dfb662c6173d63ecdf8ec57c9fc09731e247f617c51bef6731d7efaf8d317f8fc57c7ef3cd18fee15cccfdc84f63f85fcf62ae5f35c87cbe23ea89591f5563577e47f2d0bf9b9d8c51fe8798ef635889196f537f7bbfead118fe5f47ccf7b5a83ee8df95df8c71de6222e67a56cb18f1e7528cfac8978d717ea42d46ffa8df8ab9fe3d2333dea8168df1fb2496cef743c462fa677d6327efbe22e6f3472b63d4ef9518f215d91f157fb47662c8f3762de6fb12f662ee67d9fd7c1fc4a398bfbffa648cfabc88f9fca295c7e7171662c85763fd47dc6f6ccc8c9dbc075fccfde858ccfddd7b31cfcb558d317eea628c9f3ac78be281a7ad31ce63aa3e743eb6690cfd1a62949f2f18bbf29a5d31df17630cfb74e27c14b1fdb65363f8f39297f662f46a8cf527fa138a0fea2731cf2f178c112f1fc58cf7bbc658efb0ebb99ec8feaff860d03746fc168ab9be736d8cfdee8998eb6b9c5f141ff46ec57c1ead618cfd5be9c7fa5f79c6b0a7763f9f57667f52bc31681bbbf2de252fc7d37e670c7d1ec47cfebb620c7f5cf5c1f6289e8c61bfd95f15af5cde8cb17eb01373ffbc688cfdcb58ccf8feded8953fff10f3f7a1ec7aee97de89d95fd8de8a77eec6c6aebcc9540c79264b63ac1fd9f56c9f8531e261e9c7f62fb2be140f9d5e8d515e24e6fe6dc618ef97b474eedf7e1863bc97c48c6f69df141f9dbb6296e789a9dfdc18e9d287f1d057de18fd2f2be6fb0f607f22c5471f3159fb7b282f52bc12de1ae37d296531e39b17b2ce2b2fc4dc7fbc33c679bd8618f66bfd618cf843e9fa7dbdaa98ebbd6d63975fef51cc78e6c618cf2b4a7ec62bcdbd98ef435a8af97eb59698fb6b5563eccf305df1c66a21e6f39bbe31ce5fbf93191fbcccc5f4373362fe9e9031cf6b558cf1be3aea277f7eb53686bef762becfb065ecd273763ff2af7c33f2bf2273be7d93fcf4dfbf3662e41f1f8ce1afbe8af93c20fc9b48fe786b2ce6fb25eac6d84f9a8bb93fdc30c67af9a798f1efd918ebe50159fb09c6287ff920e6f34696cedf136c8bb97f7025e6f9e5a231ca63fdcb1f7f9c18e37cb52f667c101a633ebf17f37dc537c6e80fd257e7b9dac6385fb011f3f9a01e99f67e5d12733eac19bbf2e7aa3fb677a52be6f89889517e8dfac8df3e8d8dddfdd5a998fb6173633c8f722f663cdc31c6fa4028867ef52732fda9f845cce7533c31df37da3586bffb21a6ffb81633fecb1ba3fdafc96ccfcf8a31cefbbe89b95fdd32c6feff4accf1d733c6f9d2bd98e7e10664cedf5155ccf7e7778d5d7a55f733be6a8e8d11cfd09ec97fcd4fc4dcffef88f9bc27f3d37af54359ccf8e52ce6f3cd1b63f46f5dcff9ac3d3786bff628c6fd27b69ffcc3d348ccfda0ae31ece58398e74b589ff20f3f3362947f9c8ae9df2c8d719ef94dccf799b2fde40f6e4f62ee57c6c6f05fb662ae3f7d1923dea7fef2ff668198f1c58331c6a7f2577f2b1be37c8ef4d5fa0eedabfcc17324a67f3334467f5279ec4f97bc31cec7593ad7d75f8c5df965cb0fe5dfd1de9bffd734c6fbc20331fdbf8c319e2fec89e98f8c8d5dbaff26e6f3d7efc6f04f5fc5ac0f8e6ff97f9f7b63f8631d31e4890ac6d81f388bf97b6a1563d48f27e6fb42d9bfe40f36543efdc1f7b231ca9f88597ed618ed3312339edf1823feb0f2f87c7f6c8cf1a7fa97bfa8faa7bf18df18c31f36667f691ba3ffdf8af97eb26f863cce1f0fafb41e3ee982e50f4e5b64ad577a64f9631331e6ab59db18ebbbd764ae0f6f7762aed73f1be379f808acf5dde9ad98eb89d762dcefcf8ce19f95c9f4cf025dcff5f8bd27a6bc356377ffec854c7bbedc92b5be3916237d9c07cbbf59ad8c519f3d31fdbf0763f8e71b32edeff4438cfc8a8131ceb38dc4cccfd2b95f3020ebbc8c31f22b7862fa174763ec97ccc9d4f7732de6fb014bc688379ec4c8ef60d7d39f627bca9fb874c45cbfdc89f9bed9404cf9e6c6584f64feb61e772566fdc562fa5f77c6a88f5b31d7c733c6f0bf5ec428bf6de928ff2347a6fdae158c71de6229e6f3353b638c175fcce72336c6380f67f9f3fd4f2fc6184fec3f21edf9742ae67acead31f62b543efdbf97a618e5bd57c53c1ff9618cf7e1b2fe6dfdad2da67f766b8ce7174e62c8139e8d71feae2266bc64e9b40fec4fdaafdf2ec43c3fd413733fec620c7fe041ccf3a22363f4afa198f5f94ed6fa4f5dccf3582d31df477f31863cc63caf903376e921fb83f6e3479fc6585f698851de8bcae7fc1d3f1863fddf18e56df7c6d82fb3fce8ef6f8cb1ff427b2dff2a9e89f97c4cc618f3f38798efe3898de1cfe5c42c8ff2c45cdf19adc49c7f7d31e3ab9e31faeb9d18e59dcbc6f0c7242fdb77712d46ffa94b7ecec775c9c7f9789137c67af5a798ef33b574fa972a8fed7bf7640cffdbeee7fb61d89fe5af0ddec4f43f1f8d719ee95d4c7f6d6fecf25f5c89b9df3131c6783b8a79de93f393fcb5eab3b12beff82e667d148db1df5e1533def68c118f3c8ab99e7d34463cb615f3793df63ff967d140cce71b9bc6583ffd12f379c1b631dadfd2197f978d31bf707e92bf766a89e91f3d1b637d3512f3f7204263f8939f62faf35fc6188f5762c8f3c5f691ffd63b8831fed796cef53e633effe41963bcccc4902f6c19c35eacc5dcaf42fbda7a5ed027d3bff16a64fa675e864cff6bfb0ab6f7ffecc5f47742b2de4f7914f3fcc3454cff2c3676f73f9ec89ccfe24f32e71b1ffdcbd67ffc2732edb57f4be67ce9b5c5d46740667e01fab7ad4f1c1e8df17c455f0c7d2bb7629e57b074eabf20733e297f8979fe60600c7fa32ba6bfd63186fe7332fb4f7f628cfda7bc18e51ddfc4fcbd2b4ba7ffd412f3bcfcd418bf277126d35e545f8dddfdcb2731f22f578de1efa93ef47eca95b1cb7fc2fad67ac5e4464c7f252be6efb7dc1a637c37c4fcfdab9131ced356c55c8fb1fbb95e6be5f17c6840a63db97c89517e5c10d3bfbd37c6f9e39918f9b5258fec4b460c7d87925fefc36f1b637fec45ccf743dd19c39f55fd713ee95d8cb15e2ffdd9fecd0f32fd8b8eea97f349503186ffb516a3fce89bf17ccf52ccf561f677edc7553a629e87ae88d97f1bc6981ff762b667cf18f5abfc68fff35331d70356c6f0afdfc5f4afe7629edfe2f8d0f9bfc70f31cfef066294b7b574d457f9c518f349468cf2cb6731d79b7364d6f7d3ded85d5f577db0be8f4363979ebd16f33c17eda9d663b22d63f8df4b31e48f3b623ebf7436c6faed5accf7a7dd1b637db829e6ef276dc41ccfba9ff3f7312be6fe5e49ccf1f5628cfe9411737df5640cffb22ae6f9094f8cf2df9ec99c9f1b0763ec0fefc58c478ac6f0876331ca7fce19a33d391f6a3ebe3c88f97ccbd418fe822fe6fb91abc6580f1b88e9df5a7e7c3fc344ccf8c8cae7efffb9fe1dd97a8b772473becee4c99caf333db0e6e7bb3659ef671818e3f99d1d99f6da5b8135df7a5b32ebdf9b9035bfcec8bcbfc574cd9fabb298f3e7c218f777c9cc7ff548a63d9b3f1bc39fa88a198f0ec91c2f6f336377fd6229e6fb40585f9a7ff29e98ef036f89b9ff3536c67e8d5dcff5888631d66fea64f903ba9ff3c9fbab98e791aec8b41fb53763d8c38118f7b732c6785e4ff9b33e163932ed4bf5ce18f6652546fec59d98f5eb83755e635710737fef45ccf9f720e6f3796bb27e8fa323e6f9d86b63d81763aed7b17d656ff357623edf343446bae465fd856563c8c3fea4f8aa2c79699f9b0f62dae38931e2f9ae98fb49763f9f37657dcbbed6bfc4c86f3833c6fcb716733d624fa6fd9c5c89f93ebb82b1bb7f9c11d37e1d8c614f1ec4fc3de77b32ed616b24e679b08598bf5fccfe217bb6df1863becc8bf9fec0b631e2f558ccf7f13b7f3e8a65af565764da2b8fe9b25719a6cb3e751ec8b24f68cfd8ecd3862cfb3425cb3ecdc9baff0296fdc9dc92797fd0252b1e3992653f307e638df75395ccfa9e9ec418af1f25639c071e8aa95f9eccf1dd6f1ae37a9547ff7d7163ecee2f4664fadf998c31deffc2fb63dab327eaabf595565dccdf23ef89b91e1b1b63ff7f23a63d1a1a63bcd5c8f4b7f20b31f72f2b629ea77f37867d5d8af97c3cf5d3f88ceac6f08fdb629e97c81963bd7a24e67aa2670cfb4a7d345ecfb131f6e7b6628effb631ce9364c58cbfd8df343edb5b63ac8f1dc5d4df37c67e38fb9ff9274331e56f90b99e305b8af93c45cb18ef4f943c1ccfc767633cdff821e67a815dcff3cf1931eb676d0c7fd8d99fc45b977f5207dbf86b9235fe96608dbfa047d6f87d256bfc6dc9da3f607e1a7fe388cceb276f648e87fe08acf9eaad2346faddde18efeba17ceadfa38998ef8bc81b63be7a24b33f7f168d5d79e79d98e7bf5bc688df9a62fefedcd618fb4d2f64f6e74e598cfcbe96c6286f2ae6f9eb2763ece73c80355f7d2cc45c4ff81073fd62628cfc3764f6efe024e6fc7b6f8cf31ec6fc3dc1c818fe11f5977ffe1e88393e1e8de1ef5c8b999ff4e1f346b3d818eb69a198e7eb32c678feeb56ccf3a137c6988f7d31c64774658cf5fcb998ef5b888cf1bcc89d98f6e3688cf731b4c56c4f670f639b9f5a7932fbc3e089ccf66ca2fd62edbf74bec41c2f5d32ebfbab29e6fa458f2c7ffa8dacfcd1bf628d97f79931e28b90cc78f06e23e6f3032531cacf1ec53cdfd53246f9d44febf3f58531def7341223ff69418cfa7c7f16f3f90e95cff175f18c713ea74fe6f98acfc818cf3b96c53ccfba30c67986ac98f1beea8be3b12279381e5f60df62c5f3d58d31ce1b7c8921cf2e67ecca3b64c45c2f6f19e379da3b31e3cdad18f5f35515f37d151531e4fb9a92e9bf7f5d89f9fea59931f62b42317f3ff7cdd8a5af7c317fbf2912f3793031fd85d3c518e7194a6294bf0a8c51be319f777e3576e9ddae98e537c47cff49510cfd9fd83f654f2e2b639ccf96bc3a7f513276e9d3b518f24eed7ecaabfaa0bd296f8d5dfa742186bc93d818f6c698fe50cd18e94d31ed71ddd8d5b7affaa1bd0933c658cf7d16f33ce4d8d88d9777a7dfe45afe682f24d35e545760d98bc5c418fef21d99fda3d21673bdad27a6bd1889b97e5d36c6f34c0f64b67756f971fcfb0531fb77c918fe774ce6782fe7c5eccf4fc638cf5611733fea24e67c762fe6ef51dd19e33c4b00d6787ed889f9fc406c8cfa298af97edcaa98fa0dc47c5ea46eecca3b8ec97a1e222be67cd735863d1b89a95f474cfd4e62ee1f5c93f5bcf054ccf3504563ac4f86623edfd13276e9cf2f623e8f7127e6fb936ec48c974ec6f0a79ec47cdefecdd8c9db503ac7efa1648ce7ab0f62ca7f6d8cfdcabc98bf97f06e0c7f5aedc7f1bb0a8df13ce7ad98eb7d53638c5fb507c76f3434467b1b73fc3e1ae37968f5278e5fbf6f0c7f12fd77a2f9fef102d6facdf42ca6bf3823eb7c4487ccfa6d6e8c5dfaa146e6f8a88fc5b83ebb3046f9bc5ffdbf933376f5392e8891dfdb9398e7d1afc4b40f5963acc7b13cf5f7eca731f6178a62fa4f8198f6a727e6f3b19e31cebff5c9ecbfd5584cfd4331df072479587fed9331fa679dace73d42633ccf7623e67af39d31e68f9998e7192bc638dffc2ae67e53c1d8a5c7be98fd2f67ece48f1ec55c1f9d1aa37fdaf5fc3dcf8d31fcad43c64b3efe7fea3b1364bc4c988932b1fb4c32d3e43b48fe3ecbcc93f4c50fd7cfedfac0ee5ff2efcbcc2a33cfac93efeffbc09bcc36f9a4d7ed7e2877915e97794fbef749793377ff47e690fc3bcc7c668e995372cf39f9f78f72b8efcc57e6922927df95448e7d921e6676eebab2932b95fdce7d5793cf7da696a6bbfbd6943ffdfb83bb4e72ec7efaf692bcd3fc1e93fa307d7ffa4ef378729fbafb8e584eaa2fe40c71dd9fd63fca4df5803c8d44bf59f29d96739f69fe54dfdfe507bfd1e3f7f34fe56ba1be5dfe3fddf7a3fe890c903bcc3cbb4fcbe9e565daeeba4ef2b1f6d07d6939bfa89f9ffbc93fdf3f67497da4ed1167baae3dc2dfb6573a46322f995ea69f7cfe73df03f7794dfefd9619269f41f241fa88e93f5fdf77f7f43263fe3dfdcedaf5df9ff4efb94cdefdbdf09bfb919e25233d9f293a19ae32d7c96794f08f798df8b9617ea5cc6de6d5cba4699e97c9279f9e93eb353348fe0d7d24e78bc93fb0cfcb4f69df9f41224772bfe77b01af533e3fea9fd49317e2fb3732feaa1efeac1d7efc649deeae1c2ff0a25fd4bff442f97f9cffc0da7364727ddf37fe45f93f7f523d63777dfe77aef9aecf5f7fff6bfd73a4f6b4f6f84df9e918f12699d17ffc3375df85e473493e59fe3dfbc3bfffcae7d7d7ce32256f6eff2e249f71f219b90ffe36b6eb16c927e1c43e8cddb59049f26593efacb74cfebd4affedadbd0dcb9cb38c6df2b7f483b293bf79bb9fe4824edbbfa497ff3b3afef6b3fde1f3abf47fb42db64e1fd58ff7bbe5fef5bc7fef3efd7bfc27d7173233eb1fffb83effbecfafda63e4e6118dffffd427fbc3bf0bdefbbf31ef016d40decd2505fe6dec3eb061237e8f5dd97bf7197b7bef23b9eff0635edea793338bef64147cba79067fcf7b6bf749afbd72e93befe89dbc4fefec1d7fa39ff4d5e7d7f571e5f27949e678cd71bf773f3ef95ffced8fcbf8a34fe1877fa732fc71d97fa57df3bfb9f6e77bd51ebfa767faefe57fb0fffdb9fc7fd81e9c477ecf86fc7b3eb281a98dde7a5f7f600fff395b76e1f7dcd9a1647ef00e9c4bc666c3666efec07c90daad06d3679c473487387993113077328fdcf7c46c5cc1e690b99b67ca6efed9fc9d8dffb697bfd2756bf6fc83fffe57f4ffe7dae3db662ffee53cbfe7b8d16ff8fb6fe33ff914bc4af271f5efeaf73fdb1fffc1f6f81f9b47642f0adedd3f6dff7ee7e355131b5f457ce162869fe690242df579dd77d2024767f752bbf5ca98e2eff34ce311e7977af7a96f9dcc3ba1f357178c45d21828b1375ecdcd2d3fdb5dc55f3fdbd8efcf15e7ac3bb3e97f5c1fcaeffbfb9fa9ff9fe726378f780f3fc8fb8fe5fbabf6fdb93cc55063fb0cfeeef3db79e4efebebcfcafe77cc23d9440eb5c74fe5ff8fcc23b22fce267b77bfb4b7bfb663bfb26b8a21befff6e83d7975af91c41023171f4c3927e033f29aa9bd4f3ef83ea7763fb372f2689e28fcf049e7a1563237a5dfcf5edbeb785def25f9f4bc7e323f25adea0d92bfcf92bf2f92eb5fcd16fe6c3bffd8c787bd5afe8efebfbaff9fb7f53fcf65bf9573fe2fe58d0fea606671c7b7ccb3bfcbef57f308da436df6f7f1d7bf6f0efdbd79e4efdbc3ca77f388c6ce7fea3bb54f3fce233f8fd51fe386d10ff789658b0b991fe708b776e2a56b22c3cc9537f2c65ed6cb7979afe015bd2befdabb493e575e29f9dcfa4930e6fb7e90b9f2c3e4da61727fc47b938f1ff9b17d265edf9ffa337fee2ffca5bff2d7fec6dffa3bffdddffb1ffec1fff48ffec93ffb5ffe25f97fd9aff8777e35b967429f3b9533cdf39e6b3be31ff4f9f1e3fee6d77ea9ffcff5f0af7effc13c92ccad7393fb9fcd5ff3c38f6b913faebdfd52f71fdab290c9fb0fae8df5f9e3fef1efaea79fdbe3d7f3c87f7ecd20f5fbb136b474e333fdb7fbf676fe631a53d00f756b476e0c17143b308f92ff94c614a9fdf6eb7ec32bfa4dbfe53ffb6dbfe377fd17bfe7f7fd81ffeabff9437f947cc6c9bfb37ececffb05f7db95d7fe8d5ff26f834ce0057e10f8eb2074ef2c9a04d36016cc8345b00c56c13ad804db6017bc07fbe02338049fc1313805677f187c0597a01c5482bba01adc07b5e021f93c064f413d6804cda0153c076d674b4bde25e804dde025e826b2b69d0ebfb65ff3c486cf7e595f05d549d063fc93c6482e3e4ad9fd4d6b79a5bf50ffbf2d776aeb7259d71edf735bc1c9af3ce77fa15d110f16d28f6b1fb41bf249dbf162f15b89b15cfa777c2ed6b6a3241ef9a379a1606b718a2dd3fb276e4db1f09764fc2bf5f3dd1ebf99bfdd3cf29f9c43e06fc3bfcfa6fe7b32564b892d5fa7b141fa1df4bd9d5b931a0403ac1d25df57ba2ff1fd6f93cf551a0704afc15b300c46c138c806b9201f14826270155c07374129b80d33a117fa611086e9d392e1249c86b3701e2ec265b80ad7e126dc86bbf03ddc871f091fc2cff0189ec273f8e5e7c24b580e2be15d580defc35a92cf43f8183e85f5b01136c35692cf73925f3bf9ee84ddf025ec85fd7010be866fe130e151380eb3612ecc8785b0e8de93711396c2db281379911f055112cbfc6e4c304a6cb87ce21f6c63a27ffaefdb28ca60ffa1e4d5828e57cbf4bd4b14676e13db9cd449c2b9243d49fb4bb6f4b7e57ecfcb2f9421fd7729adf7a43dd6d66ebffdfebdfc0b5ec6e6f8beb78826c9c80892bf8d5c1bd31748d709bd653008fa98c392be7072f73b1f239afe8eac5927d7b71caaa79c9761de837fdb5c9bb6c72fe6bdff9179447e266cce87b32fcbc4a65c308f60cf41d77b27ffd131e69a49344b7acb3c5a44cb6815ada34db48d76d17bb48f3ea243f4191da353748ebea24b548e2ad15d548deea35af4103d464f513d28478da819b5a2e7a81d75a26ef412f5a27e923e885ea3b768188dc26e344e381be5a27cf25d48b8988eaef4a9ab701add249f52749b7cc77126f9788943364ed29311135d47b53888d39723e6e2f42181493c8d67f13c5ec4cb7815afe34de621895f165c4ffb95ed4a6df8dcec96a52573885b6f8bb7c93c7449f3f09ee35dfc1eefe38ff890cc9f8de0d56b079d64b424736b327afe9a9dfcfef7946d82f6d825f67f445b9dd8e46090fcade4ea7ef6f7b2fd7a1e090671ba527eebe693527c4cbcdeae774858715ac15ba5ed1ccd5cbbcf5dbb97113b629ec934fec4c66f3997a4ff9e51bef93f30d7fd953a9a67163fe4677abb79e4cffcbd7ff53bcb3d04d8aab9db87c57a503e3e25769036223ea7fb0e3687a436289fee757b5efc155fe2725c89efe26a7c1fd7fc5cfce00fe2c7f829aec78db819b7e2e7b81d77a261dc8d5fe25edc8f07f16bfc160fe3513c8eb3712ecec785b818a7cfdbddc6377129be0dbbe9b1988937f127c1249c4493f4ec681cdf4cd24f263dc8339946b79359184fe6934c3a42260bf79d8e9c78b24ce796a8e6e6acf429ff5572ed3a7a9c6c26dbc96ef23ed92776d24b7a77f8439cf2f76b35b2e1df763de1a033f9981c269f93e3e4148c26e7c95792e365529eece2f2a432b99b5427f793dae4c1cd2163daf03facffdf7e687fb106f896d96546dc772f310df342fe4ff31d5b3ba56d7c993c4e9e26f54963d28c8f93d6e479d20eba6e9e48e7c1816be7db4927f5b0927b4ea90f31e926a36499ca3149d7d57e6f1ef9decf1938b9d792937de45fee9f3fb4c78f6719fe47e711ef843d87f43b099f67b037de2bedc0dcec177ce2793a97d0b6a5eb1edb34cd3b4c7ac1383a4efa93c1e475f236194e4693f1243bc94df293c2a438b98a7293ebc9cda434b99d66a6ded49f065e769a74e9693c9d4ca7c9c8994e67e134f6d25e3d9d273dfc6a329f2e925112c7c95c315d26a3221d29f3309eaea2da6491cc13c98870bc0ee3744e49fe7695fc6d9eb0fb7b3a72a29b64d495a2abe926ca4db7d35d78ed3fa536339139b191ceb6febeddfad9ff655afc357d9feea71fd3c3f4737a9c9ea6e7e9d7f4322d27f3cacc7d5aaeae66c18073c03f328f680d47723df35b6b852517f3cc79ddf6cff34fe690acb771f794a695ccd3f46e5a9dde279f9a9b030fd3871ff6aa7406c2e2a9a44ffcfd3cf2dbf5d09f63933963d3ad8b47fe4a3cf657e791dd0f73fe6fe791ffe41ce26c28f6aadd9cf0367d9c3e6506d3bab79f3692ef266d91376d4d9b49cbbfd28695b037317d4efcf9743cdf24ff6e4f3bd36e104d5fa6bd697f3a98be4edfa6c3e9683a9e66a7b9693eae4d0bd3e274e05d4fafbc4e72fdf5f4665a9adece32332feecdfc59100d6761d84c3f61308b268bc4fe7bb378969e6e4de696f4cce8641ed566d3e493c432d1cd2c1949c99c12612e494745728f1b1d5132d7c4c9e8982d66cb49fafcf94deccf56b3f56c33dbce52dbb89ebd9bbffd67f1c84ffe711a83cdf6b38fd96196f892b3e3ec343bcfbe669759d95bcc2a2e0a4e3f99f4ccc0d467bcf387f5ff4bdb9cd671ba0e354c6207b7ffe3ce2aa5f5df4fedbec58cf93f5b5b4abca663dac6a94c491eb7d3a744cebb5975763fabcd1e668fb3a7597dd69835670f7e3c6b79fdd973125b7666ed59e22da631699affacfb87f348fe7b5ef3dc5e7832475fdc19ab1ce29e7fad7ffed01eff7fc523a94d4dd762121b327b99f566fdd960f63a7b9b0d935677e7aa129f7a361bcdc66e7e81ad99730d6b36cba67673969be5678559717635bb9e55a7ddd9cdac34bb4d0df1dc9f07f3a443cfe379322dccd33d8d85d749629ac4d79dcfe78bf972be0a3fe6ebf9269eceb7493cb399efe6eff3fdfc239d2726f1fce0e6826454242364e146479c7ebb11948e8a79324f6492f9a3947a59d1d5fc331d59613c5ba4232b9d63d29115c6f3e3fc143ccccff3aff925f1bba7f3d4df5e9b4ffef77b1ddff1c86f6d57e2b524f7a7f67136afccefe6d5f9fdbc96f43c3f896dc6f0f99d0f5ff85edff94bf3c8cffb33d9d4eb49e680e7f8387ff016691bcc1fa795f9d3bc3e6fa4f313d611ff8a9f90c1d984a4bde6cd648e4b4688d79db7e6cff3f6bc33ef2635fe32efcdfbf3c1fc75fe1616e7c3f9c86b7b87d4134bfc05c85ff95d59b36ece9c3b3fa3e0f46db39f2ce88ffc3be690bf8f0f7fbbaef5ab75e651e6b7fee09faf5dfdfdd8fcad6d1cccc7f3ec3c37cf87d7f3c2bc98f4ddabf9f5fc665e8a2ff3db697d91044c0b3ff3b408dc9ac84d66b70817d1225e4c16536f9f74f6a4c72ce68bc562e95f16abc5da2b4c0f8bcd621b3716bbc5fb62bff898be2c0ed1447bdfc9f72ef15d03efd5cb2f3e17898fb6384d868bf3e26b7159941795c5dda29ac42f01e20cce11737ed29191f4fc244e99c3fb4a6390d902f14afa77179378c9dc937a67494526a327b7b85fd4160f93f36c8fb596f89cb460ee776d79dee691fe2feabf94d8e44ea6376d24231e6b7b6e7fdfc510b82e89db9c8f3ff8d3f6f8f9ef05b6c95bfcb5785c3c2dea8bc6fc71d15cb416cff165d15e4c179dcc9bb3d35799dfdbaf706b5899c1a2eb2d162fb3eaa2b7e82f06fe79f1ba780b568be162b4182fb28bdc221fe5e26051089fc3eea2184f1757d16671bdb8599416b7d3e7593bb1689954ffdfc4233fcf2723ac7b7af7cba4132ffd65b00c67d965b4785cc6cbc91fccd3fff83edefc57fdd7cd23b2651a4317fa7d4bef4c7f74ccfd0dc407df7baa5ae32ed9f9a60befdf72af239d3fa6e9795bafb79c2e678be57cea7533afcbf972b15c2e57cbf572b3dc2e77cbf7e57ef9b1e82c0fcb4f9495fab7cbe3f2b43c2fbfbc56e2e377d2329797456f595e569677cbeaf27e595b3e2c1f974fcb7ab4593696a90d4bcbdd701d0d7a71bddff9f107b76fbe58b696cfcbf6b2b3ec2e5f96bdf48749276e54a471c7f71c92f6fe345e413c82390523268943bacb7e38459cb2282411fc743958be2edf96c379c5d9269c3bfea335a1c2efec8f7caf01ce28ff9cf3c685f5bce2bec09c76750a5bcb3d9513edfff7d9b5894b736b8436075d66f9e568395e6697b9657e59c8ec3335c438c93d17ed5da5652d8b49ac71862fc0f96792ce67de615e5e5e2daf9737cbd2f276955979e1e3caf75f43cf1f466f613d5d335c05512dba5985ab6815a62be7abd8cfad267edf7f5f4dfd797c5ccdbcb62b2febce615f7866dbcda18c89dc9a682243fabd5acd578bd572b59a7657ebd566b55ded56efec73dbc4e3dbb0ed57bc9eb27a13ebb7a8d739d32ef06dd8c7d37e3247d93fc44d33ce237d8c45e77b8e3257934ee68aeb10e9f9d60b6de2deed6deb7c925b0371bea03b139bfa8be9b5eedfb97435907f1f611d63b55f7dac0eabcfd571750a26abf3ea6b75595eafca61695549fe7db7aa6606a9bfbdba4f7ce380f7d4bcfdea61f5b87af2faabfaaab16aae5aabe7f974b25bb527afabceaabb7a59f516e7557f3558bdaede56c3c973e23164bc6a807356a93fdd71f10c6c6131b18b897d4ed7825623af3b7b588d57d9552ecaa66b59495c314fe30ace23364ae252ea51618424692e2e8157164e9211924d3cb6eb640ea9ce77abfcaab02afacfee1915d8a3fc1fee4d8f7ed89bf85ebb497dee4ff3bfd333cae92a7929b5a389cfefce1aafaebcb34bbf726b5b2e1648eb1f7b4e2ece18bb361ab875af740f1c6b5569fc779b795da5cf631f5737abd262bbba9db6dd733235b7fe98b46b347171c9659d49f34ccb4af2bf4fda7618a4fb1f97b5e7f5d7fe3a5887eb681d47c3b09dd6593a1ac2b95bff737595d81d7eaf93786f3d4d57ced7b3f57cbd582fd7abf57abd596f93d8e421f9dc79fbf5ce5bacdffd5912af74d7fbf5873f4d466198f62fe8eb62da974c7e7d48aefb5c1fd7a759757d4eaefd4aacef7d123ba57b6c2eeef58ee9596cefe4f661ae92fbf73fcca5e893d9242df95b6a3126e989a212e7b091f7eeeadd9d23f363cd273f9cd7d23c52a00f3d4aa43cb9358b743d7de5d6b277ee4c54ba4e9572d3edd9628d7b9eae6f24df2bc5206859d8a3f5617d5997fde1bab2be5b57c3ccfa3edaac6be16efdb07e5c3fadeb8b977563dd5cb7d6cfebf6bae3f5bd9e375b77d72fb3cdbab7eeaf07d3fefa75fdb6ccae87896fdb5a8fd6e375769d5be7d78575717db5be5edfac4bebdb4d66e36dfc4db0cc27b59ed8a7789b29cc5edc1c72e2d9dc915b9f4fe4fbffb87bb3366591a56bf8c770cea56559eaa18288080a8a967ac63c28f328bffecbc80487baebeeee7777f5eefd3d075cd6e0809019112b62c50a64b7c6da32348243686a7d73003ec12699df31c12708677077df41d9ed0e697f07944f5b5a688576e8846ee885fe75105ec22b2db4dfffcf6b0b90e7bfb4cf7bedaf88e8ae7e01fd2e67f82ec88f927a12b691681538ad2f715bbb889e8f735cd8163fd59ba2d656c281701abc260cc2308cc2384cf42de58629f9dc3023f947f4990ab573d930b74a84ebe03d218f06afdd844558fabbb00aebf01636e1349c99c7903194fbf5f29f7d6e7ba0203964c379c8858b900f97a110ae423194c275b809e55071ec701bee42d5afc37d78083fc363780acf61cf3f58b103fd1c90c322710d9c031c6ad877594ff22f2d874e019e37e4fa30078170b61d1d6a4b01f6a95d0e0fe75031672fbed7413ccc0f207e24b2b7c8674e5bbe01b947c887bef0b5089f2a0d0bd847f61a79427c56f43bce37215b82f6e11ce7a886d4947e0bdfee7bf28d823a07798fe14bdc0b798f39750b076668c9261fbe87c3f0231c85e37012d15a5f2f232ad2223d322233b2223b72cc508bfc4be4469e2d3a66e49b6174719ae81a055168ab5114c5411d2551aaf5a32ccaa3222aa3caec4775748b9a681acd2226628335e4e8a33946b9c47ec45d6c4d78bf11e748f441577c255a447cb4d46f8668d8c8f63928ba6af1c7c39760bce291c31c4642b442b6d132cf8618899114ada34d24470b6743f991d2d61d3accd1ebfa52bec1055fe3df47fd82f4ad9c9efcc198f08cf17b0e706fe49e56b1ad43ffb315ccae247c06920322f78170b2200f66d013d3a2e8681bed22155dd37d7470a7700d6899a290df65c1fec23542cff98c8ed1c9c8a373d48bfa9412bd39b2c64683e83d1a461fd1281a1bbccfa2ebe542f5d5f05ce7d9f77696e4e14ba2494cc7947984ec398a5071163db40c25d6d0eeda9b47fda61d63dde0030b3d1a86189b261f5bb11d3b8118bb9aab398e8c708faa39b117fbe8b8447220c7d73888c3388ae33889d338a3ad20d52cf03d90a3736377837c8ce2ac5f3973c011a7fbface3471acb247f1128d7d34e4c8b6718e7d50dd72a261ddd47181fd0889df499d1572491b478bcbb842675369725cc737b46b26503725b55dd2eb87f1c100b8491a8ff62c7a2df2c4b027d123dad3e83dc076e1e7a3bd1a37f1349ec58c798d546de4e4316b24f13ce6d055591882e518bc41b9a67132fb311f2f63215ec5a2cbc652bc8e37b11c2bce2ddec6bb588df71a4b29f121fe0cfae8f7637c8acf9613f7e0ca5a5adc8fdffcf77810bfc7c3f8231ec5632b6af152d4d668705c8bbebdd1e649dc7872a9123aa1122dd113c3828a628b4fee77fd81e621caa2ae4662da703b94cb24b1123b71a28fc44dbcc46f6bc8e193ff707eeb4bbec323bd174e828ded207e2ee0316701b92064b9b09dd7584746d7788f7e6f6b2670edeffea38bb9010f5eac0a3fa25d945c12040e92c0a992d03d438d5e5bbcf4c46c92288993c4721264852ea324d312334cf2a4484a834faaa40ed71736b9250db22a0a8eacecae9ef4e443fc67fc86eb4c9657d8e8800a2eba76adaf463b05ea550adc37d82dc07148a638d7e8988b649630099bcc132e59247cb24c8464e5de12319192353a970d3ae44449b68083925da29a74b24f0ec9a723535b974d8e2e0b3c6ddc4b347e60bb16d335adaf801c59c7b3b3e9f88513ed602cb66af95ab876e98814b2ab2e979c9273d24bfac95bc027032f8ecec97b324c3e8275324ac6ba994c523ace520ace22d0607f437e9d52528d4a531dc597318a5729974b0d974dcdd472d6949adafe25387bebd449ddcb8731d1fba9972c523fbda4d73448c33432fb696c2889013e214d92619aa2c865efce352bcdd2dc9a99615a68fdb44cabb47666c132bda54d3a4d672913f329abdf2c279da79c5ea3c78576b4e4944f97a990ae523195d2b52358f0cdcb748363db3295d17706fe2ff225a9926ee334dda5aac9a77bb43f7440ea5d3cdded8e6e87d8866b5f21afe5a587f4333da6a7f49cf6d0e7f4d3376f0cfd89c4d6d37f9c1b7cc623afbee4ed09a3bc9108c9dda403740ddf69211da61f41908ed2f1b5974e325a77332ad3342b3901f7b8f59b8443c5d1a467b2c38bbb0e9f657a6638fbccb485ccd2b5cc46f73d45d80fee9f1f509993b9061f9b869579991f1eb24b5a98c7ec9a0559082b1afd1c65719618c245051f1bada0aa0ac7ebeee8ae5f8bdf3c9c2d6fff6e4e5aee826320f003dcba2c453fdbe610ed2003b80fb0832e3b33ccb22ccfd0e75f76da31d96465566987ac36796010c1f3215b021979c3d78ed92d6bb26936cb988c8d2ca38c3eb279c6810f74e40ce11e5f813c1cf818a8d3e88a8bfc4ec6a3359ce0ff2b997631706f7ee7cf5984c55657acb3d2e60020eeccb36526642b03adb8abe59ac05fb290f7cb44740692e584ef06aff50c3ebb7971b2ced6e8ac36991c6c3225db66bb4ccdf6a6941db24f2dcb8ed9293b67bdac7f99666fd9c073b2f76c982cb28f6ce4c4f6211b67936ca5bd69fd9c46df766d69396d3939a5b3b966f28696eb0857e460f34d37377233b7723b777237f7723fbfe4d73c407e6e95877994c77992a77996e7ded116033d2ff232afd07bd1869289e631aff35b2ae58de96a4be43b429217caa7d8eff55afc34ce67519433396b1ebdbccb67913bfb6a13b1ad04dbe7c53d934fd27c9e73e83b2c723e5f5e132a46982cfecb39f90e8f7cf5251d3fa9aba92bb990af723197f275bec965433024f4bd1493cfb739f2adb91a3bf99eda0687fc80ec66c7353e61bfcea3efbcb9f762227b093102f23f0a3ad4fcd365f3637e021c904ef273decb9679ffba4806288afa3094fc2d1fe4ef9a9a0fcd3047bf27d37c948f4d2e9f14b461a2950eabf98de4021ff8ed97c373dd977a537b5dd17ddfa0d75de1b1a09c2bf01fc8f3e0fae29ce1d950e0efb063aebaa118be21161af14bc08dc0381157700da5d00d01ed9e6361a0f773cd7e8122b6c2cafcc22e9ceb67226851e11aef8517d78154f8f9b9b8049be89c9d733bcde07fc5b5089c2da584459b5b23fe3cbc602d23ccbf8d29eeda146111157191a04f4c01c142f5acb50f66cbbc40676d6c5cb3c8ee8f624e7971911745382ecaa2d2d4a2463b68a31df41bdaef0b74d6b77c5334289a5a187c312d660513d6e8ccd9625e70c5a2e08b6521186ab12ac4424af2625d6c0ab9508aadc75369b12b54eb54ec938fe2507c16e8bd8a53712e7a45df99176ffea51814ef86560c8b0fcd45f6d0376d972d46c1ba18eb8d6b40aec5e48a49499794553a1b7a1fbe61fe29177154536a38678739a8a55e1aa5595a971dd4d1c196e13bd9d64a1eb92d147f2b975d6903962a518458baa557fae525285a6d905ecb1f3a3ff986effa33bee291474f1cd87b9c8fd24c8405e6e5b50c8ab80ccb0845a50ae490cc11b2dd23db2a634b2b13932fd3320ba625c20f65611fcbd266114e819acb7b595d742a45b13c8acb35377d77b9b2a685f25636978db3f39b400e96e5b498eb5584ac8af666d4e5ac644ab69c979c390cd964e74fcb45c997cb52285766cfa6033b1fe18aab635b91807d05f6b3249fd5d699bee09147cde9c927b78fb07b601d95225e5f0ef95f29e15c998ddeefd9a73fb2f28635727c17c2bc51b9ee2c19610601a32831e1fa203fc3c1ae8944ed006bd41f6a2a649ecb4d29978a1940b48670155f6ed1df76c5a9548b416e96fbe77e2084d38a7b7d24a2c7e5c116cbcff2886251c31f00a38f30f9c8be2f4f5d850d9fe9d3a3e1946782be906d3d92bd8c7eef11ce2cda695ceb19fbc6ca72f429c4b5e8cea2e796fdf2ad1c94efe5b0fcc8eb72548ecb49cc557445555aa55786f15e999555d9a55239e9d1102bd7505ca3f220a22ae5cb32b735845f4cbef2f50bb5c5755752171950fbea62d499843e57b6b4ea5a05c1a40aab88f20127215c95b6361bd761aab84aaab4caaa1c7234c4d695275c73c70c46f01d70c50bf46331ad8a7097c455595555ad2ba1013517c89fb4d8e17cd76679c4b97f8647c83937f79f4f087fe49452ddec895169fd2b8adb81655935109d985c3545361406d08fcd7e30d38ed5cce023744d2ac672a2ac62abb915b7b872e49815572d2abe5aa68e3ed2fa9590ecaa95197891c95f114aae90af4536d8a92403e13ae89331b46a0d9d00e87f9ba0a8e40ae1856a5bed2a3531008380cfb0ef58e38593e07fe747daff3f67d45f0e608656fbd75cd893efa6ec2f7f6fff463dfe47f063e7ffd1753a90ac0bf828b0e2856688d104dddb37d891f877589f22f24d22f24d42f5a9a168ce3c5647f49d4fd5d9faac7a559fda134c8df1481fed97358a49e7d55b35a8deaba1b18738cfbea0386f534af7b8d2bfe72c1e7502882b315716f76ce0bd6b60fe2cd85e38ebc474e0bd901faa3eaa51b5f2d46a8cce64624e6a145d0596191653adaf9db5634dd55a88ee388a851573a11dfc21dafb28fa8148afd603a6463b17af60dbd26ab3b66abb766ab7f66abfbe54372a455145494da922ddd0c374101deb6b1da03b3a41cf0deba88eeba44eebacceeb22c8ea1276545737a9abbaae6f7553879504dfcbf5ca936b828d238c78b4628ec87323f45a4feb59cda414c4af388722b7793cd05b3950be2bb96c68f897e4e4c8614ea5eeccddfc52ebfe8247082f0a672e39b2531c29762f4e64d46c8c22087437f1f54ca6e87bcfb115ea5753e2eb0c13d960aee6ea45cdd74bed88ce91bfd26618d7b51068995a8cc38f7a553215c29585657850a7305c43ace78662235c558bb504f78bf84a7382ef1fb2e16950af8b65ead79ba244f703ed18f477c910a133a0f3adf755fbedce78d4471e8ff6e3117c03d53ea2f554cbddff3b5ff4f4fc97cf00ae36c6855daed1ba9f0fda21b5d2c600542901e70e59f696a30dcfc7d97da3dd5d1db702769307b9b69aaeb7496a086961f0f5ce146bb5ded7077b0d7ba4fea44f9e501febd355adcf75afeed76f955a0fc0f3619ed2d3956863c97b7cde1d6d4ea38b4b5ff84ee8d3dfeb61fd518fea713db9d137eaa6dd90b93227650cfbd83c427d02e2cd9b09758afb5e17a209f2416362c3cdf1cdbaa1bb7a736eeecdbbf99673bbe8f1ed7a0b6ee12d825cc52da656b784aaf59d26dfd208ed44dbbf65e8fd8eb7fc56dcca5b75ab29e576bb359444cfef36fe4c7956739b46e16d766350f03beea22c6c01ac1bb29d4572636ff31b97f76f0b6a47ec0bda916ecb796de8b333bbf1ba7e5bde38637013c251368cceb755c6dfc45fb4a57ec52351cb61257d8612f24b5b47be49b7f56d6338f91823d8611aa16f2cdf94627cdb22cbc111ee714c3b576437258bb9ed6eea6daf5f82258ab3d9dbc1b16f9fa91f4a805bb08fefc34ab0b14f041b8a563bcec2de8edd7d6b6d6f00f1fded743bdf7ab7bee1840c7afe99d86a0bb8cf17e3e97e7f8b3fbe1c687de8b6959864ad743943bcaedaf7b1e86aff58378f35d5f9a9dbdbf37a7aca39b6ffc3fd3de3bbbf014e377efe6d606b6d5e0de39bdb80dc531249776bd99cdcded13144d7f7e336ba8d11f6aa0cfe36d1fa0ddd5045047ba4d128aed11ba331cdb0b1bcb8b1b543e398c706d87d543eba63117485485cfef011f0ed1fb6e2be9b9e724106f63135ad1d1baff1ad65730938ed68ac6d2db013b3f50b63c8f8b5b6057d2bccc94536c0a651c433b44dcc871ada7a7345f65433f74da0cf9bb089b4ac899ba4491d097ada9bacc99ba22993aca97ce41410fe114d14af6662736b9a66dacc9aaa61dc4daad1139a83bc3870a1c0fed37baad7b0cdbce1021467bb3e7c2e3a07b4bb9b45c337cb46685629157d52aa3ba352e09cd2db966f8a79538dd848cdbad93472a368c051e29b2dba8e3bdf6ad4a7fe91dfe19131c541ef0cae7b9c352b7d6ff6cd21d965a2356e3e6f3877646c2ca7395a7bffd49c9a73be35f786d5f40cafe9bb5ead9893e6ad19586fcd7bd26b86b1d07c9429bac612c986d81782a76085032313560ce91a83d5d58c1ef880d86eafc07d310ad48b9ab1e31b6d5f4d75c809379a7af221def3fdff03dfa1dbafbf7f89aa9a0959edc83a3e3defb10b1ebeebe9f5ed2ec1533e47f7f7f3c07fc0417025ac2782186e03bc6e35ec43ee119c399cd2f918bd5e9c52536d8aa0c0d44ccb298a6fa6f6d469565397e4b530e36430f5a88fa93fbdb8b7e9751a4c4343c491c608f2d5049be0bd6a7636a5b50dfad7f8b28bc6da476a1a355773126bda51eb19f414f90e642bb45a41bb0f7947d81dc4777431a66bdede5c739a002620680f6c80e14ed36936cd114a3dea3cd461a7c5b49c56d37a7af377d326bc421c4f5b613a9d4e6753c65c4fd9e9dcd2a61c3a165a7fca4f97b7657020dc597ad5fa10cc9d453ec19b0acd65ba4277c3361c175028b235b7e1549c4ad335f21b9be986f4b7a0e7423d01708c830f529b76ad662a4f157465b79633dda147d51d4ef77f098f34ed017d877b6aabc9d3c3f433ab918d37507c8daeaf73d50ed3e3f4942ca7e7696fda9fbee108b08bcd35845394e960fa5e54d361bd997e4c47b8a7d202dce015088fa16bdc71966f03623b496ddcb0b214dbea21be17a47f46711d6215c1d7e3ceb331390f627f3b1c405effe77ee4b19a5f7089ffbcca91df7a43ab746c88b0237eadd57fc121deafbee8c9422b24826ad722743638f811eeebe3f9a46f68389dcce81935d30a29ac2ec3e070755df622cdf4489e1933136a2ca43ea2abc88eed6716a5ceec9993f50c76866256a8a142af1ece6f41bf046d5bddaec1fd1670d5f4e7bd4df0c9e391e0965a9979f03c13a1f46832f3d1df34c889805d03846f229b6d9e482480bc23c23dc48f10e48c6c028a98e08ece2eb3ebed6316a4e7f25363117e6a6661f4119d2e9c319c45b3789650b4afb8ec75e9b2b3547383cf5936cbcd7eaecd8af09c0c67e5ac0a6e60af757556538d55b57568a869bc3bd2ec366b72ca1031fbdd2b25c3450838f7171e0f3e47dfddfb29483d1bf757d063dc87f186b0c8a13ecca6cd6a364bcb193363834370c3bd0e6f7f561f217c5eca875a72f4eed7ba309bd734d8fc720d36efb2d3fac578c6cd1633be282dc0467d633d5b969cc921b030018c119be631ffd0fa33c1c4780e61490e1fc037a3c1ff9338dea2dc0b8e4028926935ecd90a2c12c404b582112fbafe314df24436c4f20e603adcabd9ad58b0cdd4579cf03b5ff2145774f9adaf111abadf9d1f79f88ce775d4ae2fca7ee098675cf3127de1d76a2d3e76804f07b948723de0bb90cf34bbffa3758522d77026cea450bf1898a77da2f71a7a0b743f10dea468ec47da3e3f970d96b3f50c6181343470a7aaf9d41f81eb0210d75dc999747bb78b4bbf72639faf1078d06aea0fd05979d38cc4b4717f2627f94c996d67bb993adbcf0eb0136c0dbd4f974924d9e731ec4a7388f00a3ffb9c1db5c0655b8ee806dbdd9c3a7479246a373be9d7d9b9d2673d4705d65b7c9df5eb53359fbd25d7f200f502c2e7a16fc0416b7101f8850bf43fcc06e8fbbf1b0a7c5e9169c7d970f641e55057c1b8c3beeb94603e41db774ef8600dd101d615f43795dae90aba9ee7b6aeffe77cadd36c145ef355c4cfc6d5cc3c829a04ae1ba088a172c39bb59c4df24f86662883af5c40d6c8c70f19ad10199d31d01d47889c31198bb1cd23836e10e3929c8eeb90b81bdb54ca1fc0eaeee2f616f729d38c6080c4045f4156ec3469f396d80e8385449ff161288c17b7999be798e1ebe33778e40f7d0cc96be1f3a2be721cbef99c679ff49cf77aca9b59237f50a3fb981559c9f8a091c35c982b13405ddffcc096de31df907546d1381332515a32f1f5c824f412f387a15fd66b79ce5dff480fed1764c7a625933299e538a1396172ec3b0cb035b053a02e92184c911eaa6d3033846006f915438403f90011f62bc96b11fc71e7caa22bce94e017f03eb6628da98025cdd4cc2d1c320d336566d6bb76601874c63d1241c0de7ee45a001f58385e64d8a9e932983f46b79c4e2e82feb53eb2e915ae49abc944538b29e4fad16344f5c33ebd0f0ae00f3073376ef59f0003ac09b70cfc67cb92e6184eb3980503751c11459a3cb364042bc15110e9c786d78ddade6fdc774efa62303ec1ba1f1d478d4a9915d63779239cd52f35f7d3173c825ee32d19919198758aaebdb106ff1a3060df194f3b963eb36164cd4d878c125880134caeb8d56766cbec18645d1884c89903f3c91c99538d6c3e73cec78035989e6b927a4a7b2f4c6b8c7c08c9e9f8e49e9a3da6ff72cf70fc0f11cfbda671b7bb17d5e4a2c9c3c7bff88aaf59db97c727bedb4b16981c45e69ab58c7ed63b7c7b7f4efb394fe7e24336b75d1ffef33a839d862b0c3837178acc5ba95c46cc206399f7f08319321f5981b3171cf85ca88b30a362cc8c994910514ad8a77c96662956837bd6aea7966f87fd888bf3f1327a96ce1aac6939ac059d3196761b9a1cf0692c03edc92b6beb39ebb02eeb5ddf589f91d80b7b35433600de8c76cc4443841c08bc8e0d21176558571dadfcb321428e1a3c1ed44dd808bf9fc3c66c12aed9748a6ca3763204d780fa0ace5b436d156b92b4b6ce31c7f8f3336add72ae4ef7de10afad7138585f452e5cc867c1fb251b4d65d1f95a33b4ab4ec8fe57c0d86fb5df635a68fb1436f73e01c2e5813e97b7dc740ed75da8b1c55d93defd0bc7ef9ee7b59804fa30802bed815f02dfcd96448f8b1e5c13b6626b0fed904a02de9921348e21405d593bb337b6217c57768a8248b8d34b9631de58969db31cbb60797689ee83c09aec0a678a1d52bb267581472d9bfc1d2c105969e8ffe87e8402f159f87ab7af238fe47518b7dcfffe78bfc7dffff8f1fe3c177d265a0f90c72c745c0d75708e6d04e7c1622b4bea68f7f378fa1e6407403d03e73a3f882e81897c450d99873760ab987d165d3b766df69151be62bed68eddb072f819abacc26ecd305db23b569df6d93d7b8895cb1b955b657ec0da35b8078afd6c7b563acedbbd7f843d6a1c7b62cf75c9f67c2b1ab2fd621070ec1b3b60df8b253b347aec073b62c7b6ca4eb47a4ecfa9b9765dcff5b9914a73736e9962bd2a2ae3ad8eacadd19bdb7367eedefa73cf9accfdf9657e35f479808eb05806aea1cea379ccf4e7c93c9d67f3bcd6e745b19c97e67c5ecdeb7985fe1f4eb3f96d7e99add06b6ff07a74046c346ff4c17c4a6bf3d9aca6eb39c39e238e8ee7ec7c3ee7e68b394f2de8f5c5982f99f15c08dcf96a2ecea5f97abe99cbb3fe5c713ee6dbf9eecab8bbb97aa1e67bda9e1fe69ff0bd6986f6690af9150466905dbfd0de9c991fe7a7f979de9b7fba273a86bfb360f3ffd3478dd25c05bd6f7ffe361fa0737f9f0fe71fe8f7d17cec2aec199ddb845e723447711a3be074ceb0867309810d8bb30d9d73ac23e772defce8f3a935b7ae6a62993746e37cee92e4f13b77e5022e0c58cee1222e46af49d06bd2f985cbe0bab58fe83a72395774bf37a36602f705ee07573e9effcf3c3613ae0a392ee30a2ebd9db91a7faecee5705ed6a496b82270b91b577305534d33fcf7a0bdfff87cd1776ad07b4cd3607ee3661c83d648ceb1dc9ce3a61fe1d860b805c733e3696f36e496acca09ce915b79334eac4bb414b7b7c079e7a4eb1bb7e636a9a46d38b9bc700ab77578caa2636ec7a9e83e35e8fea0fbcfed69edb10ef0233a081e6935120197805689cf1d667ab0e43ed1f53f722733bcd5dcd9931c9d23da4636f045f53dc4dc98bbaf72fdc22b22ee8ded7303ee1d450789a595b18d3008b65716b101906b3139c023e0111907f913ccf9348fdc90fbe046dc3814c2253769b37963f23aec83902f5ad0d97941d1938546faec4c17638b4bdb6701bcd6c6d116fa656a089093825c5cc89afd85b13067e542afd385b5b0178ec7229c202f1e7d975f754b7af4043d1eda9ee9eeef7fc58ffcee20b9b098e09685b7f0eb63dbb3a9b51c6a89da70dee2b2407ed9da2f82456839c89758866cf68351aecf75dc8be32e22ffd208999f8996b388b1ed3ce60af860747d12b0c3c83e7799fa31897cbbeb688eb18e187ec4518949d02c57b43f8fffa947a8e0591ae9cf21bd9e100dc17a68cfcf3107b7135e1f67a893ddffde3ecf5016a9e178793e5a64fe0070515a2cf2405e1497e1a2bc6617c75d5dd6d04bb2a816b52dba03dfa1f68b1ba55617b65e34e85a4d17b305e3e8c0c56a670a60fd1d882b3a1d4c7cafb4effaf75b5d14dcaf80fb41b0ee1295661aa5eafe822dc666881ee70bce652f3695769a7910afa1e7d1c091d26c7bbd58506ad42f8d385df0357bdb1a477f00b92f73f4c871e01aae3cbfc10eb14657c376101eb731431ab3d50c40f76e97b933eeac37c875e3daf06eb1b445ffa23994aa99f7fe67dcc382753c747a9f0b0b41fb44a87f0499656b5c72e80aadd0ba13f56a21a11db35e6cf2033a5f19624e8421fa4f3ddba4eefe86f952d04b78809e78aabcf709fe8707ce7ff5713da65928d460b15dec1c01eafbc866819ebd41d1a01352958bdd42b5cee87aefb92b3ad7833f88f9d25b7c425f8a236966e42d8e95be38195625911d04b99ab68f037a331c60a9741c07f2d8e10912f59083c4f270ed6b7a1e60bcd9fefd9f7a845c13d45702fb713edd7d86f398b61883bce6f9203b19d7cfd0ba49f7861239d74f5ba414cda4e8c599f2173d5028227d208ee66ed0f5f4b3c5f51c1e8a31d48916fdc5db02cf9d69d70cd6fcc2dc06ee9e6bec636cd93ce905bcf6b363ddbe56539dc4fbe86e526b2b5dbc175e3271e40583794efe535f42a7c50b7d721ed6791ae33dea5fddc570f1e1c535dde6289e7835b8a63a6975ac745cd3c67cae8eff65bee18e9da71c06c9b958d8a658dad55a8c6a7b315e4c783aae28bfedb7f3705f5e4d5d753938f014af41ee0db3da4c93072635302f2c8ad4cc2b9fd7a92d6f20db8d35e4a147e04907a39d9342f257f719557fe768757bb1df38f3266ff136eff0aec75136c2230ec148e8fa215c7491788ff7f94bb6e3af7c60f27cc847d51cf9eb0038c07c7ce1f9844ff92cc7be017aea319b9c706f2fe604f3a89eb84c5d6dfbae5c317e45d860ebe797ef72533fffd8ee14cbc5681bffbdab34a3efc2e738e3631a6dddc37e79f4f2abc19cd15a71bcb892f9822f2905e7327bee99e045be02ce755b63da2c6e7ccddf700e908b35741d9b4b83fdc7a9f5235d9f0de92d7af88c4e43ffe51e12de2fd6462ae9d37508be44dff3536ec7cf52e52a8586cb3a6b9e011e24e46f70ffd6892ab16d3cc32c28acbb8a7b12813b0cfde2e8a4587ece73c0c962ce8f5c05ce57219371f72db82a057977d2478e19d4c03ef0da2bd8e5d6bd7ce4daa49a652234ce2f78de68f86585bc29ee337b871c92ae82ff4b4ebc8090abd7f27a26e8aa7bfccae8f2eb9a8d223c5ee4a5aa4657f91df91292777ad5fe38b9495b0b7fb3aa7656c8dfd5931d503470b97c9f5f2fa6fc86972905f992069f7700b51a646d544a31d71e35337985df166ffc8e575997df9b36f86a4acd4d332c13fec09c1d1fd8e08c07954ee00043ce8ad48e71ddeace836a7f6feb0b8f7c63773f20ea9dad88d6cb173ed54f3e9ae4fc1022ef13f63bbec774b74b603d3413e2375e7d6077deb6c5a0282c13f94f7fea8a9aa3599444b41ee1dab66baf847e7e74ef36b4aab9fcd18b2d1d572f94a8e24fd4c774035d66ae0c3c09a2f788f5004e440f8026bac3cd771a5f6d3f3bc4f36d8f3455f1677ac9f7f8beb3c05333c91c8e4ee3dbb9fb911eee7b83d7e21ee030837a03e86f68fc82e1df920f7ee0789676f7251e64155d737e697b0468609910df023c1a525fb965f8ef2f7e04e7f827d0c786190311c9912d926b3fb2728f7fe787d43be0247ac27f5c3ef81130500c8b1ff3939b9d8f08af0998dce4ee201fa3e8d3256d83fa410fd7c99ffb063b0d11d2533e683562fe9e7e53847be70beeac8bb9b5a4969a259ae152a77cf784f35b9d1ea21b1a4b230f8343a03972f4ce1745349bf0a55546d0e7612ecd2241f1bae9f8013042701d03f8686db5cf831c511a927ad6734de2e1c7ad96d3dcf5c680d542f8f0c9d7fc0307958f20562874cb595aa5bcb48167d19e07611da1f3e7f3878ffb95b78177f369e92cdd787591bafe9856d76b8a7385611bdbe09997d476e92d412dd03684e5c50c9dadb3585ea94e5b06c73e78ad13fd85e7f923dfcc1d6bfbd9dfeef5dea3ada0b87e870f83269adda7968f8ab54f5a9bdb69f461edd8b6f7aed3ae3d3992bbd6dc65b00c9711dcb98e63097e64190357f55105ea389cb70c74ae302feb898f03887d9968476c7f80d7e3c26bc166e25e0e11a1567e992e3357a2f7cbfc7a2e18f388a22a1a7ade96c5b2243e0c344f902df2109a27eaa35c39e4df97555d507aab2109dfe969762d9e87d8fb4d8dfc3fd024d70f75b6accd309297b765d334cba93348861460a85dabd592bad2c559ce968cf5994e3265c92ee74b0e3d2e169325bf5c2e0563611e0dbbe5ae769d091ef090c8ea729f7bca7fad4f588f7a46a7ed023592e5ea1ff521e871292626ba57c2525aae196db9998e3bf6cb9d5361e1fa88f7f01dafef83beefc5d098d3525e2afea4d8a2f84160e6cb2deebf2fe96e6ec93b9957ac99b1b744eb02b8ca4b75b99f968b08eb4f9edb99302a59a70f4d7bec8f8668fd437579ff1b3ff27b1bd8f564bdf65a3feb0d3e748b5e66d952f9f2106f969f866628503bc7b6c0ec5807cfbbe4a996dade59e87bc67ca02bfa96c7e56979d6fa067ebeebdded20e85e5da182691e176b47a67694b2ec193c2058e70a8c44623fefbc1d1f7c104190e97ed95fbe69fde5206852a59d7f38686bab832fdfefef1f5e232edf59d33c2e8785b7fc588e96e3e544a00504c551c4d7d9be8fca7003411374ed28a0afd6bcf1fc5c3004e8a5343f4153463b16fa73af46e7638d2e32f59efece811203ba3e98e183b90ab4ddf19bdaca1cc93d113cf2acd4f0d307e04ec33328c14cac602a58da01b8ca8ffa78db3ff2c25079c6338447666cb483600b8ee06a7dee9dcd048fcc1da03b3db56efd9d0113071bedcd3c0abe7011ae18473f7486bfea663ef0c7abbec0abde6f978379e847bcdd7b2b54bcaf7e9d31f45d0ea7d5eeebf4c71d91a28580e18510578cac34823c95103d756775b8e1a5664bf219d8a7a0ab27c44222a45ed2e541307f0cef10b8d3086f88c6da14842c3908b950082566be78c0a600dd5e63e35ef02eb16d3a9a04cc4545ffb70d679e987da1d28ee9841ad107f07d4473891e113db1fbf13ccfef3f7c041d32ad116ae1668642e3b2c214f993caec4fb7d73761368b7dc55e098cc01a9ae5401f39d4d9eb77e01cb898c5d3d5bf8bece9badd7bfbbaebf7aa35d9b2c33daf00be5b1759bdec069225e909f3affcba9f7d34ac32369cc410386121f01a56a7031e195af70f16890778e45b6eaf77e7e8426ed3c32a4fa1b0b40782501fac08b4e0eefa01db6e9e32323e11bad62b762c882e779fb3f53c53ec9937f7e03ffc916efccb6cbaa79a41b7f75e6deaebecf353ab0578be3fbf9b5984edb22069fd18d74780a56d5bc2faabbde8721846cbfb825c8d81d974c02712362125c88282fbcc311b12987e6405003ec1b97ec97284adb0633e4ddefc803e67882402660ab9f70f58658e0fb9a0faddd2bc9c3fd4a2a026557d16f68557d6a08d017927ac73e8fd32d7f5effb11d75b0987782a7ce6c2f2201c8593b0e73401f946ff2cf4f83290b291b531559ccd9d405dc71cb926e0a62e43fa0beff5c9072766f7f7ce72801f7e589b674e6cdb797def2785eb7b3b3f47653fffe804425f781306c2bb79840eb1ca6d59b12d97d8c2751461f84ddfd1b3bf241876e40f04747f8591301626ee00787b5877fed1af6f639c3ca6d478baa28b08f7f7136edcabe6d9f3faedfcc6ebfc91d7fac85d4be31bbff0dc97ddf18cd4d6beb6fbf33e0b90e482486d01b403a754b9a256da4a5f192b13f85e08c18f566dcea5b55ddff8908e5b0c3f8796c9e7d4ca5e392dcfc826391bb8bbb03b3a5e91b159b9ec2a2bd3b8eb4737ac15c21fc6e696411fe1ca07351aede8a33b15555a9f19af2eab6b335b05f5de4da96615028f17ebfc15bff8ccbfa99d0f1af6c54e731d0172faab68aaafe2e8b44aac7d3089d855aa8f78de58dfacc0cec736fe9e8605fc57a80bb55803ecb2562bae552bb81fe2de674ffabddbdebaa7dc15f85ae0b9619cd75edfae3e627b6d7f05f623088f3c7a7dfe8903b42cf13424e0eb619fae937ef37bffd1b31ff9b56bcbbbbdd501e6039b89b9cad07dcdc3e1aa5895be807560865ffcc41be4b61c71165ee7ad36dcb3fef1579ff33c7f64fba7f347ced4b3eff855afe3f5ffaf7e85d44a3a5da24e9f1162c486ea4d6fab6a555b6b435cddc08fd88ffee35f39c2f79f89263b891a568d4d749c02b4e247e6e4e660659923e4bf01e583d63ba8dae478820e7e7f607f2be6d9f04216bd7eaa57abd98a094db631de17e565b862b9fe9475e9d59c7fbf8598478cf3249067bffb90e867fc08e6c20147d9a60277eb2d57dc6a7171fcc38ae72e97b1509ac704fa34d06a5f2da1e7f08eba119ec01d41bfe4793a1fdcf6f1dcb9bcb86fb4c51d242225c7437b12fb67c2c526fc27a5c523ffdc817020f4c1f32bdb5a09fc04d4fb5e7b123b3cf2f021d6f8e5f51eec10a2f16f4eb4b3a6ae56d6193a02eb034c67f8b23ebb99572d076ba1bdcc8effea475e75fc7f8f47beea406d5becfffcf7f39763f0f2fc7b8dfa49bb7688fbeadee9fd4acce895c45d56eb3ab4a8d5e6de73f8d21ff0128f6ac051edd40270975741ae16f6333ada0dee4a2e4a5e8b498f2207391de8a5809c16bc1fe94381bc0dda21ca6abbda314d76d0ae2b95f2811bb0da6bc2eab0fab4dcd531baae4ed467379ff1ee3f7ec55fffe9e309cf0ae168d24995069fabf3aab7ea476366a801f716451058c5814251a44de278e8c3867a51243c7cc41d47786d2fe0dd7740071c5c0712a19ab8dfb0cd11b63d83b89fa2ebd7f33b9f0d7ea49648e6f88f7a09ffce239e25a9a0fbe7d8a6e32f45d7fadaff01e784f35abfc323786d10dd0443b69cd59bc7547ddf8ba5d5e0620373e865fd92fb36d6d53003fd50fdcf34f51ff7f8791ecc573ff23ccbdc7ed9475d1eabd3d17ecc237a7ede8bb620dea3033cd3b069e72e297cb97ab7d5d570f561f65723d28ff0da07f0ec43b042d9dd66425d04ed18adc8621a45564aa1d75661afc68b77974de6ab8948bba64810fc2499624ea8256ac4e7c4e851d445a3fa10cde62c5abea52b58afb1126dd1115dd1ab58d1172fcd46ec748abd2fdfff27f04884af43806ddac5aac4400c6752e95a8e18615b6e41e4c378c42792de4b5cc7f1ba3eec76ce09f7920bbcf702e20a2caebb13ae2d46b7b813b7b5422d2e203ea4c37b98530dd98b7b9dfdcf6be5ffd923447bd0e1007d805d1dec19afc0b9433f7b1b257ea9b1138b07df0bb47a101ef1c538bdb9ac9810ac81e71274331e5bbf4df871045f5ad557bff0cdf1e7f3477a2f7be949abf6373ee4ab2f79b6b9646fc2d943ce9fcc3a44be64f12ea6534bcc801f944c0d0b8ece93bee64220dfdff6cc8d882f801abb98070cb0a2c5422cab21330ed6da15b44796bbf97a696907604ee24ea033f12984e3554a692042bf8a532696b31c8bb5b369355f3fc45b50cffa7e2436e2549c890c9ef1f1f51afc7d1fd23ee2da134b5d40b34564afb33a3543ff5d9c430ebfed42bb3333304e38137d123c61cebbf7cd3dea1da0928376086484458e6488b5b3b8107971290a368ddfefa96f031839310a76eb85281adb87ce803998e7c034252c90e77e90d696bfe083df689cfcc923d122b134e8bf2713f69ebf2b796fc0230f7e591763dcb531711d052c00ba661233056d50719dbaa085f3c5df434c73686744126ee1b09d4df53adff119673ef4317fef47fe9abdfc9dbec7ef6ceed3f3759952c58d5ea5b1a5d532ce97b7d36e7e9797ff5227c6357aec2b5074102e45593b888a7012b7f94ddcddaea2aa73e21e452d1f70f5ed6e7e21a0fa2144228c633842df0caf6f81a07b78528141e640118dfc467466640ec68ff88d5ffd08e96f81da2e701242d05489d12e99b7196dd0f2821e7f9b74984daac610bd0cadfe438b2bc8e40288c7bb595b4e753027712f5b39a6f8994ec29b78144fd74ff12cf6421bbe3fa92842dfa0395c249a7aab6786d88f57e29b057d25b897d0fc30f962210e504027a411447b64873a57e27fa0ce24be8bc390133fc4913816274435e2b73da7bf3d7ef3bc6e075eaaabd9bb1af998646a40e9c31c054c9111553af8dd70cde3f222d1fe0e6a4af444a224edceb5fa89fbf6bb7930ffa5f9ec141d68cb9d7e339c349a61958764da696574bbe40fe25a9ced84aa605b1b46bb2b64795ecb245d322453b2245b722457f20ca1c013dc10a257718d01d7f88db5214abe74a974a794ae52203af3fd9c27fd85241ec5b3aff6cf5a893ffbfd5b5f02b3a1407b7f4a959a2d855224c5a0fb84b50acd52c2fa31734301fd45299152295b4cd1ef1699cb08ff47d70145518c6728cec59c2c0e5a5f020dafa95448a52048953595ea455edc48f485eb22607f5de9268852a3a1d8bd3e4ad3a269d53cd0759266fc7bc6d8a7ac3014dbc41903af21bcb909dc1b89991da02601751ae46b9c079e79c6937f13b7a09d29b186b2c890f56cfbcd6f8352627ada11345dec56bb31d94873ef04b92a7a683512c7c834e45827dfd63dfe5f1fbfea2f3ffdffbf345757f62f8e0d9958b32f2dda0c2fe6717d930fffd606dd992b28fe86bc3ababbbcb45c1c25613934afc1991ff2ef6cca1ccaa3b49244e86103a502587592549febd5eda065d9d6df4a6b69434f9087bed1ddcc95c76c8ae8e9f71ff523981f14408f239efde883f6462423d029e39c93025c0149b21c4991b6120f9a97e154da05b5a49a41dcebea1c903535275037016e34f20147693f2d5054ebe97be9902f419b51fad45de9289d0c0173816ddc912bd49b8b03585264a4f37407bd8a04db184bf6902952af1c1a225cd716278a2d470eebe82e52d29382f1d0e53ff1217f76c0b9483ef26db8afa8d54f80684ca9dff943f34970a67692fade8d6861ea7b2d95dea441a63b3a257d67fbff83e3455fe0173ff24ffa901ece174dfc436cd734e438a4f7fb4c73acad01fee14ff4991e1a1ca42ea027a6799686d2473df3118a974669a94566288d132db1a4c99a3644ac7e83eef89a5a6bc13239146f6b9debad0d3c1ba94f95a6d3ce951d3fe69b7773cb7ffc3a201be5ca6bb3baadadb5bd76f2bedfacddb5171b6be0ef3af1225c4b7c99ad2febeb3a98b2e6d67284557392ea75c82f452914894a1fd1b1250cbf155a4145bee4d6916621bb3a81d927c84ff93073c3f7d3721df3bce1826e19608e75b24eed35faaee63ad3fafc82e01f63b3ce6b3b76d685191a2ecca977db9a7eabea40724e9041bf63a17b6ffc3de7f45cdffa8f1ebd7569725900d560d8d5ad763c7a5fe89f7742146925dab1f2d755b6a754ac41b3359d1445ceeb7a7d5b37ebe9b7fa65ff89afffa37988ffb41f417654f8d4de2c60a67beb19d150c23d04548733fed88f24a6f1546fcd47aba5c9ad9935bb9e9bfd58d30e8b30f1b2de9a5bad71b54a582fb06eaf27182c02c7c8d6ec60862bd14f27fdf0ad1f19dc6b3bddb97e5367fddb077400edd7bca6ae97442ddc825ef523f4001a0ac384a7b5e05fd62b3bbdba56097d9dbabd5eaef3b558cd032988d6d27abddec426c22907b4926dc7f7724b337a69b62633bff6616195ddac2a382e52b65d2b507701f55773b2de3a636a073cedcb9bf569f0698cfdb292c6285ae3bd98614081fa86eb1644c1cdbeeb4f4136b99b4f8fe70bd35fea177fff706c7fbd831ecafa1df7130db126bc0dbe63add6eaeadd7d077fd9cda472e68bc17a1f52897b5d3bfa8fcd67ff77f1488fdeaf0fb5578bd0f730bf02a311b4305ed48eff0c8f743930ec47ae4635ad83f5e7fa68acadf1fab43eaf7ba93f134c1eb84e90ff00bef0baef585e7ffd46c9d88672944cf42e604e910db98e6e5ee098cc6dfdc7f0c841b3627f3d3016386a0196a116400fe67a5ea68bf57b3cb5d7a0d982ce6f72b135ebca696e355f0fd71feb115a0d637f1bafd613ed60d8fc01be9b39b0b48564868be386de501bcdea6d74f4b351dd3666fa4ea91b2bf636f622cc44f03db87fc3d9381bc8500c35db0fae878d476600c0cc978def65e6116cf7e64274a9f075a6a0a68ffb2f485596c6f342beb95f7f178f90cfdb5c899a3af82cdce7833051f306ad4b68d71fd03d635b3d1a98b3a66f82907226c127581477f37f008fc08c8fb3231bc85f04f62ddb84a0c308ca384fdccfbf9213f19f70890b9a19016348383e06ad8c2168a82f0ea0a50eaafa9b683ddfc49ba49d237bc69a49b8f6dffa113c1f11625988e7ef7ea4e3fcfeb41f1d534a1c183c89eb8133e0f837c73c96c34498d958efdea3a690cfdfa49b0cfc81b6dce48ec16fcd70536ccad4e4879b0aead5d662536f6ee13918078bd0df349be96686fec618f486d50e95bf9917e562bbe1a4a1281b5675b81ab5825638a51d378b0df4c5788d1aee37cb5b064ae5d0253dbfa09d12f98304f7a5a0d5f9a8c1e03c1b28a3773a671d53e8077d08c63797fd46d8ac3622569f05ee008a2fcccfdac9057a42d5b7186b5e9179c03625ebd6465aee37eb763efbcfadd37f138f54f45e63cb3c36818fb4d940950cb3e3ef3ee22fe21192af6fd5d1808785735813dc4f827ccb46c61e7a02ac14661c48330b7396dbb980642e21cc88c598e34293fcf9b99dbbdad98eef34deffee630fbeff46d13ef1f9761c5c27bb4a7b1f2642408dbfc639fee166bbd96d54ac47bfd79ce8b89138891a6ff68bf7cdc167b563246d3ed7c1e668ab4ba6543727e388573468fce3de7fd02e43d845c4bab9d47d8e8a631c357573a6f7a6cb339b9e41275398c505f9b4f90ddb6e0f3221d1cabed72ea02b0de6d0c30e01ad47fb077cc6778f26e71adac19f49f34833c3529dafe799c96dfaac929b8e0cbdb1a44704cf74c4f36e376feb25bfd55c8c2d7f32f7f8efe191761e88b8d5fa218a7b378336e3eb77b9ad3ff7238413fce837e87e7ee67d759ae8b5b97997469b61a7bdf5742e4fb5587ad5fecdfdc3bacfcf7c7f87ee6d3e36234370aea42f06b43f36e3cd24809953583705f3121c7a20d3de12f77c82e6d3869285938c0271e4fb36de2954645d36a213a53a9a6c961f96235b5829d06a2bae9af5acc37c8f4eb14e80c28f589ae80dc8b6ec003bddb00a2d6038abc386cfd7f7c97f7bdfd5beffded1e970420e2b9fc86e205f8ec1a7ece547ff22235fc8f8f2452fe52b601032cf19b014ae656da86d365c0eab378fc731c2cfe521ff553c02792d777671b24b38d1ce5c06dd9bb701e1b23e76c89ff89247d4f5a2710edc51ebce023487862d0772e8abda9ce00e9cb7eaddedf9bdd7903db51a193f9113f9b3ef3fa587f6cc3b302c64bf6dda700d013466af9f299dc2f354cd82998430abd05734d75d538a1c896b39f63772320bed14e6a653be75925339bb0e608e9f9c8b8345dfd22ca2e74bf00285fb648ca588e770dc7593a1b3cd1cd43c3220f2a2e7b2725185e6c9c25a8ed164ed3f6aeccf35f0e79cd5d7daf9173cf1ffee3bf0fb92f3964bb9926bfd44f9ee5cbe99f622921b791abecb3399a17cdca789ef15e5a3e84a05bd82f81c4e963d8443483f7af153b9c77fb33e4234530093e4b61972ac6d0536f11f9dded25fc323c66b1f45e74f082b03aa8b4e3535149995e7d790bac81cd64524ba17bff000eebaf1fff07787cf9517289e76a977dd5acfa197d01064de0cad533c9297c82ee68e2c0bd9525ec962d1af7ac8df1acb9c52825896e4b50ebddb17ec8bced2a730b9340e0b3a0394ef97f2a63a697d0ef42da1c7d1c7a897c37591b62fa3cd19c2842445af655956e42dfa9c9dac9a3cf4f2802ab9c47eb9de5fd546fd2ff7e1878e76ce0b74def5e5bd7cd03ee44ff9a8a3d52a9fe4b3dc93fbf21bff4138bb61417494e581fcceee91fbe1f03cc7a6e56afd94bfff37f1888cf6fc989e04b7f5581eca1f861bad300f14c5cbb85feeafda209f445cb592c06c100ff78e50ddbc3c9c95746253ebcb2389a37b31f48294a0634c7fc3e1658f4f7ee41ffefe9777ea42b1142d8fe589c4afcccd52a1154ad1143daec56d3657d0a5c818c5649646cd8ccc50f617f3f49d52f2839b0537a267bc001d5a43b11a0914591dc957145b71a2a1e24a233d57bc6bd934e550f1610624cc0d01df0a9c0313cf0d41be96360498fba75c946b36550273d0e10c257ce08c363a7b66087dcbc5fdbb8fede79984ab5c8b665f89ae93708f75f6876eaac4e816f34aea7bc0c7024d9854733925a369056a395ae9670b3c93be68f95aff7fc7237896abc6430e82caf9b899193cc2250aceb58fbf56a5fec8973c735e9f700975351cdcb308fc23432c43a5345dcc8d8a5a2cf46bfffd899ab579f5ff021eb9254a85351fd5fc7a61255ea9d71a68312a37eeaa1da1f3cbfc348f356df6619e64ba3043a5a1d445a42b948c736258831673596bb09b584ba5d5c9776484fad5eb5ab6c56d7852a658fbb2ed2b21b887f4fce15cd1519979b1324391d707b2e190dd002ec2e4c93ffcd203f8cddf7ef880ec4595e7ab36f788356a6c496116d7c25590cfa464651e2bf12890a7673134c375ac70ee3be5630c4734b57ee63efdbbf591319909085a8ac8fe2daa81c1370eba53cf737bff8a0dea6cdab39a3eb249580bdd732f218bc2fa631994a0050ffd676a3b2be46bdcf9d58ffc13b9ac673c027a90672a5590815888dad18bccb0b10d5e3b2b4bdbc63ef13ec1a07e37797da10869abf1011a94a68bcff5edf27e1db6f3dff79484a0884cfa73289d9f2e64975556b36b683d5faf6e3625f0b06cc37688ba28649e097b120e217a4c83fece67b458efaff0eafef2e3ebfb9ba3e9a85a52aa5537f9d403ed9d8be9f5fd80ebbbaccda6a97b2beb85aa888aa4acada3f16e8b9ae5ca44ab077323fe0fe011dc83079cda2bd8416fa96cf8a5222b8a6b82fec99fd66c9f718847e2ec7b4eacd5ecc273993eb4e3f5733344ab718ff32139ccabc2fa4bdd793c7a5fcead1ff9b5a7f21f39604e8ab25576856d1e816b0b732f0097183af852c85c004f09e6af589aa22a7b669c07d41a9f1be867429dde468f57d094c4d826c01a021b9cd7213a6036b5530e1a9e5bf8c43c27bd7e683be19c9706f345ac313fa915c2f8443be8d18778ef01b45b3cf367f8e4a70e93533e175bddc57a94a09b4966d3a3ef674bf544392aa74b3f37aea17286b9f2300f062626d127ec777e3f27ecffd9dfffab7824c7b9a537e89f08df28cd95624fe9297d2f3394d06af1c82f3a50775bd3dab0d7397c24e3698d615606d45bcc9e975e3f2915661b221be33b9abd46bb6447777341bef4befc381ef9268ebd3f8eedb5f2a60c6628a2021b0efd2cc09489268641664a5963e0e84294c4affc8121d7567651dea7e5ac72532ad54c2a85da80375286ca073d7119970d73cd5df4d0aa9a63bd6045b3e5ab32d28e3857f89c9ba2dadfd1f5e4c7588b442333a93056a12d4a19bfe0913657f865e2b3f78a53bee6babad7fe95dcd7a3abf8eea37c43cc92a0893ea9267cc33a27133223cc3797ba32b9ceb6307e727f8519965bc0b7a00d4a35e05f2117f87f80afd5f52e76bd62a085777664a9f6e2fc2df2f51b9ebbc7911a745737e97601b933d03fb0d570ee0a77ebe66350d4c6fc210ef2335eae1db7ba23b7bea3d35922bee3dbbefc7b7de427ec4ff4d4ab69b7f68de8599ec8bc2dbedc1a57f0216f044b614df58d217e67c32da27471cc29339cceb7a6a203272b0ffcc60c9743cb61d545b0b5ac7ef27971e22a2eabdbd6de3a5b57db6907e0c19527e25f31cec3190dc81dde32c06da01871d76af460debba55913f0e504bf00b717aa854ff5950e07defdd2a30ffd3173aacb4d7efd7bf71ee4ffedac2c8c25bb47f2bcf5221830bcaeb773bf3a2d699b92b69ef1d1ea637dbd8f3f7dfcbb78e4fcb457b71483ae04ed8869baf5b7976b59bdbb0630e74c6e7b85ee9a87eeabad937c7d7972411f44293243d80690eb379c55be0da1eeac9d4dbe920c479f0761ecda6b645b86389ffee835dbffd27b3678aa8ffc04de803accb37e535f079d785ccfa724d044f62fb9ad1d71c4f3ace3dedb46f67dee7ddbd70ff58e119e43ef8126cc36de26b7bdc36cd37a63acc89c2fd7b016ca689b6df36d7151d6e2aad80289b13424aca7755f9964c21b9e63889533c8b4e94e3f007c883934cfdb0a45bcd8a6132d5ec837b6b9c2ceb73fd74ba82f3e847af88abbc6e2f7b3962d323f9dbc2fce4dfaf79ca622f2757c5dd36fdb9ae87d9a2ea0f2ed6dfe8e735dff78eef15fc723cf750887ce708ecb75b4a571e1bdba39cf649890d9e10cb7bdbbadde16f12b94211a2b2540b6389c5a37b6096f577974bd88dbc2dd36a610be17c34ca094b64fc37dfadcdfd89e1ff423a7271d00f23d71fd1759822b9c8ba3c5a5906fe6b9623f2693610d4af023edccc117bc45a625834d8f26e631ab0cbac8b7d3c2f407cdc281b97730c7e5a89d881292b9b41c65eac599640e03fb6a10fbfcd02b039b1e5a8db29d7996ce987df303b8c3a41a8b2255819bb7e7f07c1e2ff5a7a728ec2b4efcc5577c538bbfeb163cd7f2f121323df2d969140c82c9f25ddfdfe2a907fdff28dacab16dc7735bfef1f549e2817f118fbcf60d530c9e5b6a6a566a6c9965c33aa56c08f53b5cbd52ea9447effc53d83103ed28f3fe4ccb02b90cb6ac5f6ee75b0ee18e18c5ea4ebc12f6ebf7ed62cbbb12b0dceefdcb7f785e773cf213dfafd364eafc12fe5d578163946a9a2be4915609088b988909eadf6093891f11e60fedc4474d9bcc30866c762921cca2803a2bcee8e2be703205bc9d1909aacf4e4d6f97dae75630b6f918f26384b74b7a36c9fb19ca76b51503833f6ad095001afc26ae2729d3f15642d1194dceabc37d6daecdefa2b59759c9dd0a7fc6287fa684ea913ea1ee7dc86b80d98a27678c2cad5e98e1760dbc6ccccfa26915f4dda9c69bfe50fde37f1b8f3cfb118449ec2dd13e829e0a88d3737bc56f375b1926b54026d8bafb10d22f629e0c9e916eab8c879980ba82e707b65c2c987b02b17a249b6135c7bd13f039afb6e0db3aec8ffa91878eec803cb6b599863e0707fd9af0664870d3333f0dba973a0dfd2f6c1b3c2710eb549a8fd741c7aef9f6d046c1bb8bac7467ab6cb7db5d281578ae4ba738ddc6fb28f2897b11c5538ebc55b7fb66eb0fb6071ccd01a797931644959ae00e524f79f4eb40c5f60b3ffbdec7f38c53befa8c571c6253dd67184f5343bbf7777cf363fa71596d3f91df15f1b58339955885dd2a9ef292ffecf1efe291c17d6fbe613ff249353360ad53dbe3351404e8959066da11c7cc23f7f2d5236f4fc5767bc63ee20dfac1975bc88f113e16f4a13beb6d6fdbdfbe6df17c2264bfb777bb009ffdabf6fb0fe391bbe65ff73dfb246fefae5d3690b7ef81e59a985735b23597ac46acde0378c4bc23e847fc0ef800f7e16fbad9e88e4faaa4a09ee49aa0b847b428c97470e03f6f87b5a78f2edb90257e046bcbc0fbeaa4e69e0fb34bb1df1cb383f5b9fd30f906d9f0edc8ecc72697414f8beb02eec0ab96b61e2ae21ee10e775c86ce7fb4b3755f785ddfccceed725914e9ab7fe4db1e3eab569a6b753014bfb71dfb0ad6ca2c71dd43be63ca9fd1eeffdfc72383bbd6aab39d50c0a1bae099e6f28ed6822270cc1d658a0103771bcf7fbf6ba1e059ac613ac13d840d8e4dc9ecc34827da4a17fae4e83b6da7ef8ca670346477e2177dfbef34faec3b5febe7fd25d13b1e500e25596532de999663f206d126d4c8e408e24b006fcc2fd083f76d9c0f338549443476fc48c07a241e4c7e9e2606e9426a357ee17dcc93d65f84d55b207bb165107b3d4d0812ef72569673e9079123e79f3b4bf777763ab91dcaa379dc3958d1a19d616c1ebb19601d9ee9f0c9c3b7774aaa5df6b6f3334f95c8975d42e68c10d5d9a7be53bf7b5f4b6bde762eb545f7b84785e8fe35d30dd6b6c49ad19873f7dff023ff2e1ee962f40e8fc0cf7d7a6855445b3e96765ec6ef7c7dd46a8adf7580f1951616e2b2771548bf39ce9b0fda3e74bcf7290ee63f15d76b9d1ab817e4579dc56fcec7747e108f7476a8c35d273cfbd09f96bb0b42d5933226b91eb0ed9dee15d64db43b3cf25437685717eed7c0fddda0f30b73d571cecfc30a75c8b663dd5f8ad86ed7056d2d3ddf5d77017018d08ea441371f7006d4d9d1e7e2dcd62edc45bb3846d73ad0f3de2ed9a5ba2d99cd3c67f38dcfd6d66562b0e178310d66c87f8dba7e91a7ba54e747ee7f6fef13aea77cf125aff511ace34f30c8133f8ff0ec3873e133ab9852f0bc1bac2780a3e9942633427e5e5fe07f138f3c38fe0e757bd285c435936d4f9777597ef02f8b89c13ff85bed1c444a1bc71505dd354bec47065867c4a7768e0e3aba7876474ea99701d1ccc01ce3ae46716a7ba03b3f02d8a1d7fa917fc687d8ad1fd950dbd0e74e86b3cbaf465b17e8a214623f47df6824bed8e0a77992f7e7e095f9f0238f95abc4dcae007cb72b41e384a8a142a48a50bf0788dcd8048c94857bd95fb061bdab164d3cf22497d566bbbaacbde3ee167bf9671e08e2aed17a96964cb18f1ade73644fb92cd7061c71355c82fe0957c234be9c6bf73a72bec437612dca094c6e83ddefe586625089b79be6e750dfcd9efcfe63eecd7fc3879035fabf8047b02fd94ee8de8baddf319c33923665b563626fc7c2ac2662a3b0fa9a6708f54cb3a81cd9fd2dcc6ac4bab96887d86bcd6c75c1df29df8181375b32a7285230370ccf29a274648f3a3de2c1438ff8ee477e329e6d0fb43bfd80dacd779ca1d8f66ed1ce7dc4fd1c843943547a081ef9861ff5cc9bbadbf0afb6fb51e780bf275343894e3b7ecd6b5124123c03115df56988c8cfc0ac2b50381576cb59a0cf77c22a4751d6aa4974b7cea1d71fae21cc8ed14ccdd5ddeb81616012c69769076dbd0470d55dfbdd211dbfa046048a7f58ab9efa5a478169182e0af6f01c4707b4f1f10cb2bd21ee4453541acdaaa29de4c33d2133d1c86c82ff060ef9dfc1230fad6e0fe191673d76f4b3c6235cb2de6de809b5ddc9d50a56164426c85e39e64492e4776a879f7b059e27cc5ea4cf8eee6878ef5fae1edfdb29bbad30dbedb61475305dd0f3c5792f784d73c742affe6cf68f7ccfd6f639da4e5d15968333da9d6df5491f7f57732078a4d336feaeeef0ec5f7e995ff5b47a61475c0df39dfdb8e6fe455e25b3acb6b5c4e411da37143cf79ce4c02628f212e33ee1065728420bacd8d6f2a7993135e696a9bbfdf49d634163c63599de2f3ac31aa0783c1399328faba9d6df1dd82457cc3ed6197ef17dc65dc9fc0638e9e20f6e8ea541bf4b31df7d2aeeee886204852f77276ab73c609de8e77a48efbfc3a7bb7fd6bf8b477aad1f39213cd2e59a5a1d565c3182d91f038ad6d8dd79d783ae2098ee059948d7bc7e6e8eb304f7609478aec99c523416f4dfe9b75d7ff7e69ea6fbdd60f7bed9cec252b715c8ade35afbb8e5865258436bff5cc3f8513cf23aa7e58d3ed9eba9aaf561aeebd37c15d2c38f7345ad4e16ae8ffcaec7efe9f72f8c42e80b69675ab5bbcfb06032f32aafe3eae65ff8b9c1db9769b41bbaa48eb2b1c6ed0e01f43e01ad14a8e3a315ce1bb7dd87b322f942746f0aaaa677c16d360977f2b4dcee46bbb1218296f283ff053e10bdd1c8d276134350e9c40e26fe3959a8c88475ba261ddfcbbaeba29967d7d4ce89ae6a7a55e5aaae1a4c924c2e4ee4522a6821eb07d574045dc175a5673ca03e7126fe6fe391e7b90f9717bf82e70ee139eb84a7b34f3edd4a3ce02c3051b839a916efe319b8a1cc51227aee46b7553b9bec76d09b916e304f1450de262c361fa9185f550778bf5837fcd58f90d914f63f561f39111fe968aa1bb5baed449392d87f9cdb69f5c220da30f4afd536fbcbe3ebdfbbf7211af2f79a36c239fe00566d35533dd5af78f562f2ccf966355732cfa46aae06e4b6cc8fab717bbf1a5e01b38911d2efa957155d4f3c0f92cc1604fdfc262cd430ef85bda5602d7016e54b0f68199b7d8631683592dfb3bd1af2a51aaf566698c8a05c6d3c666bb5e70e9a926a72a9b3839aaad9e643cd3127c20f0b3c2b1de1521a9889134a6a7b56bb7bd56b67a4fd37fcc8bfadaf75c71e78af76f8a4b3eba42ad8d832e00db5504b2fc62a691e5144d66f4e118be01ba80bdda714e8d28a2ab572dfe949f8d6e4d02f8eb1874ca58ea2d6f15459a837ebe6b0aaa9a25817eb698c9ff0c74fe391e7595ff86f9a55abd112adc209e8d43ef980bb2dc675f693f48e355dbee5d23e739ebf706c9fa3318af48920bf6b2094cdab53799bd6debcde190a689fe0ff9ba48e02b320ad11d878fcb39815ea4c655416dbea41cbcd067fdea7279aed72c9e765a9cf510465bf72afb16f5a79b13adff9c927a5ea32c5b9a9cbaa9ccf686752856c6bf5ad1e9a39d4ceda4e2e624fc9d485cf23dc5861bf0575903714e15de60c3d493550baa03b4ec65beba3f75ff1c1ff613cd2f98ef8cb8c53bc87511c5a91f9f0f459e5d5a5c1c3ec5517a1776483b84c4c0414b7fa3ea52b0aaf0ae1bb2108ae36ef7a0ca94087c99c36e9cfa3275717b40a57b4ba52c578aa4ad097d8e6b73a9d949fc523aff3583c6a178f0a848a7107997f67d6b4ab1ae7b89cb67f847bf515f6ab0ff96e3ee02fcf733ddcad867c4ac9858abaa6d4ab1b8f162be4a76c84edba7acc156a31a48a073b26ee6bfdeb8e529c0f6a0fbd1af89e8c71bf0ac9098ed1aadfa872dc27d3e13aae30ee1ded59ce7aadc9d416ebb75c318ec95545dd9a6161749ced7befa8139bea4e55f300f99bfd65a6a5b87e34a51c85e04631ddd0c89f608ed6e665bd7c9d75f3cfaed17f138f747681d8dc06e72c9eead2948467d60da958572956575c493dacd7eaa7393094ac067b68389b55c6462c7f8ccef629130d21d9a8c7e4442928961d62adc54eaf175477ce2017a22c2e9fea2966d4b3da53fbe879fb7bdcf9158f3ccf2ffc2e4efdab78e49e8bd1acf56145a373c7358da7d54de686201b0bd34ecd1397dc75d87fed017c4cf7bcd71d9e725d541765c18a076e02d979ea9b3a20bdf0ea3bb2241e61a5907e7fd0cbc273887de80cd6fa08428013192e7a6ddef08c711be40331678a32d40f7584fc88f9ac4503d1afc1ab6357054c08d780aa31c72a5d2cd4093fd2409bd8bacf0480d75d0c6581de7e4f696e2ea86769095a31045bd280812a7ab8d7f6ba2d69423b33e4ed7e5d7f32f7f8bf8f474ead1fb9fcd6cf38f42337aeae7a7b631aeccd666b38e6d85080055f1898c9a7e48aa6aedd8b437ad270ccea76b5101cbf8ec1365a65a8ef689821f5628f9ef148afb51fdfcde8fa7fb55f8f19c411b576e4da368f4ee07abf4447185774fd23246744f48feffc82e1a33e6dfc467fec17fe14991712184a992631b2ef6a756119cb20b5781225e523c04168e7f2b771d803b51e7def6ef7d62fb3c93c7c2d4fd0a9564fd880ccbb87395bd887ec55ebc2f131e9d5c1cf8b70aef1a42b17696fb3c14cde3bc0b0bf7751011ee1f6ee86a676e8356d7f3e4de6aae3d9ea54b0f0f7de651a4b54d76784d7c17dc6f17fc38ffcfb78e479af0e7eddab8f581e3f0ed1caf63d7eef5773978e6aed986c885a8145635da86373dc5faabe23bb0b2a9d59504544662ae87c1368c0523ef082891623f62fe9fd1cd0e7b8ca131e79cc65dd7f33a3ebcf7d49f79a964b40c5ee667f35eacb1eb3302e5f7d40abfd8e5677337a6101b63e84fc8f70a0b7d76e57fcae3ffcb9f60db57bf37845087ab1a885105915db592d89425db46a160887ecf601d36c74ef847c07f217fa7e1f52ec179f88af13d5a0eb47df969a6ab8b70c7272d0d156d3d77e71b5d7f4a1d3d9c73e7c88702247abf65a65f6d13ede2725e70feee745a24d659ff26caac1e75c87f483070118a8d96731c37fee73982d42b0ca93dfff6faccfff0d3cd2f911ef4f9f4fe6a2929e669fda2e4a9e12d97db12ff795817c09a875eeeb50de9aff1f7bdfb1dd28d3b57b31cc5948c8b63c54465948020133441195500e577f6a570014dc76b743bf7f9f6f500b45a8b8f37eb6765e9a977258627e0f5ad3b048306049de1ad64f7c8225c2f5905bffc8156ff9631e728dad22d98a6f2b4f259697c1a2e113bf01cff18398d8d32053fb51e0f14b04ab9dec7c885e7f3f7f3cf1c183ddcc8fa579aedd8edbda65bcd9971cb7ddc49a3b68ed45a7a595b4f26230c36c417c9d0ea83d50abbc3d366137e86a55d069a05e3ce028970ad36874c2eb426b7e1549dc02e82321e8825a4dab6b8dbeb8aed839c8c286ca6e24b714ec7b795b57dbf181f0f9eb1a9a2bb1a8295ab3d15aec61ed48ae3ab56b15bf05c7ffad3dfa5ff08ff0b37a2be7735acd3014456ab125314f8223446517f005fd41dfd55ae352185ff248999e6dc369d839d440cbe319f29b195d031eb4f0bbf87eaf0809752c05ec29962ec3f363fd49f4115ed3fb9627fc8e2dc5baba4f5e2cce634fd7da60d7d23a801a0a369e34470f722c69ad74ad4bebab83ad895f6974bcd2a67923f8fa0b1ec279138b97a238287e54680f3a43ad1795ecf1f684fbd047b9a8aa0dcaf5bda4a9c2d8f6f0bc76fdae8d883d6bfd80d78305a40ed68fa0d46c40cdfbc027d1f6aa528b43e5007629e120c4f87735cc438a490c83b6b10575b1dee5060a4143aa13dc619209809e62db519c02a9a99eae3b8db98b0682369c9a61077857794db0fca9ad52f8ffca3fc269ee5bfa4892b36c2bcc67c2e4e2a9caf0ddfbca61e6ef506ba48db00470b6735834b68369fc02f555459a0f48fc2c1013cc30c5e7833af11faf1239973c4bdd25b82896f0eb5aeceff394d446c7ee23ecfcb86b42d405b76571bf06d13320771f6bec4e87605b09dcd695fa14d033964c344d4716abaef6eb0ca60c460c48358a7eb05cbf150cd1c5b0730ea6222b4bd937ea8029426ad106843e1709e65710a80ff8786affbb8cce8d39e609396f367762697122754ccc843ff338ec0ba3f9fde55e887693c38b36b18dde90d60a867c18b044efd1b90eb5bc6e79300a9607cdd04ccdd224a147781cd5eb625667fd27f8c87f5d1fe17e775a179e4a4b807d41f803c1ca90a763b059452aa653f6621a954af6a16f1bfb0d523607ac0916e0ff8457e421ea5e2c10fcdc3ac1f12b8aa9fc4b75108de48f8cc56bbf4696a7fdcad6f5685ca90d06ecfeeaf834dda10641ea76d2ccd79407407d1488d7a2fe0a1e8795466fe0ef552da7e54fcefb58edc4b24cf3cf89de03d5444f987f0daac7822657d41dda085ac1762b6d88c7c2f3b2988e493c6d4ed8f81dede90a6f808e9bdbb6ea782dc6276f7b7002c76f6f91116fb567a19bac599ef856205697c7c4150197c676e7baf6522d96f48608f5a968659f85e774ca0d617c5f9f59b82839e0595a517b8d6c5d7457809f45faf0d332ce7f531f916ebe3709863a7f0fb4e9c268db4ca4b53cfac26eb7e80d965ab5e5a8ad6866305f2cafd37dc17c07d3b2ee4417bc916e27b67f8fe93998e6333e92e503a6705f67fe77f1b7182e8a28bbf1a8b47c9d698cc6277913807a40b04ae0fd753e7b9a0b98d3a78eeacf0f12482aefe121d3bae657f151be17287ac547b9fd517776f338d411e61f2361acbb8185f586107c13244f12e620146e6d47216041d271403efe34d4f1eeae4021c692eefb36897958cd0a6cae289e724872cfc1af027e8ec1e9550fdaf585ad87ab223220a7f28825473d1a74a80d32e521a49eb12c4eb1f4d780d35253f4190a00b115ee9789dbfefe3dfa5fd647b2fa007cce7cad84d6f15c42b0a32f38eea270a9b485f1e6499fef8430dee5406f2178284426b63d7db17fd197c3c8912b5d7d35a8e8f106f9836dc3764116b73d4cfbea58a6e6f5d88724a6f8312ff928fe16e78d437a9dd785f16515c6584a79f532f9dc2775f77252316f21a7a61ca1346f3ff187043ea99a5d47dcfef5111ce490c51687e4ffa43a8fbed637ddb1be6d2fb6fa0ead0ba7315a628a51a7f53c98fe56b4eb37eb332292138b91c6af37ab89be833c186faeefb70ad80749ec75ba1e32bb42ccae49f953dc779e5635418d84cb7ad4b475a851a51ff4a37ecae0618d93b9d36a1541d7cf33a45fc4bc5ea2be75e2f3ff282fffff431f79ac0f0499ef7d4eeb6115b1dcabe965bda257175ddf267924f059a01ca2d9a2a9d72ec330d6eb7aa3dac3745919964eab407035bd3978294f859dd8003a8965ea6582e7640aa9bde59e37bc3f3e2bc18002391ad3c899afb79042d12c88f61a2671b32141a0eb1c3a4eea69cbe6f6b1b85ec243d0fbfa489a374e7c21758244379d3b5a7f206d57da623d4080a1a294167a9be4dbd371537b5ff4e6dcf3f16bfb9ca31cd648e9bec421e87e44bfe33a8b45ed4ff83305741412fb551c998146d74f18e99dca45afe9dd7d80d7a74fe67d41fceb54df00de8ef5436130dbe93db105b64c266dcf990cf1337ce4bfae8fbcfdfb94d68c48cc6f95e91c0bccf1c7417f230d2b7a7f6ee903af171474b555ee3b3b0f2d4ea25b740c7da88f76c5056402cd1c176a3c0553bdd6aa361b420130ff84035ed503b1a1c1fd8bf8fd22892bfb7d0c478be838443e077c28dbd7c7c782eb134c2c16b7c5f2cc299a85a56b04bb9dd8a43c312015273c07acc59043f89e1e925c531ce414a391c416a3d76317ec5a8e7b69ac517ba7ebd110d3f16c8ee64414123ded560fe375e507fa6451b273eda36ee826d62798cf22f1ab705d4462798339513be123a15bc46eb659ac7549cf5dca8d068d8710c1f65825d6e33a7bae16a8584f9aea795d0e2e83a65e1026b46e0c0ac4dfb331fe9bfa4856eee7b967d21bdf333a4ff24862c869c7f2aaa53f950fd57e34d29f9d82fe726a3b358802395e500e593497cee9bb36d05a4ccbb12262e7d68daa33021caee239162512eb456b5950bd27e523b290f5a9bcdfd27cf639d19b467ab1daa215e9481dc430e51bfe1c7ffe8a77f185c6067be1dc01cbf049050d9ef9c6c30ceeeebb8ddbb602c4f990837513f40ca811905f32cf358ca0cafc13291f891ff2912c2e22e605e5d7fd4a393564b4f411e505690c35b18f79c967a6a08ba6fe3a112702d33d8289dd9d90daf41a7d16d65b2876d682e06a7ac2022f0b7ed67a3e962753ffe85fa62af86f84d856a6831fe223ff6d7d647c6363e29ff336b6ddacff81c9a994169ae2ebb6a15627ce0479dd45d75e0d4aa841a3f67a078a6b9845b301ff418c6cfd301e17c2b3309eb8e2eb50a47147a2e9a9cb6d868fc899f6ab71657dc15427d12846a3edeef4d5cbc4833c3d909aa80f1df789a0512369783c89a4b24e0ec90445d46159b81449ee63f5cf93fa85bcde7d694df5925291443592137488913153e3b021117f43ca4786643dd2f8283e0e6e6394087f158358182fd6135fdd4c02afcaf801192fc52216a19e14dc47079ba2df8d04bd1014dc83ed831d4da8839f4b2ce06b0cb8f0e2a839a7b110334f508378aa564d41ec8fcbcb4d68cb6831093b8c474d35b067fec0fefcafeb23597cdeebff5ce59908dcff40306119edc7b488e088abf380e4b3edc745d73f3f517b11d0eac0a7b85d595c2a54407ab89a440b4b18e3cb4c1d0a2ac965b8aed5ce79c34779086f21a9e187f912e0c5f794ad5129d8c64954f45d916428b9e10ebd9e103226b3306e1f97e7e5b353b32d7c6ac0bf2170bde283f50739924f52c71e2cc16019a0b1be30def9d4360efdc91cd3f2e8b61ecb6491c9217fcc4738afc07c71a74c9658a791139e11dcf090004b9981d08358afc96a50099ef0332fcc8616329f97426a87ecc066b673bba7a08a7725e66993d83d0aaa164ed6f5a1dd9c525c949fcb43fc6feb2357b6f21b1e72ddb80d65446c52c4fe055a1d790fd172e27a32d9400e03d590d15310d0d392d88f425a3ba9d646cac5532693eda97c294f76c75c50059bd7644f7c29d7b6ad8ff2c8b4ff1ae17731c16c196bc2723139d8b97ed151b71d645cf24e6bbdb1731d6372ec0c27a7edd4b556d5e5e9b0b10d64429c16e721b7b9890fe3b528e608e49183cf9e4a5df6490d68140cd481f79c56f4d49bc711ab59226579e5f0355903f3663c1c67977e8e750bafd72894737187f1c98598e6779834ee4a2c1ce3f51cea4ed96e6788962dd4cef96d6243d3080e32d5fb446160bb9bc2e43c2e6edbdda39e3f1d44824be6372717cdf2bb62c153a71ae842ff5fe58f70faf4285eebad38294aefb8eccc3e67f1bd03ee9367715aa4767750550347a1d594494ebc8ff5003b13474b2cac0e527680cd3e1b21c5365dffb019f42725c05ed19aac8ebb27723de87d3ee2b3bceb2c9607e175ee11eafb0596306c3c350cbd32294f2a93aadec127a3b21aa0aef03c05fe05f91b6a69daa8eade2a6af5492e9f9fea2feff112d0f0299244b343627fc34a82040779258a8e1a935ad011b43b8c183cbe49fd866f5cf9aac87b9fd89f80fe0f087d0f921a93168bb966bc1762b6a2d63ad8e353a22f66834903e5268abb11e5e988e4f0503f0a89991046a568e52265d2ec5a93d6a40dff25a70cfc6303d069889fe9ebea54bdbf47ffcbfac8addc7f850fccf8479656537b499dfd87e235c6e0ef10d49e7eea637dc4075acaf07149ddbf144384f2930be0e882643283da51aebd6938a7ce50180783c4277fad2bdd8fe39ae7a5588dd49753a57e1cf74864f58d8dbb33829a7e8a309eb7ec606b0baaed4f3a642c049724e84f8dad1e993d7b548c4512e78408b6631a97f5f00a982734b6b6d95923a8c253911695d23a16797cd8613d28950ec298d463c9113f12e7919a8d44e126a6e0dac6c56d5545e23319111fbbc5f80a8955007f078dfd055e31afaf62d768b5bccea45b6e3895490f19ab95a82df3ecfff837501f7750f4d7a383a36c4fb5de1a72446dda37ea73c17a4b2dc3c31ec542bcbdbffeafea23f49c527bfa2c79fff1dc805ffd8ee661fb602399757b613774544283058ee7e45cdb86c0de83f908e00bb3f8298275b83f4ffa905747741cc07c67b8ef49be839960ad50daf9d806977e766b9b4bf5ae80c4cb16333c95d2f78b6f07d549695a051e07111c3c868bc70abbacfefa356ff123883e2158fb225007d0bb82d025e39e3b489b0c2aeda64e6275af75ad90f421facdb9b76ec665ddf09fa2a04e54b4d4aa5b6332b473d1d30424e215d3573ca8e1d8ea78ba3d715a8db5d39a8c0726de95301ff03dc16661facb8add8fdc1f6a5c41562fad09f98bf8badfd93bd9c6630e6ed731e523dfdfb82f3d64571e3f95ffecbd87271ad32b38bad46fd31a809cd602af20988719cc72a28fcc18a24e4469317a09d0b632d16c2fc107a1f633d07926949692f86199f19571665ceff5f19666a52d247a15cba1c47cb08ebcc9695ac13c0e4b5cee4b261658c8ea27995c45929b3177f61ba83142aa6fbb4104995dc10cb0ac1c63ffa43c633ea5033e4c269e81e975781ce1a7d7f62676ba535d1cd65db49ce893c9c4682ee3ee748429ce1efa303187e35e30b19009e8aca87e9c4ca4490effaf296a586f7965f1db4f5b7b023160507f5dc4f3b22171c025613f91212289c41ab3e743dc008b09a8323d95efabfbf9fe65c3ff0d93d88b747f523e426dfae6b75dbd0c0d0ee31df98c37ff0bee3f27fa4a7152983cd9b9f9147618c50d863c6fc0cd85dd023c03b15a4d8e377906dc2982cb1ea2574052db3bf658bdf85366db0a19ad02f999c73779497f8b8c06173fd4bfdb96d0aa728a654bbe037bd0ba88f52989f2388804a4b58759bffbf47338dd840746649ca11320039383ba3753743851f0fd048ff9925f4ac706d4a6653919c5741d78ffaad617ad73918d8fc43b4c8a2bcbf5a3c278a49d0f0dce7b824aa33c793544a78b5ed750050253b372417f0e4acbc57cd9888ef5606808868df5c25ec727b9a2704fc8be56882db344b071a85f863e6f49d686f3f994e7673ffbc8fe243c11afc783f5fa093ec27cd779c0b91204630a67959c57f94bf8485e2889f9e920e81f1668d9c2b414b09cf65bacf922c852f2e84ea38da011819455df631a3bc0bbcb63df094ec7700cb4556cd7ef0b11d862081d2966fb9ff20d42b38c8caff9f7e815c8de70bdd0b9a0be6f2c83bf4ec263f3b8a37d82fe4364395c1dc4c744c6e5d2069f392dc3353cc33702a0cd066040e2713add0045552382f82abf43e2a0ebe4590ba65fdcacc7e7d600f77fccd682de4b5b088dc88048c6d6c69aa2a90a050d8338a86e4d072aa6aaeb1250267cfe835e3fde0891313716c652ab453d6305fe9649cb88d527e2b3c7f2015e13d0570a44ef845860acf788af7e531c0deac69af1f711e00513cce01427389fd96bbf6e57eb91596781f21171295ec465f9f45d57a16cd7f1eb19963943b1242af87a1103f81e3efffcfd7b48a888e5a8d80c6b2d63e3be9ecd6e7553eb56cfe6e5d5d89e06caaeb4557670bdbc2abbda6cf25cdf1b3b633f792e6d5b4f67e36ce2f7879e691c7bb5453ff68d53b53475a6ba581607c6395085f2f0153f2bc2fdde93712cc5157e6d8b0e7e1f90f7bfdfef36be06c605ee639cc58150364a623b6cdaedea603c72c6caae2ff746ced4289f0667d39942ab769c696f74798571f9a14bae67d3a838cf4615b79a513f1bc6d67d353646e3a85e2c43b117e2b46a607a7c5177b89f67a162346bb9bbf5f8d4fc6b537189e7bf84e703ae6c5dfb0aea19adce93d18e24a323148cae88c44658367aeed8e8a39a31c073aeee9b9bb2161b43dd76e7c6c8181bdaf942ee1b8a5343174b35dd98188661469a61cd3b6255ac18929113a76245acfacf0dbc1e46de16c5397e2eef4fb2afecc6c7f757bc23eb51c2eb51baff9ec85aecec7c5723e714ece74073c742e3f6bb4fdf1fcbacf3ba21b740171950c9a422391d9a71447debc02f681c2da9945677c698dfc894a740b613fe3cd7d1b607a3b031aa8b6d6e7e5c3d41cd93489daac4463f2658c289bc4bf84835e52fbf3317777c644af264a0fe9616d48ca7e80919fb8d5be4bc90d46591086a1c4187a0fc91d62fdc6f6ddd78365e4ab3cb08f205d7581fc1745a191dc6afa182fbfd8279484e7c1437f0703dfe747db3b417f80a58e1edd5611be591d1b8ec87425ed860c54a9c380dadb2757d6d8272db8eeb373a467199335e97727030f142ee66d037acbb0c493ee265d26a08ea2614d6453bb0aba6ed0fcde9568943c0c4c1bc8461b25cf3e847bce397fd97d87548317bb2ffe57c246373f99ee665e43bcc43ee7cb89fbfbf3555e38de9b8826b1f2f4e9aaf11b11ab6dc86853f077d05c9e780e82df8f4e02bde7dc4afe09bc87463bc13679a6d548ae7fa3450fbc2d01fac26247f2f2231ae5979378be5f2ebf1dfdb50a0d9ecbfdcdf5014fa8b89e91d36501f12aaa45eeb1f1c6988ea57745cbda1e96f0bf341138fed325174b788143330c392c6e2a3cca4eed72aa38ff01cffec7a7c768db90da90ffe8fe55e505b15473123943b16cd594d227a918a7a68b9a821a594473973aecccd055ebba2b93457fbaaaa330c8285b06acec1df6537cdd850fcc2ac622e3cad550d63736d6ecc6d65a00e49ecd923fbd6a379ff75dfafd7e3917fe436d6f3abafdca643fde1619ab72e5edbb5fff43a16a2a0bb1d3b12d6044b199c59e65fe73c24b1fce29d75b6086da6df23822d68731f3cc93797cc9d531ecd268766653b6bd6471b61ac625d25b17b64db7bfdbbb7eb831f1ef2576242cb9c0c06882e8cbba7f30c698cc7bdd0dc42379bb1cbe2be4e05a8bdeb74961d731f6319df9bed8ae6016bec8de6c8ae0a1b82b14f6d4360fb7912799ec7f57ac49f9fffccd8c8180856d746d899c745099fd893ebb7907db111c45707fd295a8ee6fa74571d967bd1481807a5866062c151999825ac63507b9b6996cd8a59ed8ffdae7da90fe60db376515d7fbd4146b8def6b4a359ef0c83fa4616a90f6b78d31ffefe23eb93f28c98db19b3e3f90fc46b7d017e92b08b0fa5319ebddd350e3bb509dde4f241547af16c222945eca1f54152bf36c52244c64e85bc0bdb404bb331747dc025d4129affa7f390d6d5e2f141c1f55884f1ac8e5a586af469fe08f58f507f07ede3b10498ed4e682ab1b8761c1f8fbb4e2ac315772f9ea7283b24a86291208d87894f44121ef96edef78fbcdf6efdf3e433f021cd836dd36c3a4acb325b11c48a99a43e952a8c04753531db7382cb295c74dbecac43fba526da0ae17580d10c68e60bb32b9a612bf2cd9ee2a2e5ae0e58f64ee7384146e084b1269be0d30aa88753b89803a1f9897549e3b5aee6e987e2b5f29973197ec867fa3bd7a2edea27538daae8f53201ac7686117815ef94a9e98a4fc6e535392190476e93dc408e8dc8b0de81ff101e642d2a95cafaa2063d77b109fa899c9bc5f97daf9f8f62cfde880fb2d146d87b48816aa1a47f535e8724c5dfc2a7a47eaa994373847224f2dd823a23b4aa9bfa12b7cb2ec44751bbdc1bcfe75834a97fe44fe7ff36ce8bce0df1c197dda03e3ea0e5d634c7c146d4a603c05f16c610cb4d304ff07fdd93520acba1bc3304d1ef884f428d488775e6bb077d2f6f6abde2fae9729abd2283c42004900f641ba66eaf829adf9dd70f47c1d9bab5ca83fe7cc4f79e5d8f9b79fa71bc5f3fc99f7eec8ffe930634449b068ee2f4c0ee9ee0cc321e91a901c5aa9039e8a8a5bc85d528e419b5117fef319e4268b41ae7f08a4c1a07df16780cd72dbee1fbe3bf6e21e6a919ac1681e6db4bc265e998c62e706d381d9079e566b0e769ce22ca0122a9699a560c91373364948a247a536dba8be3c226b8ec0477fd2a1ee07ecec307f9ec7fbec694a7f0bc12363f41f5b8322533a73c9d9b44a7537de89f4cbe2739f0eed1cccf44e1321db87bee6387ba88806b4031edb526d4061bb42aab69c951594dac27b0d85f2cdf890453360be693f91c580cef86f6e9a37804e97a84f7ebf523f15a577c84d41ff93a1e22d1fc6bdb335f2607a4ec3729b608cdcd835858ea4be7f9ded04e03f8cd4d4dd86cadd84c7d3f8810ac587855042cb40dfc019177ef72247f8b8730ba456ad5dfce03f8f7a363ce2c6e4f9e1364b05478ff68ddf60099af16de04a705a921d50fa0f6fbab653b4a7b6e4de7f5040be0513faef9fa57ad73966667e3a031cfa84e2d6734b390e5964b5ec7f200cf1feb5e225459724f5837e37c8fe3acc9cc3712531d4a387aaab00baada5c6f2dca9e087a27a688b96d68e75673cb0f4a806310f4495cf31deeca87d6e7bfc347bca4fec857f1119a170d397f2fe6da51a9ed278b0eca30123358bac04752dcaadbba5099da1950c539ef74fc3996ffc177dd3cd7b136cc6953c068ff9ff3915bf9d7649f17a76a8c355dac673c25f9ea290f21f10180177c76c3a515d018e1930a15d53c77f5ea9c2cb82fc44b9ba476e4aff848b61ecc6779c8db9f17dd832e0772a93cbb7865b4d4032bf2517c2631c4a476cc6824f4049de1ff5f0017056a0840bc318b9f0ba71ac4500be3d5405943ade2a86acd26136bae55774aac12ecb080e4a5f271ddd626f8081ff977f511b0a75bc2c65a58cb6d27b16185090275b6462c93e74f832bcc914c4d7186c9ce790ec9eb23b56cc565d551763b4cff58ed5ee663ff58fdf0c7fa404ab7b2f4be208841390efb6dceeb32c810781c01ab8e8024279c69d60a2a5b5b31e86187de02eb4fd6dada001f21f16616f1e1ff828f30befe953c24c502e0311480077cb1b6e2c86f8a5a75ba8827aab5b3f680296c1dace3185927eb6c5dac521007fd6edf2a5f287ecb7e992751347592cb78045d4d5f941b5645dd9f0f655918af0dabbaeb9e8b0d79aafa6d883f7ec0473eba3e26b3b9fe3d3e425f878f632b3fc747a61ae48fc707ab86163c7784e777d37ae3a94d88fa15ce262a428e1eaddb41eb13d24a6820f7677f4fa3cf1d778fa598c62bb16bad32b822fe27facde5dfec3d081db3eac22a9ad8e3a5eb84691e09c77f677cce77004d2244d04f2f56ac06e8521ee41ce62e6d82814563cbb27987f7bcc4177e81f7fb1b63f9b5dc2f91186a88a5f601a1563980ff0468bead805e62295613b03845d36a59ed4177a352ec15c24b006b4d165f016f4ba45829da56098391e137209f51341797de76d1b23a8497787fa48ff0f5881ee10bff887fe4868fdcd9a0e54fde1f6ae811fa31f31b4ba8cbcb6abb862c4337cce661505b5569cb7def148b84d7ef23a7e325a9322326753bfab6b1ce1f1b80fd486282b97f57fad0f81ff1906b3ec2ef03b58189dfdd76b7258a2a9de853cc0647fb0b35aaf00004f4dadea2d7a66b752b12d4a9c2ff6954f58ac8f2290b19bcdcdbfe92f78c8f7c6e7daffd11fc7edc0746b0b7488d12826943f4107c52b0447520fa862e6a9642ec58f9cdc0ea05155e1b86e4a500b6641474a1d60cc36e2ee2359878a0f5c3ff9fbacd83d31f0a2f565f88ee62b3ac0ff69fdbf8b27e3bf6f97fc03ff2f946b19ab06c6b0d46fb8ee1a8e18eecf4b0b44675a8539eea23dc3fa2ec782c708a4be5dde82f697e06d411b7546bf8a535c3e51bf937f593ac484d95d11041bd956bbcdfeb1a56ccffe363dea1375eac111ec76be03bad522d3404960fce302c57628ae39bcd7ff1bf441ff9e81ec83e279dcb50947725a88705362de6d309852e99a328b4acb18e16dd7a8efe96e58f0496e697131ec6f371b2b6c6dfad1ff3dfce67ffe495c43a59043b508d3b467127001a35ad1d6be95c9e4ffc232ef58f707d84dbbab21824d779e4c057f6eb951da94493ac2739871fb199dcfa0faee577ce47f2599a07d9621bdb9a2c8bc013f9e978bbfe08f84666238bf80d02a2d9037625d69b4067da91fc4cc0ed6d5826c3b4029c196e931b8af18facfb23fc0246af49866e84fb89e7d63d0b3ae073d1fc4cdb8d46bd796bdbd48eae655d2a5e4330302fc1bc43970575260b9be920339fbfc245f8983ef55fce67ff5c5b313a0039eed1453bee512392c1777e963df7da0fc21084d0d9e4b569b9ad886bedfcf73c7711decfb4e0d0c909aa7bbc19cb676af565f3a7398de57e17bc0314c3519c21ca41f4e23b188dbe13d8862559b9d52be82fe869bb1f3a80cf42fc2d50af762068f3a5950f4a09b6628a67f2185febe71ac92135cef8443401331eb09a859ed09f07417555d83e59b2eb4fcfae5f9d5b05821119631dc48a07d653b5bfd389df3e13b777358f7fbe1ef77ce4277848f6acbe455bfff46a729f2c96e377eec17ad6dafe12d0a7a18ef8797b25cfdff2912863d3cad641cfd06a246d0fd64bdfa810bb4926b77efc41cc8e473c33ab8f0c33bc84dc4f8822fd3c9b8d1c15f20adfc3468138e09358db2d5b4e073ca0e80519914e6ad4939868b5ea0fce5dab3808062b82a32f676c3fc32ff48f7c74fcd77a1a9dcf1ea93523063d41b55efbd2b822895b4d1262c5f14f1ddc909deb9eec80c45e032efd042dd78df55379c378626a4bbbe655bf2be3fcbd7cf6efd547b85d85e03b2df7a5bd64bbbebf74dc704773f26ef511c8678728797e2238cf48af19dde4c55177f9b5ae53aca74b6227bacde3fedd26dfc46b65e387adea69bf4639544c6b0afea2f990c74ee2bbe6543f193ecf8e6c3e227518b78dea79284dd1727eb69b22c757e4f8c4efe1fd7ef7be20f6b7491bf303f0afab235b72247c222457f2249fc6660364bde44b584723183263752885da042952341b6c3ce20b7abcd7386ff9bdf578c447fe8feb23a224a67c490efa912acd56f6365a1602b4acb2cacf6fea23a9cdeb210689807f279f2cb503d854d331d8f933fa83f62179f73d7d64423ea7f71c9398d9281051eed421080fefd71f817c7d1fbc9c247f5fddeea5b9f24ceeaf8dfdc9595a48cb6a17e5a49514635abde7797b8c177e3e5eeb77d65fba6fb83f23a28f08426487d23aae3bea4994b04ae67440c74258167005a4acf33d57daf6c5e6f362796a383ed21c655f5ceb780c79a65b3dd67bfea78f646806abd1de17464155bd48bb46db691d8377f4113809d36c5cd7adbc8f8ce5299a417d26c8c7e098b5098dfaf318602effa67c84f126df1ef4a5bde75e45c4ff025f0b501f76c5dd4b6ce39dd453dc296025822f429ed5a4035a969691bc47ed8a5d1574e1487c3bbcffc18fe8236f6170d236c712e019e2b87a6de9b8de1dc353c7b5a1162fd6afd4c0078bb667873bdb388ce68d755b3af56ab108b1ce8bf25ab59e052d890f33eff4bbdff18ffccbfa488ee4f0d17c085a43ef35c0dafb6a229dbb2be62f79531f6131b5496c2d8bfd4deaa3a3fab6b3b200b716e47862cf4feb61a57ac457e92384f609d17ce7fa9ed76e5ec56b3dbc927111346d4c6b8d8b215da412c4024cc7f89444adaa6d386091f091b218082ae683fb4407a0cfbbfcd0badff3113ede22d68f6c3b90ca52656220856023cf582d9680c900533f829ac1d3b3a3686ba90a9e6288c6d99fa5da2a60354d681e89763f9f1fe8e7bfaf8fd096f57b838f415387cd50aa435ec5aff591c4f6c5a20601eb1050500173049968696f85b158049f2ecbe3cbda4e3eaf8f5cfb0e08f661d331f1eed87d04ef97e083396e8c1ca5931f5abd813fc03c0fea15ae7c7b798e1145739d56a406c1223eb1dc498b3d6bfb037ce47a2facd8fa04b42619e42d4aca3177d687cf8eea7904cb86d4f9a231d840ad880586d8f0f0096aeda734fb6c6f6369ec3298cfba4195d63161fb80e36ff1b8e7df5d8f7b3ef27f5d1fc9d0271243c5f80944c02d05a90979eb6feb23895d2bad2515062160bb1f4be4b356b3bf6a506c741697ca69e3ad2ef4a7fac82dcd1bdb6edc915a330d7ceaefe1fd128c46c0d66acd0fbbb2d40eea98875eb044b5174df7b02715b0b19e124d5fa225d4b067f585599f084ee377eb2337fe1091d45e2798bfc162238cb70d7f30aaad6ca983f59002f5479df38b0a3e251027e79078b9a42631f00f56398244764add5eadbf8923f740aac61593980e6e7fd4aed6eaff677dc413b33535787d5bac97ec8b505ffc57fe9124e6374ce2a1a00e14727cc07fb2cded64e9b0fa4bbc96ac250449fbf3fe5efb474c21e14d04fff77058393dca237ec94798f5fad851ed38020c76829bdbc17d0d8eb975b9b1869d64eb2b1b7f5724f14efe8feb2357e306ffc654f5edf8101fa55e6f3128ccc7e64ac2a71cc92e9e77c80975181e3e791df29a2a14678ca079708ae6cfa7c818d5e7557528682810a89d2cab8f7c948ffcdbfa08af4b42eab0cf9f12da8ce5fa7aced96d4feff84742763a927828826fe52f5d548fd1e8280d8093d37b529fbec87180b53b5bca9fe823d2cdef8a24876fdceb2163e9beeb1f81fc1675bf39b9dd1389ea83d8d7fda02eece7f5c9795f02440ba75529f437f356c6bfc3e5eef10fea237c9c58ff68484a5552a5617537ba0c14db00f177ed80c714a2fc594e285e1bfcda3e983cb7876211a46b466483572c9de5ba457d3cf4814f666aabc8193ef23f7d44caf0111e0344e4fa6d73d446c67bfa489233c2eba35b8e8ad5015f1a1db6ed36c144817bae8412c3a8e7314f9fe9f3adfc9bea3710b3142887f3f818711ef82b3e12207feeb907691f90ba90b41e23cc45d4306c1d34db96238d01db85e46a5cf3ac9ff58f907502dfb87b50b7dbc9a8eb885009c37526cf9b95e303c6318d32e5fc9de82190496d53fce64c2c047b0f36af7664e72647499b0724ded94b629e7f878ffcdbfa482a4f67f32200cf7c3c0d241d2abffd3a5e8bd9b4d8097102a7e5349cd3caee4e572bf740f13c80465d76c23123e78e699d910f8dfb3df9f73ac60878e078613735ca037f19af45682c3ef1cab1067c848c9dc4d36eed66d511301fd1ecdcfa15ac0e84cea6cfcbf2f5ef5e773e2ef22c61234d7ab2bab7f56595a057b89b051d872b04335ea188561b5a237a4a2e7352b53ba10ef03b86b1f9825e912c193b6fe697dd4c7d95df89abfbf7f5919456a4762d598884d1d091cc77f491eb18da0e9a38ca76307b3ece84b16f0bd99a883ee623d45e92faa93f8e5f7e3f2759ff48d6be35277913bb993f9d23e37d7d04f8a26b5bf23e2076aba3b014e2738cefa1b63a688979a25ff29498c6c512db5c363636f8b27cf677f9077f0ee0fbfb83c6ab232eabbb97cbdc83f04b6b6fc37a78f6aac56a036770c4a8851e9f9029d81aa99dee2c43f50cc6537cfcdbbc535b99a53dc3adf1afc6f97bebf1888ffc5fd747b2f9002c8f0cef14c85118db7dbc4b24466f33fa48821b9f8df18dc02b15c6aaa088d2845440aee39d7680fc7282b94e6bc3d3ba7ff0ec31f1117fde3fc2e38de4840f022616d61f26e7e919d0906e6391794be2b53a9dfa60b3ca51bb15d6d6f7b302eee7585f0cb761bcdf853ad4a467f5d4d3da9372663d7e62fd135b93ed369ffbeaba8fea47fdec42cd94da0c34f1433745dfa063245868799a3d06bc9ebe67bf1320c68054f2f3e13f585e50164dcc4b9dccbcff8eaffddfd647b2bc04e8704920b96bf360ba3a6c889d3d93ab0ed88dd50e41302d82bc4b6befc28a1c0347b93ccf7ca801fb90fe3ca2b75fe11fa1f749ed72f01efc3b3e5aba53a89f48ebad03af031c2d6f4671c4f07b1fa24f2469d1df2aa4d621e16d0ce7de17764d3d684a398811c8c41467fbf135f9ec1fdf07445fc4fadd585adb06c49781d67dbcdcc6cfa5793c473df511119c7f6a874cb16cf0ffe1a48045b8373ccfd635c0f14a7c241fb53d92ba637778674466f827f4916bf93ac1801576b65bb9d806e47d53bb08a33d60632708a60e44a1385e24e56105d6259473ce8b81ed339a9ecd55fb6cffde937f25669383ef207e0bea6e8c56f261c970b6a6a9be742cb9583af14490c32f12e687da60b339637d0374241dff7708bc643a26363893e681b33e68896ec0fbf515f85aef5d535ace6c6a8218a9a3dac2253cc0cde20ba419650c9b46e0717414ab99e5f7739920cdfb213ea245657b6eb7ed2a7d168903b3584de6b7628fd31ccd1417e5c656f98fe823d7bcc4e7f2e86a22c93191b452dc131adb7b3659fd114c8f1795cac1732ff3b9b3d1d0725d4c68ee77cf49aa8f58577c847c8fa52675e92ca556e4a84027d3bc165acb0ade877bc73f06b63edf9178325a4f90d7e538115e7461b55252fc965b5c949fd047521e4fe9b52ca851d47b2e2d19be00d30f337c82e81d503d228b029ed82033ba18f70fe1efd5a56be7b692a0c2f8af6c5beff310daafd91d3e41f08fe823fcde59b997c8dd52415980c60ebe683adb1c9b11701a39dd6a87581a134aabf616e5a42745c5b2fb7dbefd67c7fd2b7d244bcb24126ff644ec6796303ece94093269056db21ba8871378c8133e21aad2468af41c6f2295e48b3c91d83589e94d58a7811a2322c7f84d62a31facc777af3b7d2ef35d0817c189c315ded1047311af0dd8193d86f742eaa73074a48a7485ea94da20134bbee3b2982ea2c13b6de925027b16f0e4ac5deb57bc5d62fde27867d97e8f45ed1fd447b86d4b16a278eb28c76ed6dece69d151a379ed64963bfe1ceaa63b7e5c1f6f96ce959de9cfed56efb56cfe489a8bc2fd3b24c70350d7e6bb4e03e5c9ee493c693086c0777cdc7f75244d2abeedae5040fe43f1f979bf69ed453affc544cff97a7cad8fee013abe9510db4d6138f22488812015228ecfa9be48f52ee01b903792d4850c533e42f495691677003c8f1477c0f7aef8c8efe26b65f92c5d9be23fa58fc8895d9cd885963be975596031bddcdece6c41a701ab26fa9260cbabbb53e5d5ae66f2daa41b9fed77e923a92f387d1ec57ad934a43e660d4e6bf54a24ab6c5c1944f775a6e7bdb7b0833ecd6581382d7a1f62c3a27573b544e7a14dfb717de49ae7335e29a8d2c06c201330fe034470334946db1a793ec98c83fa309ded096ac32478676e6aadcfc66a9fb7e04781caa94a636b462ab337666d85b77ac86dbfaee31e12be0b717aff8c3e729b13087ef6f14075fde3255be79c790941fec5f22e541c5ba3b3dbde3a6a4ec8d9b9a9d0e7755cafe27ebe674eb2fa48d63f42ea30127c10cb6e2a879c93438e82f5279e93081ec357f4ec843977ad747242d49c137cc290611aae12599cf2ab740db2afb3ebf153fe91745e0361073e128881809d4ff197d725c21b7d778a29165ebba8ea28b649ac2b2ac14913a9fec2e2b692f53c98e809780a928785d241c8621c7f540ee03999b7f2c3bfa28fa4be544a33a85d285aac73deb6933921bc462dc38d27b510318dcaf9919c0b769dde19eab7b25cef2c4dff2ccffb883e92ea53795e5b96bcc7fd693e97eb4e036aa4e0fee3b140e51e67e0a887cd7cd2038baf4578ce85f8d02516f3cc7410c045c93c4f13b3f5477e4a1f91c4ab7960f6b6cd2ad8ea9b06a9e80afe11c21791868cdd732e3ca897d3c93b1f5adb5cd4583a95dccc36402f838c64f091c01c2451a860c900ebaf671b4397d8f7ee7dfb591ef2d67ae8a290600d6778c93fa38f6469c78cd455b782ea746e1b409b127b3a956bfd53612f202908d133601c2a7abb949bef269887c889ffe07b7908a5ef541fb9c583bac3a10aaa81880ca73777b0bc1d9aaf4ecbced9fa69b43cce03a12fdcc6eddedaad7eede7f949ff48c29f09eed7408876b930f697c013730ba4b9bed4474bed3ca9eca4a04a72d707244a73dc1b542fb9a5ebeff10102ea009589180e338f9df0372bd76f1fada1727818bb70dd176ae7e37863f03a809a59558bd43fb9890bf8a7f4112eeb921c12afd7772bb1d3a6742acd5727396efed940f5dc0ad50307d363e95ccdc55e0f0580e974937ff0207ee71bf4917b9a9be6278ee24e67d328b9fea6d141b9f5f445933571e735ebb90d44f04dc734de39fd7df29cdb79bea5a13fa58ff0f173fcb09860116f82de617e2a21a55fb48df373242d8ddc363ef9836829447e8763358ac4c7b110ac5d0be576b93de137aa1380ef9d56ca20b99a3e324ea361a82a342791e4fb643117b3e3a7f8c13afe4c0bcac05b853aa9bb05f52907f75837ff9c3e02f60cc0ffc5f26eee903b625a738f9785b975eed43ee7ceb9cb78e47bd5f305f9d32436eb2ddaf3f573721d1f748fed91e0d36f54370e0ab37c2e8e437538f3d5218925037ff28a8d393b07bfbf1e3fc547b8ff8ab6fed699d55696fe126f4a918e84b13022bea928ebe722317298b66baf3363333a147225c04af16cac7f402cb04d7df1b972fb3cc4648fe993d49ef7e67c0026817014bc5c85d52b29da0a60d8072ac1f7baf1a7fc63fa08a7ff80dba8da5b4774ba1c7b916abb6077df8061be0ae8fcb9da255e74b74a50f56d51c3b323d2e8f16f18f77bfa48f673fe7cce174ca077c2c64650a71cefa031ee27d8de8ac24194585ee130f3fbb778f4ad4de76fe823f0fc1c5d23c0c9aae766fe6a12548d9ced063dcc1701635e26747e2f925acc80cb88e97c4ed4fc5e14aea4c1663b878c5e88705c2344ea5842fd32476db7832a99179edb93f5ed5f8d1fe2f0c4d154130d6301b5e50591d48eb4267541102e57f514ff257d24eb632739e74b6777e80d1d35883218f0e01391b0c0e2e4ea585b5ce61aa131070c912e96ebbba4a6eb6d3cd39f61fe7da43dce677f84ff4b6b39d1fabb7dc8e1034469868beb135cf5eb9a8a6fcbe16fadc7f7f291ebbc47163f0d3638884983532f0c720aa3ffab441f4c7542900ba02689e7db4155192ecd5cd3f12fc5b9437cf381a3ee1d641c874b9b6153666317565763a557c8640e21067a3a40d3a8eb5794833fc57a4f84cf488a3b96fcfe9fd047f8fdb86d1bd31f1bf5835c0bd0d9180f11a87d1d7cb7b3113296657c42dad16c1212f9136b87c4bf9de735fa92fb7ea53cfe963e2265e8dd98bd4ee76b94e4d6913a1e50731db00a99ffbcc8f0e1adccff86495c564a43ffa63e92ed03e80a47c6eb8b986f00bd2f0a62ae436c8a75d6ef27c24358aecb4aa5f54be07dd00baaad4aaebb5f23e3b02638296245dff6b603d75ce648ee089b0fc0b1c9cc41c6a6e51ec9bd087ebddf8fdc5c2fd70f0ab901d661c2ab3a586cddfe117d84c7b4723e620ad1aa60e7d6253fa2f6776ad382ca03a79a6dacfb3bbfa535fca14c6bee8912c3e93059bd8bdfc5f8fbb339e1fa88ff40a7b8a57f21f17ba4d8ef3ef3a97b045f3dbd278d75a5afafe2bf7eb91edfc947a42b3ec27904d11bc97864e2db294fb56088f9058d2d83df66ec4e09963cc4a3c9f1a151885f14032d5127a7c6addc30378adb245e2d169603ce0beed72e995b52b784c6b2f59d67b4aca27351c8635d644bf26b6e6c8cff843ec2f908a7c1f833dbcf8d1d83d8b26c6affa048029b783d3dcd5167331aabed31a991fe94c439c98c0e65f59b8fe4b07d561fc9f29107f679f2ff1ca931cb7f47fde8f7bc8ef3a27b3ef277f5916c7ef988f61feb199467138c809c26529c2da8035ce4b8f1ec3ffc2a133e0316e14dd00daabb56346b4ba5d2c226f98751326f746c5a369fe86e1d0097c511b59c9e9b9cd63923388c9fb7b6f694c9abe1fdcfff33fa48d63e84e9d46eb1d49102158a0f26e47b830fd7b59b1196b0cc455718e62c8237fe995aeb9f6df7f547de9ab38f7dfee8bbff863ef2b85fd79f953f7c2fa0f14477710f801f130d499dde88c90109de4046af58311e7c112566c7c2ba085eff3ed489f7cefd23d4fb0d4af81e9704a32bd3ef7f421fb9a19d801faf09cea13370310f3974793c694edaef4fe3792f5245adcaf3f1a42feec79fe8235fcd537fd58fbfa58ffcea8a1bf2993fe42d1e9ce181787d0fe4eacc9c9191cbd98b5c1e6abf8bb929d7ddae7f0fb9a4c43626e8605926759891d75bcfe7664eee15375bafed37858d3025eb71175bf1cfe823595bce4c9487935ca16cd30a37145b03e5734fd35dfcc264d57222f7fe2d3ef266fef45f588fbf350769fb081fe173457414b04186a15f9b95436199db9549fd9205a9307a3d4e562f136c8350af17b708eb2ee3a6140ab9e7fe93ddcabd10dd04f399404de622b32eff843e721daf9587d8d7a9bed9b93dd7869ab3b40e0952ec7caeb86b092afc36f79af871dfcf47ff8afebdc553df8a1ffabef97fbc1e7f8b87b06bc247dee2c1999c50ae8b093551eb54ce9dc5292ffaada99ae872e9ff595e08bc9f8ef16bb0a15d367650ddaff242def68c0dd6491667f195f8db8be296e87cf0ff61fadc7f421f49719424e69b8d8793580d84fc94d51f111d3576367ed90b3bcc0e547ed0b79f6d6fe239fd85f5f8eb7c446cffc6ef434ef761cd67fb7117744b5a6397fae46fc64ae2a8217f0605e517df6e17e68363b5b4c83bad50180b3bf195e0c5e0ff0995441fb9e5233f4533be4b1fb9c150124ee293dfcca361df518f5df40ab821c3853d8e2eb64bec1f580f017d84d460fd8afc908f8cfb2d9efa3f7de49a8ffc8a075fc75bd589afa587db147800c43e63f96140af573c135fdd13f58b6ce4bc9bf7ec5cde77957c20a8a41e4091f89a004b672dca577e2a729f7f461fc9bef751900f072ff9c8e94532444d0f17f9596916cd76136ed710a7ffd34732ebf1d7f9c83bfac875ff68ae25593fc39e02866691f9528aee9eadeb35be097c2f432c567eae079528efa32596ba35d1f2a19af88ac566acec86f0afea23927825af8a6301e517f96554a0b59db0b4d552c5ed589a78bde980c9ab75a8bf27523ef213e37e8ba7fe4f1fb9e623bfe2c169fff32cc640c327a49efe9ec661257e113eafa486b070c152b61a96f32bc53feca7e614eabb6f885f5d26be27b85fca5387e973ff017d24f5e326713a8d553e6e1f517d07b1a1a1e3c792539beff2ebb4ee14967fff361ff99f3e9269bfa58ffcde38a534d71362b2c02702f1c5a46e7d366f472635869358eb749efe097d449a3f919c9121f7cf06d563538b91444e887b2a389dea6287661ea317f83f552343b77e62dc6ff1d4ffe923d77ce4573cf82dbcb3ece7d7df5fc72a108c66db05ccca1bac4a7ae57988d97c24f99fd047a41b2c254bd066ddfc46f708ce2fd4a3ca0d9f979a7298aa24d694fc4fdd313ee2ff4f1f11fe037ce437fcecbf3bceab9c4e21ad1d63de7c270991886ed623e5233f4533be491f813c3cc24758ce403008aafb97fc561b3bbe13389d4a65631d7319cc5ef85f9ddab7123ef2dde37e8ba7fe4f1fb9e6231fe5c11f1de735364a5a0fd9baffbd30657cc4bafedf3fa18f2c6ff4918b3070e3dddea9ed44a7634f7687fc2ea862f97325c42e64ec04583bf3ff3a1ff99f3e92699fd047ae72cfafda639cb43446fcfa7fb01ec29b7ce4a768c677c66b59694381989fd7abfbfcdef595c63cd7dafa832d44bd4990b727026e8a26d613ffc8cf8cfb2d9efa3f7de49a8fbcc5136ef7cb23bde3d178d358f0340e8b3f67987c47df833e62de3fe71fd04752da90e2a21c85d030f287c5387f5cbee44fb10af97b4286e730bb96f43f7de4ff943ef2d17e3e8e7f4ee280d97b9a8793e27e65f1b532fffb17f491842f319a02f537f05513f2f973fed218e74bfeeb5026d8b79737ed5a3f4d3b7f5a1f798b160f7f431f796b9e1edb941ef2f8876d9c598f4736aa8fdab2defa1de70d3c363cc5f3cc8e2bc58dbff9ff8ff0117e5e299651561ff96afc117abf25a93f82f9c458ca97f3957cb551093bba9caf2df75395d8346475472a15737ca59fa0dbb77233f0b1efc4d07fbb1f743d4c9623ff317dc4cfb45fe9008f5bb60e318fadbbb231e1f5e0fef3b7f48acfd4307e340fb7afb3ebf1f3f85ad49ec0f157c32b9af45534fce65eee49cc4f07e29350135f3b55af7d32267e589faa0dc9eb410e5ad52438ebd7f2e8775e6fc74a5b98e8443fc543a49bf518b3f5784ffeff55b3def99f2cbec747f281caeb846570cd6eefffe8391f6dbfde9ff7eb91693fa48fa47c24142f0fe8eb17d36a2126f9de34275a225827940ec904fbc4237c84d22c9fd4e9f8391a7e3ddeefc288b9a7e38f6833c43c0576fd837dffc8fd6faf1f6bb82fe292c54c3de2236fdfff16dbf2adf6d1becc1edc2fd547beb371ba4069c325433bd3bcedaf7806cf1fa1781a9a38142e538de06f50fb46917c4e9f6933ecdbaf7afec7fac7691360b7431efd85f4f3279e9f6d2693cb095db6eb1ff84f5e949379cadfbc7fffbf3c07bf4a303493f7599e6137d8da980f9ff5b167bc7d7d7f6d603d86783d86f779453fc6472806229ccbe8863e7d3d1fe1b488f31022f7428d756141f29d57c289f011f21dc341f9de764fd7a8bfffa7f491ec3ca7f149b43dd20f6f9b7cd756cce7b07a976e4ba4a6d692d91497fc7de633a85db948d6427ea71fd683f6b8ef69ffde9f23ba1e9707f7a27ce4573682afb8ca62ca4786552bc114e432e7573c272bbf9a097ed3138b0386185f8d60f031fa553e913ee493ff7ee7f8effba7114c90a131bd8a0ffacc75fccef7e93c6b09861869f9fadd7adcb634dee96d1b5cf6b7fcf743f1de3f71cb43987d89ac87f98bf578b44fb8bfdc14efe7f851ffdfba4a045b8daf8776751f6ed72a635a52c634eddbae98932eb16e1888911818174cc323dc42b1fd35f787fbe0c6de0b157169378472be413e5f62fe5912eb6239af8841adde08f019c5fdc837f1ff9658530c4401f7e59bc79fed1f3c17ef8836ee179e0bfcfccb679f0fff87f97ceb3ef85991b8166336efb1d8c6cf0ff095ac87a8885311b146be4f7e37157ba4f9f83b3ff90d629fc3f7118c0b7e0ff7c72dfb9c645dc4a9b085f742b9afd1fe0a5b7a9faa49fa875fe75bf8bd8bd7c91185db7e90fb07f479ac5f117d3eb9cff5efda99e7b6afe7fdcdfd73b31ed97d09ff4ff8c8773656cf95e82143c126677528ded657fad3767f9f5cf219add9a493384fa0514fe2045fa13ec933c593bda2a13fd828dd223cf52be6417b380fbc9131e2f1f271f2f520b1d24a89c41d4cd89a641bfb1cf2fc48aedfa3f7e9ef9f32cfc9f64583385b524f8bd17e786d7b42c43ea3ff7f26f7a3b5638677f7cd5e7fddccbbffbf3fbfd2cd7adcec871fd447680b983ef2b3fe658ac9047635c065c42ddf66b96b7fc7cf4d1bcf57f8ea3ed07a88728a2322c4a4663dad590eef8fd44782758259adfac0e771af5370fc5d22e333fc615e7791e2f79e389600f9ed8ad445e1723eadf7118a69be798aed2ec3ef31bfa7be970bc164a4cfa37da6f79ab3c6c7e067740dfe0c6a174bf19a3976fc47e7379b3f92693fa28f709990d2ecf8dbf4117ebf3bdb382060028e2bc95bd626ae1005a6b099d721db9f61ccfe843e724fdfc32fd347b27a42f619f8fd322fecc312cbf7067c749320e81cf00e9c89b978f760ceb84d88df270f35ef670512bff0c4e82ee5cb45c8c9110ee435a9e58b9f738b332933db626a83c2cf104412f340d64c3860699cd8b4481e21d45439e2d725725fa8c37b209fc5640cfcfffbc45e16f35ac2cc2e96ceaff6a1f94df7677ca797fd1c1f91aeceea4fd36ba85bbe82bc6704759f76826a5735f3b2c977f25da57a87a3f1530d685ef42d7efe55621b92d99c639a0c7e21c05e67b6218831003b928fe5eeebdf4b499f78ecd22c638f9ab3df917c72527f71c19e49ff47b1f72d429522e69722cf6158f184cf08c7734c4e288d89c03c41047ba39fc18ca73c875d134c4d93f08915b3abf98cdfc0fb99282518fa9cef7dd17a103ef2dd34f4dae6417d99d9cfbfeafe6f359afb3c52abd1cc5cf883d5601c6bea2a1ee255ccf732f4f2bbc77f6fff09bfec39591b93997cae11ec5cd353817f046577253898427860e773576201f351a09d6ff139763f12ff6602dd263adc13e0ed923a5163767f9954d5d9807e11f46c77de12c6912a8c176b8243b3d17d71e46d883ef1446a585589df2a8fe79ed81601b3a4f60235dba15f049514783be0e36be535d65b3cdbc59f6ffc8ed72375a68a3cff03f051c01f063c86d46261ef3336b38faecf2d5fff793ffb5bf9235f1daff5b8d17ab383a05a9ae6fb8781ebdbf238dc3814d552f879be96d2adefcc1f019a5c64fe21a0f93d4183da82c2d01f28077fa03d939ddd2f439cc1bdcf81c65451ba4ee47f42a38b04a7be2f8c822adc03ea69cdba04f710f2c4b5dd24a8c6dba3d219ce4ee3c3a23f9f98fe7c725c4e1cfcec1ea9f3e291da2923419dd7481d15a233f8767e405046699e79405eefc457f8ddac8bfb7a094b8dd16e01fdc7cfd2d86fe87e2a126cc680e8313cde2bf58f7c7c7fdeae47f2df1fca1fc99eebef8fd7baa7d99a80f784bd8d2a950aca39bdbc9ac73b05d3bd5122df7eeff81fb534ced4fce4fd6ffe9fc419e858e2d181b60b634ccfc7929a1f356bf9f1d03d343ac361c57ab55dbf37ae82dd0930907913a6f8f4e8995c3d9361eae39dbbb1cda3d71945b6badb6ff543e3ac4dce7b6d30ef29bab41ae4b555751f579a613c50f2faf4d45f9dfb4eebb019945a1ae6de95b8bd9ef4dcd2586d35472b2b3ae527ea36a8af2641bd75995ba5a95ae89e26e75c3cdb1ecff8b35dde681879d37a3e3470bfadbce48f7a9e35693ecffc4643186f1b82ba36bddeccc37d2c10dd83e92384df5defbbf7d7275d8f9bb5fa413e42cfa57f95aff0557ce43d9b8c9ccfada47c14db9e7b7e723adb95dec1f4b481bfa731c23f35feeb16629efa1dfa08e8041752d703eac5ee4afb5561bc6977cfea76e574fcc051679a6dd85a3e7f3ecc06a367d0cf0856885acf2598211ac311497ddb94fe8f877e6e9e97d1325fb00dd4705aeb81b6e82aebcbfae828b6e5fa3b11e5b627545f56a0b2a7d34179473d89c8e80df34fdd7369624b8e32f15c5f2d3b8a53cf3fef7aa6b82fe65fa6b57c942f22e358b6f595b88d96bdfcab23b97eae19a0c0418a3646caf4ec280db1f47cb196e77543162b17c9392f64613ab09bc0a7887526d58d3ebebf6ed7e36a9d3e943fc2fdab5f41534da1f288f67d01cfb88e191d52bb3ca18b58063faefaaf4e6f8d169ee322bc4ab22d061b526f84e526de8e97cbabd9f6153c8ddf1fe45e8ac3a1fd525ee6beea6c9e351fe398daffb17e01f27f046325be08ac6f44c24aeeb5b74250a8acab3b7bec5c8607bca37d5a47d0733ccff16dcb51764779da1ced3535b8949a23e7d01c5d4aabe7dcb45591660b3ba86e0a54af001d23345579e7c9ceb18514a787958417f4eaf9e815aa4103fa387a71fcfd86d44a7f452fe809ea17e3cf425a3f9da2ca220bd5a12625d457a7cde99c6ac89091e31fbb91dc8e1c1f2b1fae3b75fc5307bdee378abef0d6c8f3e700dd5cc4cff1f1772ad21c75db414a472b3daf2cd96d0ad124de1c9cf2aa7c943d6103f341f598a42ee23defbd97376eebc164f3d96f65d16c5defac7c9a7e9fc6ee5899989d22b36d739ec1e85aa6ae50d0d792fb5ee713143334959f7d7a7f6287279826f4391db8129b8c943c6f85f901b7ab139ab755647fb79b3d47e6317f29efcb9806f91e02543ac76d394b4d0ec45762e7b9cf470c327dbeee239f0f29f98fcfed3cd01f4cbf13db3df80b660556af89de9b60ce82c4e2db7633b4e4b01e4e816e5fd873c3cc98a15f17a8614e6573ac0300ad8c092e2df1f3802e013a861c4d8abbc232528ca3b393b6cdad1287ebdaba2ecfec1ca6d9e2ba6febfb29a6e712aaf31ac3d0f02eaeefa7c8d837918126b899f835fe1de60198e6db7abfdd189ebcf9bebadbc9f25c5e4cb6d54d13df7313c37d3c179f3417ef5d17e613ee8bd895d52ebeba666a1a939a94b7d7f9f46cc209f317747db2f783f750cf32fd1cfe87ea709d4f497d4b63273aad4bde36d683308e9e9cd3ca9d9d6cb51f970ef25218e2b54b6a66b1bab932f511111bdb2259d7d43ff2988fc809bdd4ee68e71d3d25d876cc66228ed8556376067206792d3b567b28fd2fe52379c0c84b1a7926b197a7e71b9e4b7609d49510a97ccdeae57903669b9778fd55627339800d1f9e3d71e515eae54d390ee3852baf97036d305c38eab104330d18f2fdd56e1fd4831ed61ad39c85bbba796fb66b1a948e5522f55fb98ec36cf6b88f03db0d62a0f3761077826abbe30f1ab2bc91b7f26eab3a85e3210a5be5381cd98ada6bcbfb5debe0ac5f574f4ab4158fb5bcb9685ed6fbf9a23b35a2705ec374fde45554dfdac9db716165a1a57c6878f2d1360e9bd171ddec9686bbdef3f48cea40c79d3ed0f16c6d61a80b09ef1d17e839924e5d07d1faf59e803f17e077f0b9d372045b6f885d657f6a94e4d3a2525a627e417eebd1fa9282e7a6f7fdd32b9c12273c0dc83539c1bf7b1fcca74438654e1fd5b727a7654fd072ee8d66f259be2c26b60bba4b80e76e6d825d0f743588e583daf6ac2e31e5d961929b9862a9a47ce43ed7eb6ddb00b55d333b35b78fc395c8c1ac0eaab06035e7ae65705fdc5ee5b4515c2c6ec7a7d70bc3c1ea131bc600eaae0696d0c3f235d4952d62da3b20f436e03589927e503cf1fef124975a553bb7779d4eb7ebb466235477455239d4de619a746af4633306ba2cccb97ff8a1eccafd06d6ddf8c34cff891f9bf59bfb81e13fd1726f377713d4558c756b3b5b2b95cbd23c8cf7e548420b90df4f2b3b87e5efdca621976b2db7e134ec5c577594a86a1b3b1529589ac03412193196fbe58aa31c36276b591c3cef4f8ee2faa4fa696e8d65f593e8dae7279473dab651c67a02de25be5ba47557f889b86d40db6157d566f834456ce7b3069f631a6d2ccab621576c6336723aae434f08e121c9eee6fffd448b40fa3a6ac01be05e595ef7d1fff33e80f4e716d1ebba84a5bc3c9e8f2ed6bb4c8495ff69f5b4cabf46d2eeb044520ff3ee3ee5c7ac5e09958982aa2164eb60b25800c2476e6396eee5fc5bb92dfddc24d887cc4eceef417802a9972a74494c148bb711f64249ae667308001b8bd5404debd9be08d1465e6ce55a77b92efaa3d9935cdf3841bdd108aa935050a3a53fd814ecc0efd96e43c2322720540e40ef00f9d37617f6b078aaca8d4dc3e9c49856e20f552c23e39de2398147b8b6222bc20678d0a07eb9f533f3bc81fbf8d4ebf1b3d7980ee5f0b8489e3cd4f303dc2edb55157fb0b0d7fa20aabccacd4525aabafe768f0c38ad5883ad2319cbd4b2dc22fd1389dceecec6a4de16ad058c8056af11dbe5aff01b0705c8899c0e6e21dead2a8c07d3fed76309768767b7b7f87702192f9684e084042ea5f5b4a6306d641e444a7b815fd416f85e61c263e0f7c813e13ba8418c4f5b07fa4aeee993e770da1dc2ee3ce7f10efd2c2fc1e3b9bc523e02f3403fff0d1e05f52e23ce0be9bc8124e84df17b1ff426b788f98ced78280715c7e5b6dc91bb728fca434426e232c2e54a5e6075de091fb9a5ebf74dba8aff9f5fc5efc8ccf7594ce46a8fc8d16057b1589dba22b9d2f3da6379d437d8de98ef34e9d9750f72ff7894b7fda33cb08d460e8f4a8d9f26c38e793ee4e63b6fdd528cd9f37479cc6f476b7dabc5ed714f1e0ea2997f9c355fec55bbe26aeaa9abc8234c8b7378669e306dc1b486ec0e1774927e551e035e38f0102c97fae2bdcd29d537aee7e191fd8cd77e0d7c5be8cf03596b75965aaf379a48fea61c384ec79fa3fad2c527a048a41fa071f563c9b5370bbaba0733080f265ded2062d291c0e83ade9db21e844e3f16f18e342e81d369ac515d9e805c7ede9e65229f3fc1ee3d5e48ed6018ef2b919c42b8774a736f6934f42be5239c97105afc047c17f7d7056d1c346e7a3af895d26f72423ecb4742ca47ae7992f77bf788d8e91758fd642c2b1c75cf5ea3b943aac622a042e8153d3bea668f96f95d1ef4423d8919a33ce351bc5690f847ee73c3241e170aafe74f0fe92acd1183bc0c380122d402025bc2622d8c83ae1d6c0a78b77bf63cd22feb4533323a43d988f4682e9bfe201ad2264d84b1eddb41d915d48d8ce5f62e5822a3d9e6509137d170295b918c34646863644455a7851b9638ec5cb83ab8ce652c4c5fa62fcb812ced7a726e7ff0cc6304dfd9bad290f3e6080bfd2b3c7bde793b9c7be2c1a4bb06d344e570c67d061e5865b6744bbc9643b36dc8e682eb1fa71b3c27fc5fbf236c56137fd0aa18c572278cb1a66c38116896a9fc8f5ea81c7f960f3dd8195e2817405f38cb9486e32b3e31f4f76719de7bf6aa15ccf02e0fa1ae23ee3f3e194ee79c87131520321e52ef113dc14920bb01f409cc2bc33dbe0f3e6da5f547f59144da12fd19d05ece3328f63ea1cd02bb3f97dea2ac0ef137f511ce1be93588d83ad3f9861a664f5083c6b6b0045b959fca65f9797126fab348e49fd47698fad933364ec647a42b5eb1baa193b7f23ab77145c466be035f68531feffc81fce20f94289cb4b6d573abda1b9ffafb72658965428bcac90bd75176f9d2f3b20872b55c742e7271fab2569426d865167d7b355d58cfd3557527bf769583e7741dbfba845542af67079049f1aa16b09422396a9c43468049219a603979009f23033edf3b2887306dc534c327920b60c70b9c2383b5b1a5f6ebb206f5bc135fb4959143b3e37ecc4356496c299d0755186e9b0d63ef1f06d3722cb1d380980d660e2b05348eb5d0f1b9a4521003043b035615687cb8872bd71fb87e809ec0928abff7033cfe70cf258b7487111a0cf70ca1b21d3e815802f3222c9961698956defe953ef290b63fd113017d3f6fc9fc855c12e2349ef195e26fd2fcafd647a80521e527841f018f83b985d7a05fd986e11484825d98123b225ec35941e860396295d1bd7de1fc48a648fcec599b70d64f3014537bd798fb1ca88f539ae88b8d24d7e393bd2a380554704fdef274d8623a6f5cf2207b3baabf045a4a3936ec1864d5167827779099b6b881944b3eff241fc15e1fc6abae53d13705afe0836d06aff634004b23e6982057027dc0eb32c33b0decef1696bfe13dc89ff87bacadb9e43b44a40f87d312b23b4192c1f73cf69cea3a57087a5867688f83baed635e46721c6c379145b3ba47d6d6c6f806e840c033836e50ef0cb7b3c358af290df013cc9d6607e4613f82534276a840b4c9a720a2340f788447d0ba0b7c77c3dc10e9864884a9c421721b12fc1fc6e7711b14a3f9a067c1fd027c7c024c32c8ce06393c24a72fccea1f8ff59166fb863663bec6ee4f6c5789c61fa6f7e1fd02de82c7f957f511bebefc9404084ec7394ff82d3925784fa895e24a3aec0575e2420e11d61f63634de4819467e489cdf5813f8bf091d4f7c16d4cd4260f7e5615da3c1034e5303b0bcff6343e8dbcd6766b15a2b3ba2cdab9fdda366209d3702c11611a0a34de9f4f31cdf7c0decd46cdce37d08acb2b9563a92c4b1bfc9ef10003ecf3a93d9fd1083603dcce9edacbf93d6e6924ff8f77fd5e60d283539a146668316d14e6954b45b45e49ec9146b4ff5dc6276232ff0fcf45a0be67988f31c42b95a6ca7e3b7314e8373eed2ab1d7733f4142d3b23ce1da26741ad0fedfdafdd3eb233f8177e52f603a4bc86926ecda3562cfced2d837f511c7bd93ff93f94ca4aa30194b763c7042844ff2914feb23292fe3fe96ec7df03cf9836a6181a5fa4818909a8921b7c3c2ba92f5a6f1c9ab7c9de8c4a98c40ae704682186cc6b6bbdc91b81ed5ef79bd6dc31fac27274dbd4ccebb5c7fba1aec76dd526159eea0e5be64e76c0b73f2c0b5b194f3ba2ecd9df696d272624378b9a301219f6507952336d361429b984d82cac0995345393ee501090de3b483d39aecbd38ade3cfa77238dc33b111c1ff7cc705cf993b75dc53cdd60bab423c538de274be97c695386cc0d84dd09348bd3c12c31aa9604bf3074b67d1517d7fb444f3c9f2d42b34da2e9cee5412896edad58e6327988d11bd0c57888f37f3ffab6b98d2563eafe915f833b1e5d88c6fb8896d873c1724afcb9ccedfdbfa483a9fce1bf3c95e474963cf81138279c96778087bde67f491ec7c5cfd9ff40f7f2e14d62bb7ef605d773c94abc6bc777050af10f4adc2a6b0ed8bd602ebcf95a0ba38cfdc799dd627e18ddbb566fe6235f367c1cc1ff7c77174a95e1aaf7b7f2b1576b9165a821d7ff78c4f85e9b41665a7b377c01208f23e9c0e7cb48a4e86a6656968b6517a091e1ee0aa284b0313ba91da24ae572a43cbb2f267c227e07bb83fdf25e4b32b5e85180da6fd839d51d8635e05b4db38bbc4429c6b97b096dde8f50b877e6df6b2f797d6f6793e695796fa59dfced6adc9500be7fa71afbc84f14eb08d3dc2bcb217c9e12ecb13d395a6cf83f1705e91f208ca63090df7a9bfe1b63da2a5e91c65bfa3cf813e807491f161cf818f004f794c93aff4912c2fc8f23ffafae9f1e79fe11d99f6497d24bbffb2bc968c9bf054f41423c9d87bbbc3c92bcc0753a4409c59b98096856363beeb1dadf9f8ac7b466336deee83fc6ed12d9c826a7c9cf95b25a80a433823f3c3f2e47bd2cbf4657f1855edf140b17507eb088103367c6a1bc7a7c1653a80ebf9e0d304791faf3f3fbbd7a722bc692ed54960366a67d04dd625a6574cb9fd9ef30cc2bd53da754fc3286d4b7cc2647533df319e1331793c62cff5186d89e84eade393017e8036a6bfe08f589720c6084b7c58dbc72706fc184604deb88e6d542ab6313dbbfef44c74acce097c159ee7b6b76bd4ecec5e52d93f634312186d866bc49e1f71bd8ccf47abc6b460361e2effa7361a4621c25bdb4d665e927141fcd3355582f94de693edaa3bffc8f99af75ead673adfb7b6acabefffb27f84f1e6f4ca780b9f7f3ce73102cb11329cc1dcc9f96b447830023f13f157295863c829a3c2b9302b5cf6457c128a2af2bdf9a139d2443823288769a21a2388d1247edbfaf9c9516763c73d5e1cff58a23617bc93ec700f9e2c2ac782d512ae819fa129199e91364eb3d02bdc07cbe0aff8be99b3ce79c4ad7d22c33b6eeec767e65efee47db9d23f485c4f96d6a3e271eef4a9dc8ee9af4f251af40a14002802f70b9c9f6077bb36c4ae626ad1c17a938ac7adfa736a33e3f145f7b49f3f1f766896e6798cd6319ff02bff7f627bbabe267a40c22733d4827fee513dede13c5ceb0b6feb23cc5a9a95096e758fd0bbf9fe9a6ffe79fbbc7fe4ad383126ab105907bcae78bc4fa97f271df7a9e0a89b18198552806658afde33ee40f563382364957c90dbc0fac8ffc9ede24043ce5b4c2b67f86ef8c4105fb00bf62168a9d5f10d9a9f440950add415cb6dea95ca9cf53b3d223b03597d86495391e3666850fa5ec8d05c6aebb0b99c4d6d1c74e7413fce96e316cabb17f03d107b5078e882cdc87da1fde0fe01b8029520d21af8ea8964e0844083a99d8cdb78eeedf4ac1f191e91d5a3e05aa8b82f092578bb3de2cd6172bdd95137bc48e0fd794b1f69d5525e71adefa4a795ffff46ee4ffbfde73c84dde793f15a0ffa91ee0dba8e6e91fb4df83c0411dd1f845a415c01ea169ceea14bd69ae9d53056382364d7ab0ec227012293b12411109bbde30ee7e959836b10b1781d81d01c9fae42966e5dd39d2bf93aa2bb13ec5a49cc67422baf6942a23fb0d8d2eca949e57c6edbb9b5d3dfea388c96735e454e49613f072984f397446a497c18d9bef9099d7da17390ee5eeaffe0b6a6ab79b896fedcf4cabfe776addbf9bb6f9cf73c1adff5b8bd07bac507fc23199e91b59dddfe3e2befffb62ffcadf6e978adccda3db41f524f00f13be1d758ee09f973980c60fb740e3a856a2c6299e17a9e23382359c906fcb507137cbc984f902809f0e17a22e12f9c265139cf2676feab78a08ccd292b8f73f999ccc6e525195596268659b996fb4853db441a63caaed998d32bda7c2bc7826d07f314ceabd80ec2fa889ad2f05b9a7b6dcbc1f4c649ecf0dc6f70a527dc3ef796d6dfea17d407ee45ccc6776bef7fef9a9ddf69f6fb0ccf0a6f9fcfef9fd54740a26cb6d335b8b9ff039e7e25e727fad307fbfdf0ea7c501f79f3ffd736b82bbd8efe9fca09c9fcd769dc424a7db80c505a17c2d56b90a16c74fe081fc9cc023f7fb7b4ef23ed2d1ec2cf23e51dfde5151db891161edc47f8d3e767696b761cd097d653626df815ef7b6f4cbffcfc767cd7dfc3f3fb724abf7ffdac3f698fd6f5fa7beaafe2fdfcd5383ed2bfb77eff816b04fa4866d7fed17d3fd32f12cb50e727f59ae7133e42ef267edb95f11c90e3035febded3b46f7efed595ee88422dd15b7ef8f974dcc0a35d11eb23e28f8d3b13db4bf535e2d79fb556f77ad4cfcf47a1f6b79ecfe603bcaeb3e10acf4978dd0fb778cb47beb351ab2ba35b7fa12534a30e748bcabde83573727eb4c1f34137fbfdf8a4cf376edbf9bbeb91ee8b743dfedebeb85e0f62b562b63eca47bebd17228b454afc23577e951f9b0df02390678710114efd143f7f4248d439b5f145d46ff303edca4a4b6924899f93883e721f13f0014bc2573562a1794dfd4677fdfe81f9a1b184a72ef363257632c4ec5a8fe284bef29acc84caecf1fef73eefed7ef0f70e3a9b105706f91c7fab1f10730027153c9c3f356efedea5fe1f9fe78ffc9df548afc85276d01fba1e3fbd3fd2f5286dd3f5a0b62ff89ec85a1eb1f9bbdf7545cc370291daa75a7d07be6cf23d6fdffcfcf4ca7d02f83d450ba8a7feff1fbe7ab033ea1bd2971f1a77ba1e6c674a8e7aaa9d7a576bf1d3f3c0d683f0758951b0bfb21e8eef0c0aa40f10af909d0b7246486e1cf88ebfe74a7622c40243d667a73ba0f91fec7bb8aadffbfcd437ce9f872463b3079ff980d2ae1f7c3e9d0f89c43a93b93806df3efeec3c135e4e693641475097adfbf9b9b97efbfc2099ae07b258ccf8c379fbc6fd89d703d6a1d0b85b0f1515e08c9cad56ed6c0d57df75755f5bb5daac5ba8bbb5e5b255506adb53ef6c35dbdffddcdbeb7603d7cab1beaf2d0bcd6e5c7787c7f6cb4ff7039e57df9daddaa2eed60f8546e5f8fdcf3d75cf56b790cec3a95bda36dbb5355d8f9f5e87db2bac47fd4cd703e685f6f7e79e5f9b9dbab5f5ff9b73797208223e5cb361f2cee54ab5d65c009db7fe89</data>
+ </pixmap>
+ <signal>signalTz(const QString &amp;, const QString &amp;)</signal>
+ </customwidget>
+</customwidgets>
+</CW>
diff --git a/core/settings/citytime/zonemap.h b/core/settings/citytime/zonemap.h
new file mode 100644
index 0000000..c9c2035
--- a/dev/null
+++ b/core/settings/citytime/zonemap.h
@@ -0,0 +1,157 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#ifndef ZONEMAP_H
+#define ZONEMAP_H
+
+#include "stylusnormalizer.h"
+
+#include <qlist.h>
+#include <qscrollview.h>
+#include <qstring.h>
+
+extern const int iCITYOFFSET;
+
+class QImage;
+class QComboBox;
+class QLabel;
+class QTimer;
+class QToolButton;
+
+
+
+class ZoneField
+{
+public:
+ ZoneField( const QString & );
+ void showStructure( void ) const;
+ inline int x( void ) const { return _x; };
+ inline int y( void ) const { return _y; };
+
+ inline QString city( void ) const { return strCity; };
+ inline QString country( void ) const { return strCountry; };
+ inline QString code( void ) const { return strCountryCode; };
+private:
+ int _x;
+ int _y;
+ QString strCountryCode;
+ QString strCountry;
+ QString strCity;
+};
+
+class ZoneMap : public QScrollView
+{
+ Q_OBJECT
+public:
+ ZoneMap( QWidget *parent = 0, const char *name = 0 );
+ ~ZoneMap();
+ void showZones( void ) const;
+ // convert between the pixels on the image and the coordinates in the
+ // database
+ inline bool zoneToWin( int zoneX, int zoneY, int &winX, int &winY ) const;
+ inline bool winToZone( int winX, int winY, int &zoneX, int &zoneY ) const;
+
+public slots:
+ void slotZoom( bool setZoom );
+ void slotIllum( bool setIllum );
+ void slotUpdate( void );
+ void slotRedraw( void );
+ void slotFindCity( const QPoint &pos ); // Find the closest city
+ void changeClock( bool );
+
+signals:
+ void signalTz( const QString &newCountry, const QString &newCity );
+
+protected:
+ virtual void viewportMouseMoveEvent( QMouseEvent *event );
+ virtual void viewportMousePressEvent( QMouseEvent *event );
+ virtual void viewportMouseReleaseEvent( QMouseEvent *event );
+ virtual void keyPressEvent( QKeyEvent * );
+ virtual void resizeEvent( QResizeEvent *);
+ virtual void drawContents( QPainter *p, int cx, int cy, int cw, int ch );
+
+private:
+ ZoneField *findCityNear( ZoneField *city, int key );
+ void showCity( ZoneField *city );
+ void drawCities( QPainter *p ); // put all the cities on the map (ugly)
+ void drawCity( QPainter *p, const ZoneField *pCity ); // draw the given city on the map
+ void readZones( void ); // Read in the zone information from the file
+ void zoom( void ); // Zoom the map...
+ void makeMap( int width, int height );
+ QPixmap* pixCurr; // image to be drawn on the screen
+ QLabel* lblCity; // the "tool-tip" that shows up when you pick a city...
+ QToolButton *cmdZoom; // our zoom option...
+ QTimer* tHide; // the timer to hide the "tool tip"
+ ZoneField *pLast; // the last known good city that was found...
+ ZoneField *pRepaint; // save the location to maximize the repaint...
+ QList<ZoneField> zones; // a linked list to hold all this information
+ StylusNormalizer norm;
+
+ //the True width and height of the map...
+ int wImg;
+ int hImg;
+ // the pixel points that correspond to (0, 0);
+ int ox;
+ int oy;
+
+ // the drawable area of the map...
+ int drawableW;
+ int drawableH;
+
+ bool bZoom; // a flag to indicate zoom is active
+ bool bIllum; // flag to indicat that illumination is active
+ bool ampm;
+
+ ZoneField *cursor;
+};
+
+inline bool ZoneMap::zoneToWin( int zoneX, int zoneY,
+ int &winX, int &winY ) const
+{
+ winY = oy - ( ( hImg * zoneY ) / 648000 ); // 180 degrees in secs
+ winX = ox + ( ( wImg * zoneX ) / 1296000 ); // 360 degrees in secs
+ // whoa, some things aren't in the best spots..
+ if ( winX > wImg ) {
+ winX = wImg - iCITYOFFSET;
+ } else if ( winX <= 0 ) {
+ winX = iCITYOFFSET;
+ }
+
+ if ( winY >= hImg ) {
+ winY = hImg - iCITYOFFSET;
+ } else if ( winY <= 0 ) {
+ winY = iCITYOFFSET;
+ }
+ // perhaps in the future there will be some real error checking
+ // for now just return true...
+ return true;
+}
+
+inline bool ZoneMap::winToZone( int winX, int winY,
+ int &zoneX, int &zoneY ) const
+{
+ zoneY = ( 648000 * ( oy - winY ) ) / hImg;
+ zoneX = ( 1296000 * ( winX - ox ) ) / wImg;
+ // perhaps in the future there will be some real error checking
+ // for now just return true...
+ return true;
+}
+
+#endif
diff --git a/core/settings/light-and-power/.cvsignore b/core/settings/light-and-power/.cvsignore
new file mode 100644
index 0000000..e6ba7a1
--- a/dev/null
+++ b/core/settings/light-and-power/.cvsignore
@@ -0,0 +1,4 @@
+moc_*
+Makefile
+lightsettingsbase.h
+lightsettingsbase.cpp
diff --git a/core/settings/light-and-power/Makefile.in b/core/settings/light-and-power/Makefile.in
new file mode 100644
index 0000000..8236ed0
--- a/dev/null
+++ b/core/settings/light-and-power/Makefile.in
@@ -0,0 +1,135 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../../bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = light-and-power
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = settings.h
+SOURCES = light.cpp \
+ main.cpp
+OBJECTS = light.o \
+ main.o \
+ lightsettingsbase.o
+INTERFACES = lightsettingsbase.ui
+UICDECLS = lightsettingsbase.h
+UICIMPLS = lightsettingsbase.cpp
+SRCMOC = moc_settings.cpp \
+ moc_lightsettingsbase.cpp
+OBJMOC = moc_settings.o \
+ moc_lightsettingsbase.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake light-and-power.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+light.o: light.cpp \
+ settings.h \
+ lightsettingsbase.h
+
+main.o: main.cpp \
+ settings.h \
+ lightsettingsbase.h
+
+lightsettingsbase.h: lightsettingsbase.ui
+ $(UIC) lightsettingsbase.ui -o $(INTERFACE_DECL_PATH)/lightsettingsbase.h
+
+lightsettingsbase.cpp: lightsettingsbase.ui
+ $(UIC) lightsettingsbase.ui -i lightsettingsbase.h -o lightsettingsbase.cpp
+
+lightsettingsbase.o: lightsettingsbase.cpp \
+ lightsettingsbase.h \
+ lightsettingsbase.ui
+
+moc_settings.o: moc_settings.cpp \
+ settings.h \
+ lightsettingsbase.h
+
+moc_lightsettingsbase.o: moc_lightsettingsbase.cpp \
+ lightsettingsbase.h
+
+moc_settings.cpp: settings.h
+ $(MOC) settings.h -o moc_settings.cpp
+
+moc_lightsettingsbase.cpp: lightsettingsbase.h
+ $(MOC) lightsettingsbase.h -o moc_lightsettingsbase.cpp
+
+
diff --git a/core/settings/light-and-power/light-and-power.pro b/core/settings/light-and-power/light-and-power.pro
new file mode 100644
index 0000000..87bb111
--- a/dev/null
+++ b/core/settings/light-and-power/light-and-power.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+CONFIG += qt warn_on release
+DESTDIR = ../../bin
+HEADERS = settings.h
+SOURCES = light.cpp main.cpp
+INTERFACES = lightsettingsbase.ui
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += ../$(QPEDIR)/include
+LIBS += -lqpe
+TARGET = light-and-power
+
+TRANSLATIONS = ../../i18n/de/light-and-power.ts
diff --git a/core/settings/light-and-power/light-off.xpm b/core/settings/light-and-power/light-off.xpm
new file mode 100644
index 0000000..26624c7
--- a/dev/null
+++ b/core/settings/light-and-power/light-off.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static char * light_off_xpm[] = {
+"16 16 4 1",
+" c None",
+". c #000000000000",
+"X c #6B6B6C6C6C6C",
+"o c #FFFF6C6C0000",
+" ",
+" ",
+" ... ",
+" . . ",
+" . X. ",
+" . X. ",
+" . XXX. ",
+" . X XX. ",
+" . XX. ",
+" . XXX. ",
+" . X. ",
+" . X.. ",
+" .ooo.. ",
+" .ooo.. ",
+" .o.. ",
+" .. "};
diff --git a/core/settings/light-and-power/light-on.xpm b/core/settings/light-and-power/light-on.xpm
new file mode 100644
index 0000000..3f8e174
--- a/dev/null
+++ b/core/settings/light-and-power/light-on.xpm
@@ -0,0 +1,24 @@
+/* XPM */
+static char * light_on_xpm[] = {
+"16 16 5 1",
+" c None",
+". c #FFFFFFFF0000",
+"X c #000000000000",
+"o c #FFFFFFFFFFFF",
+"O c #FFFF6C6C0000",
+" . . ",
+" . . . ",
+" . XXX . ",
+" XoooX . ",
+" Xoooo.X ",
+" .. Xoooooo.X ",
+" Xoooo...X ..",
+" Xooo.o..X ",
+" .. Xooo..X ",
+" Xoo...X ",
+" . Xoo.X . ",
+" . Xoo.XX . ",
+" XOOOXX ",
+" XOOOXX ",
+" XOXX ",
+" XX "};
diff --git a/core/settings/light-and-power/light.cpp b/core/settings/light-and-power/light.cpp
new file mode 100644
index 0000000..24e1fab
--- a/dev/null
+++ b/core/settings/light-and-power/light.cpp
@@ -0,0 +1,133 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "settings.h"
+
+#include <qpe/global.h>
+#include <qpe/fontmanager.h>
+#include <qpe/config.h>
+#include <qpe/applnk.h>
+#include <qpe/qpeapplication.h>
+#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
+#include <qpe/qcopenvelope_qws.h>
+#endif
+
+#include <qlabel.h>
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+#include <qtabwidget.h>
+#include <qslider.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#include <qdatastream.h>
+#include <qmessagebox.h>
+#include <qcombobox.h>
+#include <qspinbox.h>
+#include <qlistbox.h>
+#include <qdir.h>
+#if QT_VERSION >= 300
+#include <qstylefactory.h>
+#endif
+
+extern int qpe_sysBrightnessSteps();
+
+LightSettings::LightSettings( QWidget* parent, const char* name, WFlags fl )
+ : LightSettingsBase( parent, name, TRUE, fl )
+{
+ // Not supported
+ auto_brightness->hide();
+
+ Config config( "qpe" );
+
+ config.setGroup( "Screensaver" );
+
+ int interval;
+ interval = config.readNumEntry( "Interval_Dim", 30 );
+ interval_dim->setValue( interval );
+ interval = config.readNumEntry( "Interval_LightOff", 20 );
+ interval_lightoff->setValue( interval );
+ interval = config.readNumEntry( "Interval", 60 );
+ if ( interval > 3600 ) interval /= 1000; // compatibility (was millisecs)
+ interval_suspend->setValue( interval );
+
+ screensaver_dim->setChecked( config.readNumEntry("Dim",1) != 0 );
+ screensaver_lightoff->setChecked( config.readNumEntry("LightOff",1) != 0 );
+ int maxbright = qpe_sysBrightnessSteps();
+ initbright = config.readNumEntry("Brightness",255);
+ brightness->setMaxValue( maxbright );
+ brightness->setTickInterval( QMAX(1,maxbright/16) );
+ brightness->setLineStep( QMAX(1,maxbright/16) );
+ brightness->setPageStep( QMAX(1,maxbright/16) );
+ brightness->setValue( (maxbright*255 - initbright*maxbright)/255 );
+
+ connect(brightness, SIGNAL(valueChanged(int)), this, SLOT(applyBrightness()));
+}
+
+LightSettings::~LightSettings()
+{
+}
+
+static void set_fl(int bright)
+{
+ QCopEnvelope e("QPE/System", "setBacklight(int)" );
+ e << bright;
+}
+
+void LightSettings::reject()
+{
+ set_fl(initbright);
+
+ QDialog::reject();
+}
+
+void LightSettings::accept()
+{
+ if ( qApp->focusWidget() )
+ qApp->focusWidget()->clearFocus();
+
+ applyBrightness();
+
+ int i_dim = (screensaver_dim->isChecked() ? interval_dim->value() : 0);
+ int i_lightoff = (screensaver_lightoff->isChecked() ? interval_lightoff->value() : 0);
+ int i_suspend = interval_suspend->value();
+ QCopEnvelope e("QPE/System", "setScreenSaverIntervals(int,int,int)" );
+ e << i_dim << i_lightoff << i_suspend;
+
+ Config config( "qpe" );
+ config.setGroup( "Screensaver" );
+ config.writeEntry( "Dim", (int)screensaver_dim->isChecked() );
+ config.writeEntry( "LightOff", (int)screensaver_lightoff->isChecked() );
+ config.writeEntry( "Interval_Dim", interval_dim->value() );
+ config.writeEntry( "Interval_LightOff", interval_lightoff->value() );
+ config.writeEntry( "Interval", interval_suspend->value() );
+ config.writeEntry( "Brightness",
+ (brightness->maxValue()-brightness->value())*255/brightness->maxValue() );
+ config.write();
+
+ QDialog::accept();
+}
+
+void LightSettings::applyBrightness()
+{
+ int bright = (brightness->maxValue()-brightness->value())*255
+ / brightness->maxValue();
+ set_fl(bright);
+}
+
+
diff --git a/core/settings/light-and-power/lightsettingsbase.ui b/core/settings/light-and-power/lightsettingsbase.ui
new file mode 100644
index 0000000..47775f7
--- a/dev/null
+++ b/core/settings/light-and-power/lightsettingsbase.ui
@@ -0,0 +1,471 @@
+<!DOCTYPE UI><UI>
+<class>LightSettingsBase</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>LightSettingsBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>256</width>
+ <height>316</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Light Settings</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>7</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>auto_brightness</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Adjust to environment</string>
+ </property>
+ <property>
+ <name>whatsThis</name>
+ <string>By sensing the ambient light where you are using your device, the screen light can be adjusted automatically. The brightness setting still affects the average brightness.</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QGroupBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>GroupBox3</cstring>
+ </property>
+ <property stdset="1">
+ <name>title</name>
+ <string>Power saving</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>6</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>3</number>
+ </property>
+ <widget row="1" column="1" >
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>interval_lightoff</cstring>
+ </property>
+ <property stdset="1">
+ <name>suffix</name>
+ <string> seconds</string>
+ </property>
+ <property stdset="1">
+ <name>buttonSymbols</name>
+ <enum>PlusMinus</enum>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>3600</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>10</number>
+ </property>
+ <property stdset="1">
+ <name>lineStep</name>
+ <number>15</number>
+ </property>
+ </widget>
+ <widget row="2" column="1" >
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>interval_suspend</cstring>
+ </property>
+ <property stdset="1">
+ <name>suffix</name>
+ <string> seconds</string>
+ </property>
+ <property stdset="1">
+ <name>buttonSymbols</name>
+ <enum>PlusMinus</enum>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>3600</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>10</number>
+ </property>
+ <property stdset="1">
+ <name>lineStep</name>
+ <number>15</number>
+ </property>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>screensaver_lightoff</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Light off after</string>
+ </property>
+ <property stdset="1">
+ <name>checked</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="0" column="0" >
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>screensaver_dim</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>0</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Dim light after</string>
+ </property>
+ <property stdset="1">
+ <name>checked</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget row="0" column="1" >
+ <class>QSpinBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>interval_dim</cstring>
+ </property>
+ <property stdset="1">
+ <name>suffix</name>
+ <string> seconds</string>
+ </property>
+ <property stdset="1">
+ <name>buttonSymbols</name>
+ <enum>PlusMinus</enum>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>3600</number>
+ </property>
+ <property stdset="1">
+ <name>minValue</name>
+ <number>10</number>
+ </property>
+ <property stdset="1">
+ <name>lineStep</name>
+ <number>15</number>
+ </property>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Suspend after</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout18</cstring>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QSlider</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>brightness</cstring>
+ </property>
+ <property stdset="1">
+ <name>maxValue</name>
+ <number>255</number>
+ </property>
+ <property stdset="1">
+ <name>lineStep</name>
+ <number>16</number>
+ </property>
+ <property stdset="1">
+ <name>pageStep</name>
+ <number>16</number>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Vertical</enum>
+ </property>
+ <property stdset="1">
+ <name>tickmarks</name>
+ <enum>Right</enum>
+ </property>
+ <property stdset="1">
+ <name>tickInterval</name>
+ <number>32</number>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout16</cstring>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>0</number>
+ </property>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout10</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PixmapLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image0</pixmap>
+ </property>
+ <property stdset="1">
+ <name>scaledContents</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Bright</string>
+ </property>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer3</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;blockquote&gt;The brighter the screen light, the more battery power is used.&lt;/blockquote&gt;</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout9</cstring>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>PixmapLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>pixmap</name>
+ <pixmap>image1</pixmap>
+ </property>
+ <property stdset="1">
+ <name>scaledContents</name>
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Off</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignVCenter|AlignLeft</set>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ <spacer>
+ <property>
+ <name>name</name>
+ <cstring>Spacer2</cstring>
+ </property>
+ <property stdset="1">
+ <name>orientation</name>
+ <enum>Horizontal</enum>
+ </property>
+ <property stdset="1">
+ <name>sizeType</name>
+ <enum>Expanding</enum>
+ </property>
+ <property>
+ <name>sizeHint</name>
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<images>
+ <image>
+ <name>image0</name>
+ <data format="XPM.GZ" length="439">789c6d8ec10ac2300c86ef7b8ad0ff36a4730777111f41f1288887b4b3e8610a3a0f22bebb6dd3d54d0ca5cdffe54f9aaaa4dd764d6555dc7beecf96ec896f54b68fae7bee0fab57a1ea86fc5950ad6685d2646973bd1c43ce3ec73c46903648e79a5624443a27d20cd2b9382704747e124382f11a7c5e30b364b957b331866331b3800c38f70282121c7c628367c098c1e0eb03121ccd4b46fcb0f80b26bb4833987f76b6d6f274de5fe6a1a031d30969f55e161fe4715f7b</data>
+ </image>
+ <image>
+ <name>image1</name>
+ <data format="XPM.GZ" length="424">789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523234530022130543251d2e253d856405bffcbc54105b19c856360003103711c4354b344b314b04719340dcb434b31488ac1e1a2020a6acac8c2ea60cc54862606ea232b218541b5810452c3111432c510f550c22886a1e482c115d0c2c88e6168818babaa4a42462c48082cae8e68102011a06b5d65c0041d3518e</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>screensaver_dim</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>interval_dim</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>screensaver_lightoff</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>interval_lightoff</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>auto_brightness</tabstop>
+ <tabstop>screensaver_dim</tabstop>
+ <tabstop>interval_dim</tabstop>
+ <tabstop>screensaver_lightoff</tabstop>
+ <tabstop>interval_lightoff</tabstop>
+ <tabstop>interval_suspend</tabstop>
+ <tabstop>brightness</tabstop>
+</tabstops>
+</UI>
diff --git a/core/settings/light-and-power/main.cpp b/core/settings/light-and-power/main.cpp
new file mode 100644
index 0000000..051fdec
--- a/dev/null
+++ b/core/settings/light-and-power/main.cpp
@@ -0,0 +1,38 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include "settings.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/qcopenvelope_qws.h>
+#include <qpe/global.h>
+
+
+int main(int argc, char** argv)
+{
+ QPEApplication a(argc,argv);
+
+ LightSettings dlg;
+
+ a.showMainWidget(&dlg);
+
+ return a.exec();
+}
+
diff --git a/core/settings/light-and-power/qpe-light-and-power.control b/core/settings/light-and-power/qpe-light-and-power.control
new file mode 100644
index 0000000..0ed9d84
--- a/dev/null
+++ b/core/settings/light-and-power/qpe-light-and-power.control
@@ -0,0 +1,9 @@
+Files: bin/light-and-power apps/Settings/Light.desktop
+Priority: optional
+Section: qpe/settings
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Light and Power settings dialog
+ For the Qtopia environment.
diff --git a/core/settings/light-and-power/settings.h b/core/settings/light-and-power/settings.h
new file mode 100644
index 0000000..cec08e3
--- a/dev/null
+++ b/core/settings/light-and-power/settings.h
@@ -0,0 +1,50 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+
+#include <qstrlist.h>
+#include <qasciidict.h>
+#include "lightsettingsbase.h"
+
+
+class LightSettings : public LightSettingsBase
+{
+ Q_OBJECT
+
+public:
+ LightSettings( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~LightSettings();
+
+protected:
+ void accept();
+ void reject();
+
+private slots:
+ void applyBrightness();
+
+private:
+ int initbright;
+};
+
+
+#endif // SETTINGS_H
+
diff --git a/core/settings/security/.cvsignore b/core/settings/security/.cvsignore
new file mode 100644
index 0000000..11eef0d
--- a/dev/null
+++ b/core/settings/security/.cvsignore
@@ -0,0 +1,5 @@
+Makefile
+moc_*
+*.moc
+securitybase.cpp
+securitybase.h
diff --git a/core/settings/security/Makefile.in b/core/settings/security/Makefile.in
new file mode 100644
index 0000000..803edc5
--- a/dev/null
+++ b/core/settings/security/Makefile.in
@@ -0,0 +1,135 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = ../../bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = security
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = security.h
+SOURCES = security.cpp \
+ main.cpp
+OBJECTS = security.o \
+ main.o \
+ securitybase.o
+INTERFACES = securitybase.ui
+UICDECLS = securitybase.h
+UICIMPLS = securitybase.cpp
+SRCMOC = moc_security.cpp \
+ moc_securitybase.cpp
+OBJMOC = moc_security.o \
+ moc_securitybase.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake security.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+security.o: security.cpp \
+ security.h \
+ securitybase.h
+
+main.o: main.cpp \
+ security.h \
+ securitybase.h
+
+securitybase.h: securitybase.ui
+ $(UIC) securitybase.ui -o $(INTERFACE_DECL_PATH)/securitybase.h
+
+securitybase.cpp: securitybase.ui
+ $(UIC) securitybase.ui -i securitybase.h -o securitybase.cpp
+
+securitybase.o: securitybase.cpp \
+ securitybase.h \
+ securitybase.ui
+
+moc_security.o: moc_security.cpp \
+ security.h \
+ securitybase.h
+
+moc_securitybase.o: moc_securitybase.cpp \
+ securitybase.h
+
+moc_security.cpp: security.h
+ $(MOC) security.h -o moc_security.cpp
+
+moc_securitybase.cpp: securitybase.h
+ $(MOC) securitybase.h -o moc_securitybase.cpp
+
+
diff --git a/core/settings/security/main.cpp b/core/settings/security/main.cpp
new file mode 100644
index 0000000..c15bb31
--- a/dev/null
+++ b/core/settings/security/main.cpp
@@ -0,0 +1,38 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+
+#include <qpe/qpeapplication.h>
+#include <qpe/qcopenvelope_qws.h>
+#include <qpe/global.h>
+
+#include "security.h"
+
+
+int main(int argc, char** argv)
+{
+ QPEApplication a(argc,argv);
+
+ Security dlg;
+
+ a.showMainWidget(&dlg);
+
+ return a.exec();
+}
+
diff --git a/core/settings/security/qpe-security.control b/core/settings/security/qpe-security.control
new file mode 100644
index 0000000..78a5a86
--- a/dev/null
+++ b/core/settings/security/qpe-security.control
@@ -0,0 +1,9 @@
+Files: bin/security apps/Settings/Security.desktop
+Priority: optional
+Section: qpe/settings
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-3
+Depends: qpe-base ($QPE_VERSION)
+Description: Security settings dialog
+ For the Qtopia environment.
diff --git a/core/settings/security/security.cpp b/core/settings/security/security.cpp
new file mode 100644
index 0000000..f4116b0
--- a/dev/null
+++ b/core/settings/security/security.cpp
@@ -0,0 +1,234 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#include "security.h"
+
+#include <qpe/config.h>
+#include <qpe/password.h>
+#include <qpe/qpedialog.h>
+
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+#include <qcombobox.h>
+#include <qmessagebox.h>
+
+Security::Security( QWidget* parent, const char* name, WFlags fl )
+ : SecurityBase( parent, name, TRUE, fl )
+{
+ valid=FALSE;
+ Config cfg("Security");
+ cfg.setGroup("Passcode");
+ passcode = cfg.readEntry("passcode");
+ passcode_poweron->setChecked(cfg.readBoolEntry("passcode_poweron",FALSE));
+ cfg.setGroup("Sync");
+ int auth_peer = cfg.readNumEntry("auth_peer",0xc0a80100);
+ int auth_peer_bits = cfg.readNumEntry("auth_peer_bits",24);
+ selectNet(auth_peer,auth_peer_bits);
+ connect(syncnet, SIGNAL(textChanged(const QString&)),
+ this, SLOT(setSyncNet(const QString&)));
+
+ /*
+ cfg.setGroup("Remote");
+ if ( telnetAvailable() )
+ telnet->setChecked(cfg.readEntry("allow_telnet"));
+ else
+ telnet->hide();
+
+ if ( sshAvailable() )
+ ssh->setChecked(cfg.readEntry("allow_ssh"));
+ else
+ ssh->hide();
+ */
+
+ connect(changepasscode,SIGNAL(clicked()), this, SLOT(changePassCode()));
+ connect(clearpasscode,SIGNAL(clicked()), this, SLOT(clearPassCode()));
+ updateGUI();
+
+ dl = new QPEDialogListener(this);
+}
+
+Security::~Security()
+{
+}
+
+
+void Security::updateGUI()
+{
+ bool empty = passcode.isEmpty();
+
+ changepasscode->setText( empty ? tr("Set passcode" )
+ : tr("Change passcode" ) );
+ passcode_poweron->setEnabled( !empty );
+ clearpasscode->setEnabled( !empty );
+}
+
+
+void Security::show()
+{
+ valid=FALSE;
+ setEnabled(FALSE);
+ SecurityBase::show();
+ if ( passcode.isEmpty() ) {
+ // could insist...
+ //changePassCode();
+ //if ( passcode.isEmpty() )
+ //reject();
+ } else {
+ QString pc = enterPassCode(tr("Enter passcode"));
+ if ( pc != passcode ) {
+ QMessageBox::critical(this, tr("Passcode incorrect"),
+ tr("The passcode entered is incorrect.\nAccess denied"));
+ reject();
+ return;
+ }
+ }
+ setEnabled(TRUE);
+ valid=TRUE;
+}
+
+void Security::accept()
+{
+ applySecurity();
+ QDialog::accept();
+}
+
+void Security::done(int r)
+{
+ QDialog::done(r);
+ close();
+}
+
+void Security::selectNet(int auth_peer,int auth_peer_bits)
+{
+ QString sn;
+ if ( auth_peer_bits == 0 && auth_peer == 0 ) {
+ sn = tr("Any");
+ } else if ( auth_peer_bits == 32 && auth_peer == 0 ) {
+ sn = tr("None");
+ } else {
+ sn =
+ QString::number((auth_peer>>24)&0xff) + "."
+ + QString::number((auth_peer>>16)&0xff) + "."
+ + QString::number((auth_peer>>8)&0xff) + "."
+ + QString::number((auth_peer>>0)&0xff) + "/"
+ + QString::number(auth_peer_bits);
+ }
+ for (int i=0; i<syncnet->count(); i++) {
+ if ( syncnet->text(i).left(sn.length()) == sn ) {
+ syncnet->setCurrentItem(i);
+ return;
+ }
+ }
+ qDebug("No match for \"%s\"",sn.latin1());
+}
+
+void Security::parseNet(const QString& sn,int& auth_peer,int& auth_peer_bits)
+{
+ auth_peer=0;
+ if ( sn == tr("Any") ) {
+ auth_peer = 0;
+ auth_peer_bits = 0;
+ } else if ( sn == tr("None") ) {
+ auth_peer = 0;
+ auth_peer_bits = 32;
+ } else {
+ int x=0;
+ for (int i=0; i<4; i++) {
+ int nx = sn.find(QChar(i==3 ? '/' : '.'),x);
+ auth_peer = (auth_peer<<8)|sn.mid(x,nx-x).toInt();
+ x = nx+1;
+ }
+ uint n = (uint)sn.find(' ',x)-x;
+ auth_peer_bits = sn.mid(x,n).toInt();
+ }
+}
+
+void Security::setSyncNet(const QString& sn)
+{
+ int auth_peer,auth_peer_bits;
+ parseNet(sn,auth_peer,auth_peer_bits);
+ selectNet(auth_peer,auth_peer_bits);
+}
+
+void Security::applySecurity()
+{
+ if ( valid ) {
+ Config cfg("Security");
+ cfg.setGroup("Passcode");
+ cfg.writeEntry("passcode",passcode);
+ cfg.writeEntry("passcode_poweron",passcode_poweron->isChecked());
+ cfg.setGroup("Sync");
+ int auth_peer=0;
+ int auth_peer_bits;
+ QString sn = syncnet->currentText();
+ parseNet(sn,auth_peer,auth_peer_bits);
+ cfg.writeEntry("auth_peer",auth_peer);
+ cfg.writeEntry("auth_peer_bits",auth_peer_bits);
+ /*
+ cfg.setGroup("Remote");
+ if ( telnetAvailable() )
+ cfg.writeEntry("allow_telnet",telnet->isChecked());
+ if ( sshAvailable() )
+ cfg.writeEntry("allow_ssh",ssh->isChecked());
+ // ### write ssh/telnet sys config files
+ */
+ }
+}
+
+void Security::changePassCode()
+{
+ QString new1;
+ QString new2;
+
+ do {
+ new1 = enterPassCode("Enter new passcode");
+ if ( new1.isNull() )
+ return;
+ new2 = enterPassCode("Re-enter new passcode");
+ if ( new2.isNull() )
+ return;
+ } while (new1 != new2);
+
+ passcode = new1;
+ updateGUI();
+}
+
+void Security::clearPassCode()
+{
+ passcode = QString::null;
+ updateGUI();
+}
+
+
+QString Security::enterPassCode(const QString& prompt)
+{
+ return Password::getPassword(prompt);
+}
+
+bool Security::telnetAvailable() const
+{
+ // ### not implemented
+ return FALSE;
+}
+
+bool Security::sshAvailable() const
+{
+ // ### not implemented
+ return FALSE;
+}
diff --git a/core/settings/security/security.h b/core/settings/security/security.h
new file mode 100644
index 0000000..efc83a2
--- a/dev/null
+++ b/core/settings/security/security.h
@@ -0,0 +1,64 @@
+/**********************************************************************
+** Copyright (C) 2000 Trolltech AS. All rights reserved.
+**
+** This file is part of Qtopia Environment.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.trolltech.com/gpl/ for GPL licensing information.
+**
+** Contact info@trolltech.com if any conditions of this licensing are
+** not clear to you.
+**
+**********************************************************************/
+#ifndef SECURITY_H
+#define SECURITY_H
+
+#include "securitybase.h"
+
+class QPEDialogListener;
+
+class Security : public SecurityBase
+{
+ Q_OBJECT
+
+public:
+ Security( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~Security();
+
+ void show();
+
+protected:
+ void accept();
+ void applySecurity();
+ void done(int);
+
+private slots:
+ void changePassCode();
+ void clearPassCode();
+ void setSyncNet(const QString&);
+
+private:
+ bool telnetAvailable() const;
+ bool sshAvailable() const;
+ void updateGUI();
+
+ static void parseNet(const QString& sn,int& auth_peer,int& auth_peer_bits);
+ void selectNet(int auth_peer,int auth_peer_bits);
+
+ QString enterPassCode(const QString&);
+ QString passcode;
+ bool valid;
+
+ QPEDialogListener *dl;
+};
+
+
+#endif // SECURITY_H
+
diff --git a/core/settings/security/security.pro b/core/settings/security/security.pro
new file mode 100644
index 0000000..282127e
--- a/dev/null
+++ b/core/settings/security/security.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+CONFIG += qt warn_on release
+DESTDIR = ../../bin
+HEADERS = security.h
+SOURCES = security.cpp main.cpp
+INTERFACES = securitybase.ui
+INCLUDEPATH += $(QPEDIR)/include
+DEPENDPATH += ../$(QPEDIR)/include
+LIBS += -lqpe
+TARGET = security
+
+TRANSLATIONS = ../../i18n/de/security.ts
diff --git a/core/settings/security/securitybase.ui b/core/settings/security/securitybase.ui
new file mode 100644
index 0000000..2f3189d
--- a/dev/null
+++ b/core/settings/security/securitybase.ui
@@ -0,0 +1,200 @@
+<!DOCTYPE UI><UI>
+<class>SecurityBase</class>
+<widget>
+ <class>QDialog</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>SecurityBase</cstring>
+ </property>
+ <property stdset="1">
+ <name>geometry</name>
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>281</width>
+ <height>328</height>
+ </rect>
+ </property>
+ <property stdset="1">
+ <name>caption</name>
+ <string>Security Settings</string>
+ </property>
+ <property>
+ <name>layoutMargin</name>
+ </property>
+ <grid>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget row="0" column="0" >
+ <class>QLayoutWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>Layout1</cstring>
+ </property>
+ <property>
+ <name>layoutSpacing</name>
+ </property>
+ <hbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>0</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>-1</number>
+ </property>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>changepasscode</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Change passcode</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QPushButton</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>clearpasscode</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Clear passcode</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget row="1" column="0" >
+ <class>QCheckBox</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>passcode_poweron</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Require pass code at power-on</string>
+ </property>
+ </widget>
+ <widget row="3" column="0" >
+ <class>QTabWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TabWidget2</cstring>
+ </property>
+ <widget>
+ <class>QWidget</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>tab</cstring>
+ </property>
+ <attribute>
+ <name>title</name>
+ <string>Sync</string>
+ </attribute>
+ <vbox>
+ <property stdset="1">
+ <name>margin</name>
+ <number>11</number>
+ </property>
+ <property stdset="1">
+ <name>spacing</name>
+ <number>6</number>
+ </property>
+ <widget>
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>Accept sync from network:</string>
+ </property>
+ </widget>
+ <widget>
+ <class>QComboBox</class>
+ <item>
+ <property>
+ <name>text</name>
+ <string>192.168.1.0/24 (default)</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>192.168.0.0/16</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>172.16.0.0/12</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>10.0.0.0/8</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>Any</string>
+ </property>
+ </item>
+ <item>
+ <property>
+ <name>text</name>
+ <string>None</string>
+ </property>
+ </item>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>syncnet</cstring>
+ </property>
+ <property stdset="1">
+ <name>editable</name>
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </widget>
+ <widget row="2" column="0" >
+ <class>QLabel</class>
+ <property stdset="1">
+ <name>name</name>
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property stdset="1">
+ <name>sizePolicy</name>
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>7</vsizetype>
+ </sizepolicy>
+ </property>
+ <property stdset="1">
+ <name>text</name>
+ <string>&lt;P&gt;Pass code protection provides a minimal level of protection from casual access to this device.</string>
+ </property>
+ <property stdset="1">
+ <name>alignment</name>
+ <set>AlignTop|AlignLeft</set>
+ </property>
+ <property>
+ <name>vAlign</name>
+ </property>
+ </widget>
+ </grid>
+</widget>
+</UI>